2
0
mirror of https://github.com/boostorg/variant.git synced 2026-02-11 00:12:08 +00:00

Refactored variant::apply_visitor_impl as free function in detail namespace.

[SVN r19164]
This commit is contained in:
Eric Friedman
2003-07-17 01:49:21 +00:00
parent eea0ca8875
commit 0a19bfd00e

View File

@@ -500,6 +500,89 @@ public: // metafunction result
};
//////////////////////////////////////////////////////////////////////////
// (detail) function template cast_storage
//
// Casts the given storage to the specified type, but with qualification.
//
template <typename T>
inline T& cast_storage(void* storage, T* = 0)
{
return *static_cast<T*>(storage);
}
template <typename T>
inline const T& cast_storage(const void* storage, T* = 0)
{
return *static_cast<const T*>(storage);
}
//////////////////////////////////////////////////////////////////////////
// (detail) function template apply_visitor_impl
//
// Invokes the given visitor on the type in the given variant storage.
//
template <
typename Which, typename T
, typename NI, typename LI
, typename Visitor, typename VoidPtrCV
>
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
typename Visitor::result_type
)
apply_visitor_impl(
const int var_which
, Visitor& visitor
, VoidPtrCV storage
, mpl::true_// next_is_last
, Which* = 0, T* = 0, NI* = 0, LI* = 0
)
{
// No prior iterations matched, so variant content must be last type:
BOOST_ASSERT(var_which == Which::value);
return visitor( cast_storage<T>(storage) );
}
template <
typename Which, typename T
, typename NextIt, typename LastIt
, typename Visitor, typename VoidPtrCV
>
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
typename Visitor::result_type
)
apply_visitor_impl(
const int var_which
, Visitor& visitor
, VoidPtrCV storage
, mpl::false_// next_is_last
, Which* = 0, T* = 0, NextIt* = 0, LastIt* last_it = 0
)
{
// If current iteration matches variant content...
if (var_which == Which::value)
{
// ...then apply visitor to the variant content:
return visitor( cast_storage<T>(storage) );
}
// Otherwise, tail recurse, checking next iteration:
typename mpl::next<Which>::type* next_which = 0;
typename BOOST_MPL_AUX_DEREF_WNKD(NextIt)* next_type = 0;
typedef typename mpl::next<NextIt>::type next_next_it_t;
next_next_it_t* next_next_it = 0;
typedef typename is_same<next_next_it_t, LastIt>::type next_next_is_last;
return apply_visitor_impl(
var_which, visitor, storage, next_next_is_last()
, next_which, next_type, next_next_it, last_it
);
}
}} // namespace detail::variant
//////////////////////////////////////////////////////////////////////////
@@ -1298,79 +1381,6 @@ public: // queries
return this->apply_visitor(visitor);
}
private: // helpers, for visitation support (below)
template <typename T>
static T& cast_storage(void* storage, T* = 0)
{
return *static_cast<T*>(storage);
}
template <typename T>
static const T& cast_storage(const void* storage, T* = 0)
{
return *static_cast<const T*>(storage);
}
template <
typename Which, typename T
, typename NextIt, typename LastIt
, typename Visitor, typename VoidPtrCV
>
static
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
typename Visitor::result_type
)
apply_visitor_impl(
const int var_which // [const-ness may aid in optimization by compiler]
, Visitor& visitor
, VoidPtrCV storage
, mpl::false_// next_is_last
, Which* = 0, T* type = 0, NextIt* = 0, LastIt* last_it = 0
)
{
// If current iteration matches variant content...
if (var_which == Which::value)
{
// ...then apply visitor to the variant content:
return visitor( cast_storage(storage, type) );
}
// Otherwise, tail recurse, checking next iteration:
typename mpl::next<Which>::type* next_which = 0;
typename BOOST_MPL_AUX_DEREF_WNKD(NextIt)* next_type = 0;
typedef typename mpl::next<NextIt>::type next_next_it_t;
next_next_it_t* next_next_it = 0;
typedef typename is_same<next_next_it_t, LastIt>::type next_next_is_last;
return apply_visitor_impl(
var_which, visitor, storage, next_next_is_last()
, next_which, next_type, next_next_it, last_it
);
}
template <
typename Which, typename T
, typename NI, typename LI
, typename Visitor, typename VoidPtrCV
>
static
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
typename Visitor::result_type
)
apply_visitor_impl(
const int var_which
, Visitor& visitor
, VoidPtrCV storage
, mpl::true_// next_is_last
, Which* = 0, T* type = 0, NI* = 0, LI* = 0
)
{
// No prior iterations matched, so variant content must be last type:
BOOST_ASSERT(var_which == Which::value);
return visitor( cast_storage(storage, type) );
}
// helpers, for visitation support (below) -- private when possible
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
@@ -1397,7 +1407,7 @@ public:
typename mpl::next<first_it>::type* next_it = 0;
typename mpl::end<types>::type* last_it = 0;
return apply_visitor_impl(
return detail::variant::apply_visitor_impl(
which(), visitor, active_storage(), mpl::false_()
, first_which, first_type, next_it, last_it
);
@@ -1415,7 +1425,7 @@ public:
typename mpl::next<first_it>::type* next_it = 0;
typename mpl::end<types>::type* last_it = 0;
return apply_visitor_impl(
return detail::variant::apply_visitor_impl(
which(), visitor, active_storage(), mpl::false_()
, first_which, first_type, next_it, last_it
);