epoc32/include/stdapis/boost/any.hpp
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
permissions -rw-r--r--
Final list of Symbian^2 public API header files
     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