Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-11 08:28:18

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 namespace boost {
0057 namespace detail { namespace variant {
0058 
0059 ///////////////////////////////////////////////////////////////////////////////
0060 // (detail) class apply_visitor_unrolled
0061 //
0062 // Tag type indicates when visitation_impl is unrolled.
0063 //
0064 struct apply_visitor_unrolled {};
0065 
0066 ///////////////////////////////////////////////////////////////////////////////
0067 // (detail) class template visitation_impl_step
0068 //
0069 // "Never ending" iterator range facilitates visitation_impl unrolling.
0070 //
0071 
0072 
0073 template <typename Iter, typename LastIter>
0074 struct visitation_impl_step
0075 {
0076     typedef typename mpl::deref<Iter>::type type;
0077 
0078     typedef typename mpl::next<Iter>::type next_iter;
0079     typedef visitation_impl_step<
0080           next_iter, LastIter
0081         > next;
0082 };
0083 
0084 template <typename LastIter>
0085 struct visitation_impl_step< LastIter,LastIter >
0086 {
0087     typedef apply_visitor_unrolled type;
0088     typedef visitation_impl_step next;
0089 };
0090 
0091 
0092 ///////////////////////////////////////////////////////////////////////////////
0093 // (detail) function template visitation_impl_invoke
0094 //
0095 // Invokes the given visitor on the specified type in the given storage.
0096 //
0097 
0098 template <typename Visitor, typename VoidPtrCV, typename T>
0099 inline typename Visitor::result_type
0100 visitation_impl_invoke_impl(
0101       int, Visitor& visitor, VoidPtrCV storage, T*
0102     , mpl::true_// never_uses_backup
0103     )
0104 {
0105     return visitor.internal_visit(
0106           cast_storage<T>(storage), 1L
0107         );
0108 }
0109 
0110 template <typename Visitor, typename VoidPtrCV, typename T>
0111 inline typename Visitor::result_type
0112 visitation_impl_invoke_impl(
0113       int internal_which, Visitor& visitor, VoidPtrCV storage, T*
0114     , mpl::false_// never_uses_backup
0115     )
0116 {
0117     if (internal_which >= 0)
0118     {
0119         return visitor.internal_visit(
0120               cast_storage<T>(storage), 1L
0121             );
0122     }
0123     else
0124     {
0125         return visitor.internal_visit(
0126               cast_storage< backup_holder<T> >(storage), 1L
0127             );
0128     }
0129 }
0130 
0131 template <typename Visitor, typename VoidPtrCV, typename T, typename NoBackupFlag>
0132 inline typename Visitor::result_type
0133 visitation_impl_invoke(
0134       int internal_which, Visitor& visitor, VoidPtrCV storage, T* t
0135     , NoBackupFlag
0136     , int
0137     )
0138 {
0139     typedef typename mpl::or_<
0140           NoBackupFlag
0141         , is_nothrow_move_constructible<T>
0142         , has_nothrow_copy<T>
0143         >::type never_uses_backup;
0144 
0145     return (visitation_impl_invoke_impl)(
0146           internal_which, visitor, storage, t
0147         , never_uses_backup()
0148         );
0149 }
0150 
0151 template <typename Visitor, typename VoidPtrCV, typename NBF>
0152 inline typename Visitor::result_type
0153 visitation_impl_invoke(int, Visitor&, VoidPtrCV, apply_visitor_unrolled*, NBF, long)
0154 {
0155     // should never be here at runtime!
0156     typedef typename Visitor::result_type result_type;
0157     return ::boost::detail::variant::forced_return< result_type >();
0158 }
0159 
0160 ///////////////////////////////////////////////////////////////////////////////
0161 // (detail) function template visitation_impl
0162 //
0163 // Invokes the given visitor on the type in the given variant storage.
0164 //
0165 
0166 template <
0167       typename W, typename S
0168     , typename Visitor, typename VPCV
0169     , typename NBF
0170     >
0171 inline typename Visitor::result_type
0172 visitation_impl(
0173       int, int, Visitor&, VPCV
0174     , mpl::true_ // is_apply_visitor_unrolled
0175     , NBF, W* = nullptr, S* = nullptr
0176     )
0177 {
0178     // should never be here at runtime!
0179     typedef typename Visitor::result_type result_type;
0180     return ::boost::detail::variant::forced_return< result_type >();
0181 }
0182 
0183 template <
0184       typename Which, typename step0
0185     , typename Visitor, typename VoidPtrCV
0186     , typename NoBackupFlag
0187     >
0188 BOOST_FORCEINLINE typename Visitor::result_type
0189 visitation_impl(
0190       const int internal_which, const int logical_which
0191     , Visitor& visitor, VoidPtrCV storage
0192     , mpl::false_ // is_apply_visitor_unrolled
0193     , NoBackupFlag no_backup_flag
0194     , Which* = nullptr, step0* = nullptr
0195     )
0196 {
0197     // Typedef apply_visitor_unrolled steps and associated types...
0198 #   define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF(z, N, _) \
0199     typedef typename BOOST_PP_CAT(step,N)::type BOOST_PP_CAT(T,N); \
0200     typedef typename BOOST_PP_CAT(step,N)::next \
0201         BOOST_PP_CAT(step, BOOST_PP_INC(N)); \
0202     /**/
0203 
0204     BOOST_PP_REPEAT(
0205           BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
0206         , BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF
0207         , _
0208         )
0209 
0210 #   undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF
0211 
0212     // ...switch on the target which-index value...
0213     switch (logical_which)
0214     {
0215 
0216     // ...applying the appropriate case:
0217 #   define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE(z, N, _) \
0218     case (Which::value + (N)): \
0219         return (visitation_impl_invoke)( \
0220               internal_which, visitor, storage \
0221             , static_cast<BOOST_PP_CAT(T,N)*>(0) \
0222             , no_backup_flag, 1L \
0223             ); \
0224     /**/
0225 
0226     BOOST_PP_REPEAT(
0227           BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
0228         , BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
0229         , _
0230         )
0231 
0232 #   undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
0233 
0234     default: break;
0235     }
0236 
0237     // If not handled in this iteration, continue unrolling:
0238     typedef mpl::int_<
0239           Which::value + (BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
0240         > next_which;
0241 
0242     typedef BOOST_PP_CAT(step, BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
0243         next_step;
0244 
0245     typedef typename next_step::type next_type;
0246     typedef typename is_same< next_type,apply_visitor_unrolled >::type
0247         is_apply_visitor_unrolled;
0248 
0249     return detail::variant::visitation_impl(
0250           internal_which, logical_which
0251         , visitor, storage
0252         , is_apply_visitor_unrolled()
0253         , no_backup_flag
0254         , static_cast<next_which*>(0), static_cast<next_step*>(0)
0255         );
0256 }
0257 
0258 }} // namespace detail::variant
0259 } // namespace boost
0260 
0261 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0262 # pragma warning(pop)
0263 #endif
0264 
0265 #endif // BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP