ossrv_pub/boost_apis/boost/variant/get.hpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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