PageRenderTime 36ms CodeModel.GetById 18ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/any.hpp

http://hadesmem.googlecode.com/
C++ Header | 253 lines | 172 code | 55 blank | 26 comment | 14 complexity | d88d52a68fea0c754092921e37a16242 MD5 | raw file
  1// See http://www.boost.org/libs/any for Documentation.
  2
  3#ifndef BOOST_ANY_INCLUDED
  4#define BOOST_ANY_INCLUDED
  5
  6// what:  variant type boost::any
  7// who:   contributed by Kevlin Henney,
  8//        with features contributed and bugs found by
  9//        Ed Brey, Mark Rodgers, Peter Dimov, and James Curran
 10// when:  July 2001
 11// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95
 12
 13#include <algorithm>
 14#include <typeinfo>
 15
 16#include "boost/config.hpp"
 17#include <boost/type_traits/remove_reference.hpp>
 18#include <boost/type_traits/is_reference.hpp>
 19#include <boost/throw_exception.hpp>
 20#include <boost/static_assert.hpp>
 21
 22// See boost/python/type_id.hpp
 23// TODO: add BOOST_TYPEID_COMPARE_BY_NAME to config.hpp
 24# if (defined(__GNUC__) && __GNUC__ >= 3) \
 25 || defined(_AIX) \
 26 || (   defined(__sgi) && defined(__host_mips)) \
 27 || (defined(__hpux) && defined(__HP_aCC)) \
 28 || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
 29#  define BOOST_AUX_ANY_TYPE_ID_NAME
 30#include <cstring>
 31# endif 
 32
 33namespace boost
 34{
 35    class any
 36    {
 37    public: // structors
 38
 39        any()
 40          : content(0)
 41        {
 42        }
 43
 44        template<typename ValueType>
 45        any(const ValueType & value)
 46          : content(new holder<ValueType>(value))
 47        {
 48        }
 49
 50        any(const any & other)
 51          : content(other.content ? other.content->clone() : 0)
 52        {
 53        }
 54
 55        ~any()
 56        {
 57            delete content;
 58        }
 59
 60    public: // modifiers
 61
 62        any & swap(any & rhs)
 63        {
 64            std::swap(content, rhs.content);
 65            return *this;
 66        }
 67
 68        template<typename ValueType>
 69        any & operator=(const ValueType & rhs)
 70        {
 71            any(rhs).swap(*this);
 72            return *this;
 73        }
 74
 75        any & operator=(any rhs)
 76        {
 77            rhs.swap(*this);
 78            return *this;
 79        }
 80
 81    public: // queries
 82
 83        bool empty() const
 84        {
 85            return !content;
 86        }
 87
 88        const std::type_info & type() const
 89        {
 90            return content ? content->type() : typeid(void);
 91        }
 92
 93#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
 94    private: // types
 95#else
 96    public: // types (public so any_cast can be non-friend)
 97#endif
 98
 99        class placeholder
100        {
101        public: // structors
102
103            virtual ~placeholder()
104            {
105            }
106
107        public: // queries
108
109            virtual const std::type_info & type() const = 0;
110
111            virtual placeholder * clone() const = 0;
112
113        };
114
115        template<typename ValueType>
116        class holder : public placeholder
117        {
118        public: // structors
119
120            holder(const ValueType & value)
121              : held(value)
122            {
123            }
124
125        public: // queries
126
127            virtual const std::type_info & type() const
128            {
129                return typeid(ValueType);
130            }
131
132            virtual placeholder * clone() const
133            {
134                return new holder(held);
135            }
136
137        public: // representation
138
139            ValueType held;
140
141        private: // intentionally left unimplemented
142            holder & operator=(const holder &);
143        };
144
145#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
146
147    private: // representation
148
149        template<typename ValueType>
150        friend ValueType * any_cast(any *);
151
152        template<typename ValueType>
153        friend ValueType * unsafe_any_cast(any *);
154
155#else
156
157    public: // representation (public so any_cast can be non-friend)
158
159#endif
160
161        placeholder * content;
162
163    };
164
165    class bad_any_cast : public std::bad_cast
166    {
167    public:
168        virtual const char * what() const throw()
169        {
170            return "boost::bad_any_cast: "
171                   "failed conversion using boost::any_cast";
172        }
173    };
174
175    template<typename ValueType>
176    ValueType * any_cast(any * operand)
177    {
178        return operand && 
179#ifdef BOOST_AUX_ANY_TYPE_ID_NAME
180            std::strcmp(operand->type().name(), typeid(ValueType).name()) == 0
181#else
182            operand->type() == typeid(ValueType)
183#endif
184            ? &static_cast<any::holder<ValueType> *>(operand->content)->held
185            : 0;
186    }
187
188    template<typename ValueType>
189    inline const ValueType * any_cast(const any * operand)
190    {
191        return any_cast<ValueType>(const_cast<any *>(operand));
192    }
193
194    template<typename ValueType>
195    ValueType any_cast(any & operand)
196    {
197        typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
198
199#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
200        // If 'nonref' is still reference type, it means the user has not
201        // specialized 'remove_reference'.
202
203        // Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro
204        // to generate specialization of remove_reference for your class
205        // See type traits library documentation for details
206        BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
207#endif
208
209        nonref * result = any_cast<nonref>(&operand);
210        if(!result)
211            boost::throw_exception(bad_any_cast());
212        return *result;
213    }
214
215    template<typename ValueType>
216    inline ValueType any_cast(const any & operand)
217    {
218        typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
219
220#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
221        // The comment in the above version of 'any_cast' explains when this
222        // assert is fired and what to do.
223        BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
224#endif
225
226        return any_cast<const nonref &>(const_cast<any &>(operand));
227    }
228
229    // Note: The "unsafe" versions of any_cast are not part of the
230    // public interface and may be removed at any time. They are
231    // required where we know what type is stored in the any and can't
232    // use typeid() comparison, e.g., when our types may travel across
233    // different shared libraries.
234    template<typename ValueType>
235    inline ValueType * unsafe_any_cast(any * operand)
236    {
237        return &static_cast<any::holder<ValueType> *>(operand->content)->held;
238    }
239
240    template<typename ValueType>
241    inline const ValueType * unsafe_any_cast(const any * operand)
242    {
243        return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
244    }
245}
246
247// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
248//
249// Distributed under the Boost Software License, Version 1.0. (See
250// accompanying file LICENSE_1_0.txt or copy at
251// http://www.boost.org/LICENSE_1_0.txt)
252
253#endif