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