]> git.lyx.org Git - lyx.git/blob - boost/boost/exception/info.hpp
update to boost 1.46.1. Tested on Win, Mac, Linux, GCC 4.2, 4.4, 4.5, 4.6
[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                     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                         error_info_base 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             error_info_container_impl( error_info_container_impl const & );
135             error_info_container_impl & operator=( error_info_container const & );
136
137             void
138             add_ref() const
139                 {
140                 ++count_;
141                 }
142
143             bool
144             release() const
145                 {
146                 if( --count_ )
147                     return false;
148                 else
149                     {
150                     delete this;
151                     return true;
152                     }
153                 }
154
155             refcount_ptr<error_info_container>
156             clone() const
157                 {
158                 refcount_ptr<error_info_container> p;
159                 error_info_container_impl * c=new error_info_container_impl;
160                 p.adopt(c);
161                 c->info_ = info_;
162                 return p;
163                 }
164             };
165
166         template <class E,class Tag,class T>
167         inline
168         E const &
169         set_info( E const & x, error_info<Tag,T> const & v )
170             {
171             typedef error_info<Tag,T> error_info_tag_t;
172             shared_ptr<error_info_tag_t> p( new error_info_tag_t(v) );
173             exception_detail::error_info_container * c=x.data_.get();
174             if( !c )
175                 x.data_.adopt(c=new exception_detail::error_info_container_impl);
176             c->set(p,BOOST_EXCEPTION_STATIC_TYPEID(error_info_tag_t));
177             return x;
178             }
179
180         template <class T>
181         struct
182         derives_boost_exception
183             {
184             enum e { value = (sizeof(dispatch_boost_exception((T*)0))==sizeof(large_size)) };
185             };
186         }
187
188     template <class E,class Tag,class T>
189     inline
190     typename enable_if<exception_detail::derives_boost_exception<E>,E const &>::type
191     operator<<( E const & x, error_info<Tag,T> const & v )
192         {
193         return exception_detail::set_info(x,v);
194         }
195     }
196
197 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
198 #pragma warning(pop)
199 #endif
200 #endif