epoc32/include/stdapis/boost/variant/get.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
     1 //-----------------------------------------------------------------------------
     2 // boost variant/get.hpp header file
     3 // See http://www.boost.org for updates, documentation, and revision history.
     4 //-----------------------------------------------------------------------------
     5 //
     6 // Copyright (c) 2003
     7 // Eric Friedman, Itay Maman
     8 //
     9 // Distributed under the Boost Software License, Version 1.0. (See
    10 // accompanying file LICENSE_1_0.txt or copy at
    11 // http://www.boost.org/LICENSE_1_0.txt)
    12 
    13 #ifndef BOOST_VARIANT_GET_HPP
    14 #define BOOST_VARIANT_GET_HPP
    15 
    16 #include <exception>
    17 
    18 #include "boost/config.hpp"
    19 #include "boost/detail/workaround.hpp"
    20 #include "boost/utility/addressof.hpp"
    21 #include "boost/variant/variant_fwd.hpp"
    22 
    23 #include "boost/type_traits/add_reference.hpp"
    24 #include "boost/type_traits/add_pointer.hpp"
    25 
    26 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
    27 #   include "boost/mpl/bool.hpp"
    28 #   include "boost/mpl/or.hpp"
    29 #   include "boost/type_traits/is_same.hpp"
    30 #endif
    31 
    32 namespace boost {
    33 
    34 //////////////////////////////////////////////////////////////////////////
    35 // class bad_get
    36 //
    37 // The exception thrown in the event of a failed get of a value.
    38 //
    39 class bad_get
    40     : public std::exception
    41 {
    42 public: // std::exception implementation
    43 
    44     virtual const char * what() const throw()
    45     {
    46         return "boost::bad_get: "
    47                "failed value get using boost::get";
    48     }
    49 
    50 };
    51 
    52 //////////////////////////////////////////////////////////////////////////
    53 // function template get<T>
    54 //
    55 // Retrieves content of given variant object if content is of type T.
    56 // Otherwise: pointer ver. returns 0; reference ver. throws bad_get.
    57 //
    58 
    59 namespace detail { namespace variant {
    60 
    61 // (detail) class template get_visitor
    62 //
    63 // Generic static visitor that: if the value is of the specified type,
    64 // returns a pointer to the value it visits; else a null pointer.
    65 //
    66 template <typename T>
    67 struct get_visitor
    68 {
    69 private: // private typedefs
    70 
    71     typedef typename add_pointer<T>::type pointer;
    72     typedef typename add_reference<T>::type reference;
    73 
    74 public: // visitor typedefs
    75 
    76     typedef pointer result_type;
    77 
    78 public: // visitor interfaces
    79 
    80 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
    81 
    82     pointer operator()(reference operand) const
    83     {
    84         return boost::addressof(operand);
    85     }
    86 
    87     template <typename U>
    88     pointer operator()(const U&) const
    89     {
    90         return static_cast<pointer>(0);
    91     }
    92 
    93 #else // MSVC6
    94 
    95 private: // helpers, for visitor interfaces (below)
    96 
    97     pointer execute_impl(reference operand, mpl::true_) const
    98     {
    99         return boost::addressof(operand);
   100     }
   101 
   102     template <typename U>
   103     pointer execute_impl(const U& operand, mpl::false_) const
   104     {
   105         return static_cast<pointer>(0);
   106     }
   107 
   108 public: // visitor interfaces
   109 
   110     template <typename U>
   111     pointer operator()(U& operand) const
   112     {
   113         // MSVC6 finds normal implementation (above) ambiguous,
   114         // so we must explicitly disambiguate
   115 
   116         typedef typename mpl::or_<
   117               is_same<U, T>
   118             , is_same<const U, T>
   119             >::type U_is_T;
   120 
   121         return execute_impl(operand, U_is_T());
   122     }
   123 
   124 #endif // MSVC6 workaround
   125 
   126 };
   127 
   128 }} // namespace detail::variant
   129 
   130 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
   131 #   define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)  \
   132     BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t)
   133 #else
   134 #   define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)  \
   135     , t* = 0
   136 #endif
   137 
   138 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
   139 inline
   140     typename add_pointer<U>::type
   141 get(
   142       boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
   143       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
   144     )
   145 {
   146     typedef typename add_pointer<U>::type U_ptr;
   147     if (!operand) return static_cast<U_ptr>(0);
   148 
   149     detail::variant::get_visitor<U> v;
   150     return operand->apply_visitor(v);
   151 }
   152 
   153 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
   154 inline
   155     typename add_pointer<const U>::type
   156 get(
   157       const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
   158       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
   159     )
   160 {
   161     typedef typename add_pointer<const U>::type U_ptr;
   162     if (!operand) return static_cast<U_ptr>(0);
   163 
   164     detail::variant::get_visitor<const U> v;
   165     return operand->apply_visitor(v);
   166 }
   167 
   168 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
   169 inline
   170     typename add_reference<U>::type
   171 get(
   172       boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
   173       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
   174     )
   175 {
   176     typedef typename add_pointer<U>::type U_ptr;
   177     U_ptr result = get<U>(&operand);
   178 
   179     if (!result)
   180         throw bad_get();
   181     return *result;
   182 }
   183 
   184 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
   185 inline
   186     typename add_reference<const U>::type
   187 get(
   188       const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
   189       BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
   190     )
   191 {
   192     typedef typename add_pointer<const U>::type U_ptr;
   193     U_ptr result = get<const U>(&operand);
   194 
   195     if (!result)
   196         throw bad_get();
   197     return *result;
   198 }
   199 
   200 } // namespace boost
   201 
   202 #endif // BOOST_VARIANT_GET_HPP