File indexing completed on 2025-07-11 08:28:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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)
0040 #endif
0041
0042
0043
0044
0045
0046
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
0061
0062
0063
0064 struct apply_visitor_unrolled {};
0065
0066
0067
0068
0069
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
0094
0095
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_
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_
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
0156 typedef typename Visitor::result_type result_type;
0157 return ::boost::detail::variant::forced_return< result_type >();
0158 }
0159
0160
0161
0162
0163
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_
0175 , NBF, W* = nullptr, S* = nullptr
0176 )
0177 {
0178
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_
0193 , NoBackupFlag no_backup_flag
0194 , Which* = nullptr, step0* = nullptr
0195 )
0196 {
0197
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
0213 switch (logical_which)
0214 {
0215
0216
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
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 }}
0259 }
0260
0261 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0262 # pragma warning(pop)
0263 #endif
0264
0265 #endif