]> git.lyx.org Git - features.git/blob - boost/boost/exception/info.hpp
cbbc2c0b2f1349985c1aa638205815244f6dd01b
[features.git] / boost / boost / exception / info.hpp
1 //Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
2
3 //Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #ifndef UUID_8D22C4CA9CC811DCAA9133D256D89593
7 #define UUID_8D22C4CA9CC811DCAA9133D256D89593
8 #if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
9 #pragma GCC system_header
10 #endif
11 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
12 #pragma warning(push,1)
13 #endif
14
15 #include <boost/exception/exception.hpp>
16 #include <boost/exception/to_string_stub.hpp>
17 #include <boost/exception/detail/error_info_impl.hpp>
18 #include <boost/shared_ptr.hpp>
19 #include <boost/config.hpp>
20 #include <map>
21
22 namespace
23 boost
24     {
25     template <class Tag,class T>
26     inline
27     typename enable_if<has_to_string<T>,std::string>::type
28     to_string( error_info<Tag,T> const & x )
29         {
30         return to_string(x.value());
31         }
32
33     template <class Tag,class T>
34     inline
35     error_info<Tag,T>::
36     error_info( value_type const & value ):
37         value_(value)
38         {
39         }
40
41     template <class Tag,class T>
42     inline
43     error_info<Tag,T>::
44     ~error_info() throw()
45         {
46         }
47
48     template <class Tag,class T>
49     inline
50     char const *
51     error_info<Tag,T>::
52     tag_typeid_name() const
53         {
54         return tag_type_name<Tag>();
55         }
56
57     template <class Tag,class T>
58     inline
59     std::string
60     error_info<Tag,T>::
61     value_as_string() const
62         {
63         return to_string_stub(*this);
64         }
65
66     namespace
67     exception_detail
68         {
69         class
70         error_info_container_impl:
71             public error_info_container
72             {
73             public:
74
75             error_info_container_impl():
76                 count_(0)
77                 {
78                 }
79
80             ~error_info_container_impl() throw()
81                 {
82                 }
83
84             void
85             set( shared_ptr<error_info_base> const & x, type_info_ const & typeid_ )
86                 {
87                 BOOST_ASSERT(x);
88                 info_[typeid_] = x;
89                 diagnostic_info_str_.clear();
90                 }
91
92             shared_ptr<error_info_base>
93             get( type_info_ const & ti ) const
94                 {
95                 error_info_map::const_iterator i=info_.find(ti);
96                 if( info_.end()!=i )
97                     {
98                     shared_ptr<error_info_base> const & p = i->second;
99 #ifndef BOOST_NO_RTTI
100                     BOOST_ASSERT( BOOST_EXCEPTION_DYNAMIC_TYPEID(*p).type_==ti.type_ );
101 #endif
102                     return p;
103                     }
104                 return shared_ptr<error_info_base>();
105                 }
106
107             char const *
108             diagnostic_information( char const * header ) const
109                 {
110                 if( header )
111                     {
112                     BOOST_ASSERT(*header!=0);
113                     std::ostringstream tmp;
114                     tmp << header;
115                     for( error_info_map::const_iterator i=info_.begin(),end=info_.end(); i!=end; ++i )
116                         {
117                         shared_ptr<error_info_base const> const & x = i->second;
118                         tmp << '[' << x->tag_typeid_name() << "] = " << x->value_as_string() << '\n';
119                         }
120                     tmp.str().swap(diagnostic_info_str_);
121                     }
122                 return diagnostic_info_str_.c_str();
123                 }
124
125             private:
126
127             friend class boost::exception;
128
129             typedef std::map< type_info_, shared_ptr<error_info_base> > error_info_map;
130             error_info_map info_;
131             mutable std::string diagnostic_info_str_;
132             mutable int count_;
133
134             void
135             add_ref() const
136                 {
137                 ++count_;
138                 }
139
140             void
141             release() const
142                 {
143                 if( !--count_ )
144                     delete this;
145                 }
146             };
147         }
148
149     template <class E,class Tag,class T>
150     inline
151     E const &
152     operator<<( E const & x, error_info<Tag,T> const & v )
153         {
154         typedef error_info<Tag,T> error_info_tag_t;
155         shared_ptr<error_info_tag_t> p( new error_info_tag_t(v) );
156         exception_detail::error_info_container * c=x.data_.get();
157         if( !c )
158             x.data_.adopt(c=new exception_detail::error_info_container_impl);
159         c->set(p,BOOST_EXCEPTION_STATIC_TYPEID(error_info_tag_t));
160         return x;
161         }
162     }
163
164 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
165 #pragma warning(pop)
166 #endif
167 #endif