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