epoc32/include/stdapis/boost/variant/detail/visitation_impl.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
williamr@2
     1
//-----------------------------------------------------------------------------
williamr@2
     2
// boost variant/detail/visitation_impl.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
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_DETAIL_VISITATION_IMPL_HPP
williamr@2
    14
#define BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP
williamr@2
    15
williamr@2
    16
#include "boost/config.hpp"
williamr@2
    17
williamr@2
    18
#include "boost/variant/detail/backup_holder.hpp"
williamr@2
    19
#include "boost/variant/detail/cast_storage.hpp"
williamr@2
    20
#include "boost/variant/detail/forced_return.hpp"
williamr@2
    21
#include "boost/variant/detail/generic_result_type.hpp"
williamr@2
    22
williamr@2
    23
#include "boost/assert.hpp"
williamr@2
    24
#include "boost/mpl/eval_if.hpp"
williamr@2
    25
#include "boost/mpl/bool.hpp"
williamr@2
    26
#include "boost/mpl/identity.hpp"
williamr@2
    27
#include "boost/mpl/int.hpp"
williamr@2
    28
#include "boost/mpl/next.hpp"
williamr@2
    29
#include "boost/mpl/deref.hpp"
williamr@2
    30
#include "boost/mpl/or.hpp"
williamr@2
    31
#include "boost/preprocessor/cat.hpp"
williamr@2
    32
#include "boost/preprocessor/inc.hpp"
williamr@2
    33
#include "boost/preprocessor/repeat.hpp"
williamr@2
    34
#include "boost/type_traits/is_same.hpp"
williamr@2
    35
#include "boost/type_traits/has_nothrow_copy.hpp"
williamr@2
    36
#include "boost/variant/detail/has_nothrow_move.hpp"
williamr@2
    37
williamr@2
    38
williamr@2
    39
///////////////////////////////////////////////////////////////////////////////
williamr@2
    40
// BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
williamr@2
    41
//
williamr@2
    42
// Unrolls variant's visitation mechanism to reduce template instantiation
williamr@2
    43
// and potentially increase runtime performance. (TODO: Investigate further.)
williamr@2
    44
//
williamr@2
    45
#if !defined(BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
williamr@2
    46
#   define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT   \
williamr@2
    47
        BOOST_VARIANT_LIMIT_TYPES
williamr@2
    48
#endif
williamr@2
    49
williamr@2
    50
namespace boost {
williamr@2
    51
namespace detail { namespace variant {
williamr@2
    52
williamr@2
    53
///////////////////////////////////////////////////////////////////////////////
williamr@2
    54
// (detail) class apply_visitor_unrolled
williamr@2
    55
//
williamr@2
    56
// Tag type indicates when visitation_impl is unrolled.
williamr@2
    57
//
williamr@2
    58
struct apply_visitor_unrolled {};
williamr@2
    59
williamr@2
    60
///////////////////////////////////////////////////////////////////////////////
williamr@2
    61
// (detail) class template visitation_impl_step
williamr@2
    62
//
williamr@2
    63
// "Never ending" iterator range facilitates visitation_impl unrolling.
williamr@2
    64
//
williamr@2
    65
williamr@2
    66
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
williamr@2
    67
williamr@2
    68
template <typename Iter, typename LastIter>
williamr@2
    69
struct visitation_impl_step
williamr@2
    70
{
williamr@2
    71
    typedef typename mpl::deref<Iter>::type type;
williamr@2
    72
williamr@2
    73
    typedef typename mpl::next<Iter>::type next_iter;
williamr@2
    74
    typedef visitation_impl_step<
williamr@2
    75
          next_iter, LastIter
williamr@2
    76
        > next;
williamr@2
    77
};
williamr@2
    78
williamr@2
    79
template <typename LastIter>
williamr@2
    80
struct visitation_impl_step< LastIter,LastIter >
williamr@2
    81
{
williamr@2
    82
    typedef apply_visitor_unrolled type;
williamr@2
    83
    typedef visitation_impl_step next;
williamr@2
    84
};
williamr@2
    85
williamr@2
    86
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
williamr@2
    87
williamr@2
    88
template <typename Iter, typename LastIter>
williamr@2
    89
struct visitation_impl_step
williamr@2
    90
{
williamr@2
    91
    typedef typename mpl::eval_if<
williamr@2
    92
          is_same<Iter, LastIter>
williamr@2
    93
        , mpl::identity<apply_visitor_unrolled>
williamr@2
    94
        , Iter
williamr@2
    95
        >::type type;
williamr@2
    96
williamr@2
    97
    typedef typename mpl::eval_if<
williamr@2
    98
          is_same<type, apply_visitor_unrolled> //is_same<Iter, LastIter>
williamr@2
    99
        , mpl::identity<LastIter>
williamr@2
   100
        , mpl::next<Iter>
williamr@2
   101
        >::type next_iter;
williamr@2
   102
williamr@2
   103
    typedef visitation_impl_step<
williamr@2
   104
          next_iter, LastIter
williamr@2
   105
        > next;
williamr@2
   106
};
williamr@2
   107
williamr@2
   108
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
williamr@2
   109
williamr@2
   110
///////////////////////////////////////////////////////////////////////////////
williamr@2
   111
// (detail) function template visitation_impl_invoke
williamr@2
   112
//
williamr@2
   113
// Invokes the given visitor on the specified type in the given storage.
williamr@2
   114
//
williamr@2
   115
williamr@2
   116
template <typename Visitor, typename VoidPtrCV, typename T>
williamr@2
   117
inline
williamr@2
   118
    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
williamr@2
   119
visitation_impl_invoke_impl(
williamr@2
   120
      int, Visitor& visitor, VoidPtrCV storage, T*
williamr@2
   121
    , mpl::true_// never_uses_backup
williamr@2
   122
    )
williamr@2
   123
{
williamr@2
   124
    return visitor.internal_visit(
williamr@2
   125
          cast_storage<T>(storage), 1L
williamr@2
   126
        );
williamr@2
   127
}
williamr@2
   128
williamr@2
   129
template <typename Visitor, typename VoidPtrCV, typename T>
williamr@2
   130
inline
williamr@2
   131
    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
williamr@2
   132
visitation_impl_invoke_impl(
williamr@2
   133
      int internal_which, Visitor& visitor, VoidPtrCV storage, T*
williamr@2
   134
    , mpl::false_// never_uses_backup
williamr@2
   135
    )
williamr@2
   136
{
williamr@2
   137
    if (internal_which >= 0)
williamr@2
   138
    {
williamr@2
   139
        return visitor.internal_visit(
williamr@2
   140
              cast_storage<T>(storage), 1L
williamr@2
   141
            );
williamr@2
   142
    }
williamr@2
   143
    else
williamr@2
   144
    {
williamr@2
   145
        return visitor.internal_visit(
williamr@2
   146
              cast_storage< backup_holder<T> >(storage), 1L
williamr@2
   147
            );
williamr@2
   148
    }
williamr@2
   149
}
williamr@2
   150
williamr@2
   151
template <typename Visitor, typename VoidPtrCV, typename T, typename NoBackupFlag>
williamr@2
   152
inline
williamr@2
   153
    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
williamr@2
   154
visitation_impl_invoke(
williamr@2
   155
      int internal_which, Visitor& visitor, VoidPtrCV storage, T* t
williamr@2
   156
    , NoBackupFlag
williamr@2
   157
    , int
williamr@2
   158
    )
williamr@2
   159
{
williamr@2
   160
    typedef typename mpl::or_<
williamr@2
   161
          NoBackupFlag
williamr@2
   162
        , has_nothrow_move_constructor<T>
williamr@2
   163
        , has_nothrow_copy<T>
williamr@2
   164
        >::type never_uses_backup;
williamr@2
   165
williamr@2
   166
    return visitation_impl_invoke_impl(
williamr@2
   167
          internal_which, visitor, storage, t
williamr@2
   168
        , never_uses_backup()
williamr@2
   169
        );
williamr@2
   170
}
williamr@2
   171
williamr@2
   172
template <typename Visitor, typename VoidPtrCV, typename NBF>
williamr@2
   173
inline
williamr@2
   174
    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
williamr@2
   175
visitation_impl_invoke(int, Visitor&, VoidPtrCV, apply_visitor_unrolled*, NBF, long)
williamr@2
   176
{
williamr@2
   177
    // should never be here at runtime:
williamr@2
   178
    BOOST_ASSERT(false);
williamr@2
   179
    typedef typename Visitor::result_type result_type;
williamr@2
   180
    return ::boost::detail::variant::forced_return< result_type >();
williamr@2
   181
}
williamr@2
   182
williamr@2
   183
///////////////////////////////////////////////////////////////////////////////
williamr@2
   184
// (detail) function template visitation_impl
williamr@2
   185
//
williamr@2
   186
// Invokes the given visitor on the type in the given variant storage.
williamr@2
   187
//
williamr@2
   188
williamr@2
   189
template <
williamr@2
   190
      typename W, typename S
williamr@2
   191
    , typename Visitor, typename VPCV
williamr@2
   192
    , typename NBF
williamr@2
   193
    >
williamr@2
   194
inline
williamr@2
   195
    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
williamr@2
   196
visitation_impl(
williamr@2
   197
      int, int, Visitor&, VPCV
williamr@2
   198
    , mpl::true_ // is_apply_visitor_unrolled
williamr@2
   199
    , NBF, W* = 0, S* = 0
williamr@2
   200
    )
williamr@2
   201
{
williamr@2
   202
    // should never be here at runtime:
williamr@2
   203
    BOOST_ASSERT(false);
williamr@2
   204
    typedef typename Visitor::result_type result_type;
williamr@2
   205
    return ::boost::detail::variant::forced_return< result_type >();
williamr@2
   206
}
williamr@2
   207
williamr@2
   208
template <
williamr@2
   209
      typename Which, typename step0
williamr@2
   210
    , typename Visitor, typename VoidPtrCV
williamr@2
   211
    , typename NoBackupFlag
williamr@2
   212
    >
williamr@2
   213
inline
williamr@2
   214
    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
williamr@2
   215
visitation_impl(
williamr@2
   216
      const int internal_which, const int logical_which
williamr@2
   217
    , Visitor& visitor, VoidPtrCV storage
williamr@2
   218
    , mpl::false_ // is_apply_visitor_unrolled
williamr@2
   219
    , NoBackupFlag no_backup_flag
williamr@2
   220
    , Which* = 0, step0* = 0
williamr@2
   221
    )
williamr@2
   222
{
williamr@2
   223
    // Typedef apply_visitor_unrolled steps and associated types...
williamr@2
   224
#   define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF(z, N, _) \
williamr@2
   225
    typedef typename BOOST_PP_CAT(step,N)::type BOOST_PP_CAT(T,N); \
williamr@2
   226
    typedef typename BOOST_PP_CAT(step,N)::next \
williamr@2
   227
        BOOST_PP_CAT(step, BOOST_PP_INC(N)); \
williamr@2
   228
    /**/
williamr@2
   229
williamr@2
   230
    BOOST_PP_REPEAT(
williamr@2
   231
          BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
williamr@2
   232
        , BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF
williamr@2
   233
        , _
williamr@2
   234
        )
williamr@2
   235
williamr@2
   236
#   undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF
williamr@2
   237
williamr@2
   238
    // ...switch on the target which-index value...
williamr@2
   239
    switch (logical_which)
williamr@2
   240
    {
williamr@2
   241
williamr@2
   242
    // ...applying the appropriate case:
williamr@2
   243
#   define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE(z, N, _) \
williamr@2
   244
    case (Which::value + (N)): \
williamr@2
   245
        return visitation_impl_invoke( \
williamr@2
   246
              internal_which, visitor, storage \
williamr@2
   247
            , static_cast<BOOST_PP_CAT(T,N)*>(0) \
williamr@2
   248
            , no_backup_flag, 1L \
williamr@2
   249
            ); \
williamr@2
   250
    /**/
williamr@2
   251
williamr@2
   252
    BOOST_PP_REPEAT(
williamr@2
   253
          BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
williamr@2
   254
        , BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
williamr@2
   255
        , _
williamr@2
   256
        )
williamr@2
   257
williamr@2
   258
#   undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
williamr@2
   259
williamr@2
   260
    }
williamr@2
   261
williamr@2
   262
    // If not handled in this iteration, continue unrolling:
williamr@2
   263
    typedef mpl::int_<
williamr@2
   264
          Which::value + (BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
williamr@2
   265
        > next_which;
williamr@2
   266
williamr@2
   267
    typedef BOOST_PP_CAT(step, BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
williamr@2
   268
        next_step;
williamr@2
   269
williamr@2
   270
    typedef typename next_step::type next_type;
williamr@2
   271
    typedef typename is_same< next_type,apply_visitor_unrolled >::type
williamr@2
   272
        is_apply_visitor_unrolled;
williamr@2
   273
williamr@2
   274
    return visitation_impl(
williamr@2
   275
          internal_which, logical_which
williamr@2
   276
        , visitor, storage
williamr@2
   277
        , is_apply_visitor_unrolled()
williamr@2
   278
        , no_backup_flag
williamr@2
   279
        , static_cast<next_which*>(0), static_cast<next_step*>(0)
williamr@2
   280
        );
williamr@2
   281
}
williamr@2
   282
williamr@2
   283
}} // namespace detail::variant
williamr@2
   284
} // namespace boost
williamr@2
   285
williamr@2
   286
#endif // BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP