]> git.lyx.org Git - lyx.git/blob - boost/boost/exception/info.hpp
boost: update to 1.47.0
[lyx.git] / boost / boost / exception / info.hpp
1 //Copyright (c) 2006-2010 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     std::string
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                     std::ostringstream tmp;
113                     tmp << header;
114                     for( error_info_map::const_iterator i=info_.begin(),end=info_.end(); i!=end; ++i )
115                         {
116                         error_info_base const & x = *i->second;
117                         tmp << '[' << x.tag_typeid_name() << "] = " << x.value_as_string() << '\n';
118                         }
119                     tmp.str().swap(diagnostic_info_str_);
120                     }
121                 return diagnostic_info_str_.c_str();
122                 }
123
124             private:
125
126             friend class boost::exception;
127
128             typedef std::map< type_info_, shared_ptr<error_info_base> > error_info_map;
129             error_info_map info_;
130             mutable std::string diagnostic_info_str_;
131             mutable int count_;
132
133             error_info_container_impl( error_info_container_impl const & );
134             error_info_container_impl & operator=( error_info_container const & );
135
136             void
137             add_ref() const
138                 {
139                 ++count_;
140                 }
141
142             bool
143             release() const
144                 {
145                 if( --count_ )
146                     return false;
147                 else
148                     {
149                     delete this;
150                     return true;
151                     }
152                 }
153
154             refcount_ptr<error_info_container>
155             clone() const
156                 {
157                 refcount_ptr<error_info_container> p;
158                 error_info_container_impl * c=new error_info_container_impl;
159                 p.adopt(c);
160                 c->info_ = info_;
161                 return p;
162                 }
163             };
164
165         template <class E,class Tag,class T>
166         inline
167         E const &
168         set_info( E const & x, error_info<Tag,T> const & v )
169             {
170             typedef error_info<Tag,T> error_info_tag_t;
171             shared_ptr<error_info_tag_t> p( new error_info_tag_t(v) );
172             exception_detail::error_info_container * c=x.data_.get();
173             if( !c )
174                 x.data_.adopt(c=new exception_detail::error_info_container_impl);
175             c->set(p,BOOST_EXCEPTION_STATIC_TYPEID(error_info_tag_t));
176             return x;
177             }
178
179         template <class T>
180         struct
181         derives_boost_exception
182             {
183             enum e { value = (sizeof(dispatch_boost_exception((T*)0))==sizeof(large_size)) };
184             };
185         }
186
187     template <class E,class Tag,class T>
188     inline
189     typename enable_if<exception_detail::derives_boost_exception<E>,E const &>::type
190     operator<<( E const & x, error_info<Tag,T> const & v )
191         {
192         return exception_detail::set_info(x,v);
193         }
194     }
195
196 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
197 #pragma warning(pop)
198 #endif
199 #endif