Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:32

0001 //-----------------------------------------------------------------------------
0002 // boost variant/detail/visitation_impl.hpp header file
0003 // See http://www.boost.org for updates, documentation, and revision history.
0004 //-----------------------------------------------------------------------------
0005 //
0006 // Copyright (c) 2003
0007 // Eric Friedman
0008 //
0009 // Distributed under the Boost Software License, Version 1.0. (See
0010 // accompanying file LICENSE_1_0.txt or copy at
0011 // http://www.boost.org/LICENSE_1_0.txt)
0012 
0013 #ifndef BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP
0014 #define BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP
0015 
0016 #include <boost/config.hpp>
0017 
0018 #include <boost/variant/detail/backup_holder.hpp>
0019 #include <boost/variant/detail/cast_storage.hpp>
0020 #include <boost/variant/detail/forced_return.hpp>
0021 #include <boost/variant/variant_fwd.hpp>
0022 
0023 #include <boost/mpl/eval_if.hpp>
0024 #include <boost/mpl/bool.hpp>
0025 #include <boost/mpl/identity.hpp>
0026 #include <boost/mpl/int.hpp>
0027 #include <boost/mpl/next.hpp>
0028 #include <boost/mpl/deref.hpp>
0029 #include <boost/mpl/or.hpp>
0030 #include <boost/preprocessor/cat.hpp>
0031 #include <boost/preprocessor/inc.hpp>
0032 #include <boost/preprocessor/repeat.hpp>
0033 #include <boost/type_traits/is_same.hpp>
0034 #include <boost/type_traits/has_nothrow_copy.hpp>
0035 #include <boost/type_traits/is_nothrow_move_constructible.hpp>
0036 
0037 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0038 # pragma warning (push)
0039 # pragma warning (disable : 4702) //unreachable code
0040 #endif
0041 
0042 ///////////////////////////////////////////////////////////////////////////////
0043 // BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
0044 //
0045 // Unrolls variant's visitation mechanism to reduce template instantiation
0046 // and potentially increase runtime performance. (TODO: Investigate further.)
0047 //
0048 #if !defined(BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
0049 
0050 #   include <boost/mpl/limits/list.hpp>
0051 #   define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT   \
0052         BOOST_MPL_LIMIT_LIST_SIZE
0053 
0054 #endif
0055 
0056 // Define a compiler generic null pointer value
0057 #if defined(BOOST_NO_CXX11_NULLPTR)
0058 #define BOOST_VARIANT_NULL 0
0059 #else
0060 #define BOOST_VARIANT_NULL nullptr
0061 #endif
0062 
0063 namespace boost {
0064 namespace detail { namespace variant {
0065 
0066 ///////////////////////////////////////////////////////////////////////////////
0067 // (detail) class apply_visitor_unrolled
0068 //
0069 // Tag type indicates when visitation_impl is unrolled.
0070 //
0071 struct apply_visitor_unrolled {};
0072 
0073 ///////////////////////////////////////////////////////////////////////////////
0074 // (detail) class template visitation_impl_step
0075 //
0076 // "Never ending" iterator range facilitates visitation_impl unrolling.
0077 //
0078 
0079 
0080 template <typename Iter, typename LastIter>
0081 struct visitation_impl_step
0082 {
0083     typedef typename mpl::deref<Iter>::type type;
0084 
0085     typedef typename mpl::next<Iter>::type next_iter;
0086     typedef visitation_impl_step<
0087           next_iter, LastIter
0088         > next;
0089 };
0090 
0091 template <typename LastIter>
0092 struct visitation_impl_step< LastIter,LastIter >
0093 {
0094     typedef apply_visitor_unrolled type;
0095     typedef visitation_impl_step next;
0096 };
0097 
0098 
0099 ///////////////////////////////////////////////////////////////////////////////
0100 // (detail) function template visitation_impl_invoke
0101 //
0102 // Invokes the given visitor on the specified type in the given storage.
0103 //
0104 
0105 template <typename Visitor, typename VoidPtrCV, typename T>
0106 inline typename Visitor::result_type
0107 visitation_impl_invoke_impl(
0108       int, Visitor& visitor, VoidPtrCV storage, T*
0109     , mpl::true_// never_uses_backup
0110     )
0111 {
0112     return visitor.internal_visit(
0113           cast_storage<T>(storage), 1L
0114         );
0115 }
0116 
0117 template <typename Visitor, typename VoidPtrCV, typename T>
0118 inline typename Visitor::result_type
0119 visitation_impl_invoke_impl(
0120       int internal_which, Visitor& visitor, VoidPtrCV storage, T*
0121     , mpl::false_// never_uses_backup
0122     )
0123 {
0124     if (internal_which >= 0)
0125     {
0126         return visitor.internal_visit(
0127               cast_storage<T>(storage), 1L
0128             );
0129     }
0130     else
0131     {
0132         return visitor.internal_visit(
0133               cast_storage< backup_holder<T> >(storage), 1L
0134             );
0135     }
0136 }
0137 
0138 template <typename Visitor, typename VoidPtrCV, typename T, typename NoBackupFlag>
0139 inline typename Visitor::result_type
0140 visitation_impl_invoke(
0141       int internal_which, Visitor& visitor, VoidPtrCV storage, T* t
0142     , NoBackupFlag
0143     , int
0144     )
0145 {
0146     typedef typename mpl::or_<
0147           NoBackupFlag
0148         , is_nothrow_move_constructible<T>
0149         , has_nothrow_copy<T>
0150         >::type never_uses_backup;
0151 
0152     return (visitation_impl_invoke_impl)(
0153           internal_which, visitor, storage, t
0154         , never_uses_backup()
0155         );
0156 }
0157 
0158 template <typename Visitor, typename VoidPtrCV, typename NBF>
0159 inline typename Visitor::result_type
0160 visitation_impl_invoke(int, Visitor&, VoidPtrCV, apply_visitor_unrolled*, NBF, long)
0161 {
0162     // should never be here at runtime!
0163     typedef typename Visitor::result_type result_type;
0164     return ::boost::detail::variant::forced_return< result_type >();
0165 }
0166 
0167 ///////////////////////////////////////////////////////////////////////////////
0168 // (detail) function template visitation_impl
0169 //
0170 // Invokes the given visitor on the type in the given variant storage.
0171 //
0172 
0173 template <
0174       typename W, typename S
0175     , typename Visitor, typename VPCV
0176     , typename NBF
0177     >
0178 inline typename Visitor::result_type
0179 visitation_impl(
0180       int, int, Visitor&, VPCV
0181     , mpl::true_ // is_apply_visitor_unrolled
0182     , NBF, W* = BOOST_VARIANT_NULL, S* = BOOST_VARIANT_NULL
0183     )
0184 {
0185     // should never be here at runtime!
0186     typedef typename Visitor::result_type result_type;
0187     return ::boost::detail::variant::forced_return< result_type >();
0188 }
0189 
0190 template <
0191       typename Which, typename step0
0192     , typename Visitor, typename VoidPtrCV
0193     , typename NoBackupFlag
0194     >
0195 BOOST_FORCEINLINE typename Visitor::result_type
0196 visitation_impl(
0197       const int internal_which, const int logical_which
0198     , Visitor& visitor, VoidPtrCV storage
0199     , mpl::false_ // is_apply_visitor_unrolled
0200     , NoBackupFlag no_backup_flag
0201     , Which* = BOOST_VARIANT_NULL, step0* = BOOST_VARIANT_NULL
0202     )
0203 {
0204     // Typedef apply_visitor_unrolled steps and associated types...
0205 #   define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF(z, N, _) \
0206     typedef typename BOOST_PP_CAT(step,N)::type BOOST_PP_CAT(T,N); \
0207     typedef typename BOOST_PP_CAT(step,N)::next \
0208         BOOST_PP_CAT(step, BOOST_PP_INC(N)); \
0209     /**/
0210 
0211     BOOST_PP_REPEAT(
0212           BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
0213         , BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF
0214         , _
0215         )
0216 
0217 #   undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF
0218 
0219     // ...switch on the target which-index value...
0220     switch (logical_which)
0221     {
0222 
0223     // ...applying the appropriate case:
0224 #   define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE(z, N, _) \
0225     case (Which::value + (N)): \
0226         return (visitation_impl_invoke)( \
0227               internal_which, visitor, storage \
0228             , static_cast<BOOST_PP_CAT(T,N)*>(0) \
0229             , no_backup_flag, 1L \
0230             ); \
0231     /**/
0232 
0233     BOOST_PP_REPEAT(
0234           BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
0235         , BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
0236         , _
0237         )
0238 
0239 #   undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
0240 
0241     default: break;
0242     }
0243 
0244     // If not handled in this iteration, continue unrolling:
0245     typedef mpl::int_<
0246           Which::value + (BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
0247         > next_which;
0248 
0249     typedef BOOST_PP_CAT(step, BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
0250         next_step;
0251 
0252     typedef typename next_step::type next_type;
0253     typedef typename is_same< next_type,apply_visitor_unrolled >::type
0254         is_apply_visitor_unrolled;
0255 
0256     return detail::variant::visitation_impl(
0257           internal_which, logical_which
0258         , visitor, storage
0259         , is_apply_visitor_unrolled()
0260         , no_backup_flag
0261         , static_cast<next_which*>(0), static_cast<next_step*>(0)
0262         );
0263 }
0264 
0265 }} // namespace detail::variant
0266 } // namespace boost
0267 
0268 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0269 # pragma warning(pop)
0270 #endif
0271 
0272 #endif // BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP