PageRenderTime 30ms CodeModel.GetById 17ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/exception/info.hpp

http://hadesmem.googlecode.com/
C++ Header | 199 lines | 171 code | 25 blank | 3 comment | 8 complexity | 8201d51b57601ca31167dec331ce8da9 MD5 | raw file
  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
 22namespace
 23boost
 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