ossrv_pub/boost_apis/boost/any.hpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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 namespace boost
       
    23 {
       
    24     class any
       
    25     {
       
    26     public: // structors
       
    27 
       
    28         any()
       
    29           : content(0)
       
    30         {
       
    31         }
       
    32 
       
    33         template<typename ValueType>
       
    34         any(const ValueType & value)
       
    35           : content(new holder<ValueType>(value))
       
    36         {
       
    37         }
       
    38 
       
    39         any(const any & other)
       
    40           : content(other.content ? other.content->clone() : 0)
       
    41         {
       
    42         }
       
    43 
       
    44         ~any()
       
    45         {
       
    46             delete content;
       
    47         }
       
    48 
       
    49     public: // modifiers
       
    50 
       
    51         any & swap(any & rhs)
       
    52         {
       
    53             std::swap(content, rhs.content);
       
    54             return *this;
       
    55         }
       
    56 
       
    57         template<typename ValueType>
       
    58         any & operator=(const ValueType & rhs)
       
    59         {
       
    60             any(rhs).swap(*this);
       
    61             return *this;
       
    62         }
       
    63 
       
    64         any & operator=(const any & rhs)
       
    65         {
       
    66             any(rhs).swap(*this);
       
    67             return *this;
       
    68         }
       
    69 
       
    70     public: // queries
       
    71 
       
    72         bool empty() const
       
    73         {
       
    74             return !content;
       
    75         }
       
    76 
       
    77         const std::type_info & type() const
       
    78         {
       
    79             return content ? content->type() : typeid(void);
       
    80         }
       
    81 
       
    82 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
       
    83     private: // types
       
    84 #else
       
    85     public: // types (public so any_cast can be non-friend)
       
    86 #endif
       
    87 
       
    88         class placeholder
       
    89         {
       
    90         public: // structors
       
    91 
       
    92             virtual ~placeholder()
       
    93             {
       
    94             }
       
    95 
       
    96         public: // queries
       
    97 
       
    98             virtual const std::type_info & type() const = 0;
       
    99 
       
   100             virtual placeholder * clone() const = 0;
       
   101 
       
   102         };
       
   103 
       
   104         template<typename ValueType>
       
   105         class holder : public placeholder
       
   106         {
       
   107         public: // structors
       
   108 
       
   109             holder(const ValueType & value)
       
   110               : held(value)
       
   111             {
       
   112             }
       
   113 
       
   114         public: // queries
       
   115 
       
   116             virtual const std::type_info & type() const
       
   117             {
       
   118                 return typeid(ValueType);
       
   119             }
       
   120 
       
   121             virtual placeholder * clone() const
       
   122             {
       
   123                 return new holder(held);
       
   124             }
       
   125 
       
   126         public: // representation
       
   127 
       
   128             ValueType held;
       
   129 
       
   130         };
       
   131 
       
   132 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
       
   133 
       
   134     private: // representation
       
   135 
       
   136         template<typename ValueType>
       
   137         friend ValueType * any_cast(any *);
       
   138 
       
   139         template<typename ValueType>
       
   140         friend ValueType * unsafe_any_cast(any *);
       
   141 
       
   142 #else
       
   143 
       
   144     public: // representation (public so any_cast can be non-friend)
       
   145 
       
   146 #endif
       
   147 
       
   148         placeholder * content;
       
   149 
       
   150     };
       
   151 
       
   152     class bad_any_cast : public std::bad_cast
       
   153     {
       
   154     public:
       
   155         virtual const char * what() const throw()
       
   156         {
       
   157             return "boost::bad_any_cast: "
       
   158                    "failed conversion using boost::any_cast";
       
   159         }
       
   160     };
       
   161 
       
   162     template<typename ValueType>
       
   163     ValueType * any_cast(any * operand)
       
   164     {
       
   165         return operand && operand->type() == typeid(ValueType)
       
   166                     ? &static_cast<any::holder<ValueType> *>(operand->content)->held
       
   167                     : 0;
       
   168     }
       
   169 
       
   170     template<typename ValueType>
       
   171     const ValueType * any_cast(const any * operand)
       
   172     {
       
   173         return any_cast<ValueType>(const_cast<any *>(operand));
       
   174     }
       
   175 
       
   176     template<typename ValueType>
       
   177     ValueType any_cast(const any & operand)
       
   178     {
       
   179         typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
       
   180 
       
   181 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
       
   182         // If 'nonref' is still reference type, it means the user has not
       
   183         // specialized 'remove_reference'.
       
   184 
       
   185         // Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro
       
   186         // to generate specialization of remove_reference for your class
       
   187         // See type traits library documentation for details
       
   188         BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
       
   189 #endif
       
   190 
       
   191         const nonref * result = any_cast<nonref>(&operand);
       
   192         if(!result)
       
   193             boost::throw_exception(bad_any_cast());
       
   194         return *result;
       
   195     }
       
   196 
       
   197     template<typename ValueType>
       
   198     ValueType any_cast(any & operand)
       
   199     {
       
   200         typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
       
   201 
       
   202 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
       
   203         // The comment in the above version of 'any_cast' explains when this
       
   204         // assert is fired and what to do.
       
   205         BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
       
   206 #endif
       
   207 
       
   208         nonref * result = any_cast<nonref>(&operand);
       
   209         if(!result)
       
   210             boost::throw_exception(bad_any_cast());
       
   211         return *result;
       
   212     }
       
   213 
       
   214     // Note: The "unsafe" versions of any_cast are not part of the
       
   215     // public interface and may be removed at any time. They are
       
   216     // required where we know what type is stored in the any and can't
       
   217     // use typeid() comparison, e.g., when our types may travel across
       
   218     // different shared libraries.
       
   219     template<typename ValueType>
       
   220     inline ValueType * unsafe_any_cast(any * operand)
       
   221     {
       
   222         return &static_cast<any::holder<ValueType> *>(operand->content)->held;
       
   223     }
       
   224 
       
   225     template<typename ValueType>
       
   226     inline const ValueType * unsafe_any_cast(const any * operand)
       
   227     {
       
   228         return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
       
   229     }
       
   230 }
       
   231 
       
   232 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
       
   233 //
       
   234 // Distributed under the Boost Software License, Version 1.0. (See
       
   235 // accompanying file LICENSE_1_0.txt or copy at
       
   236 // http://www.boost.org/LICENSE_1_0.txt)
       
   237 
       
   238 #endif