/usr/include/boost/variant
Edit: /usr/include/boost/variant/polymorphic_get.hpp (11189B)
//-----------------------------------------------------------------------------
// boost variant/polymorphic_get.hpp header file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2013-2020 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_VARIANT_POLYMORPHIC_GET_HPP
#define BOOST_VARIANT_POLYMORPHIC_GET_HPP
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace boost {
//////////////////////////////////////////////////////////////////////////
// class bad_polymorphic_get
//
// The exception thrown in the event of a failed get of a value.
//
class BOOST_SYMBOL_VISIBLE bad_polymorphic_get
: public bad_get
{
public: // std::exception implementation
virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
{
return "boost::bad_polymorphic_get: "
"failed value get using boost::polymorphic_get";
}
};
//////////////////////////////////////////////////////////////////////////
// function template get
//
// Retrieves content of given variant object if content is of type T.
// Otherwise: pointer ver. returns 0; reference ver. throws bad_get.
//
namespace detail { namespace variant {
///////////////////////////////////////////////////////////////////////////////////////////////////
// polymorphic metafunctions to detect index of a value
//
template
struct element_polymorphic_iterator_impl :
boost::mpl::find_if<
Types,
boost::mpl::or_<
variant_element_functor,
variant_element_functor::type >,
boost::is_base_of
>
>
{};
template
struct holds_element_polymorphic :
boost::mpl::not_<
boost::is_same<
typename boost::mpl::end::type,
typename element_polymorphic_iterator_impl::type >::type
>
>
{};
// (detail) class template get_polymorphic_visitor
//
// Generic static visitor that: if the value is of the specified
// type or of a type derived from specified, returns a pointer
// to the value it visits; else a null pointer.
//
template
struct get_polymorphic_visitor
{
private: // private typedefs
typedef get_polymorphic_visitor this_type;
typedef typename add_pointer::type pointer;
typedef typename add_reference::type reference;
pointer get(reference operand, boost::true_type) const BOOST_NOEXCEPT
{
return boost::addressof(operand);
}
template
pointer get(T&, boost::false_type) const BOOST_NOEXCEPT
{
return static_cast(0);
}
public: // visitor interfaces
typedef pointer result_type;
template
pointer operator()(U& operand) const BOOST_NOEXCEPT
{
typedef typename boost::remove_reference::type base_t;
typedef boost::integral_constant<
bool,
(
boost::is_base_of::value &&
(boost::is_const::value || !boost::is_const::value)
)
|| boost::is_same::value
|| boost::is_same::type, U >::value
> tag_t;
return this_type::get(operand, tag_t());
}
};
}} // namespace detail::variant
#ifndef BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE
# if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0551))
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
# else
# if defined(BOOST_NO_NULLPTR)
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
, t* = 0
# else
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
, t* = nullptr
# endif
# endif
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// polymorphic_relaxed_get
//
template
inline
typename add_pointer::type
polymorphic_relaxed_get(
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
) BOOST_NOEXCEPT
{
typedef typename add_pointer::type U_ptr;
if (!operand) return static_cast(0);
detail::variant::get_polymorphic_visitor v;
return operand->apply_visitor(v);
}
template
inline
typename add_pointer::type
polymorphic_relaxed_get(
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
) BOOST_NOEXCEPT
{
typedef typename add_pointer::type U_ptr;
if (!operand) return static_cast(0);
detail::variant::get_polymorphic_visitor v;
return operand->apply_visitor(v);
}
template
inline
typename add_reference::type
polymorphic_relaxed_get(
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
)
{
typedef typename add_pointer::type U_ptr;
U_ptr result = polymorphic_relaxed_get(&operand);
if (!result)
boost::throw_exception(bad_polymorphic_get());
return *result;
}
template
inline
typename add_reference::type
polymorphic_relaxed_get(
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
)
{
typedef typename add_pointer::type U_ptr;
U_ptr result = polymorphic_relaxed_get(&operand);
if (!result)
boost::throw_exception(bad_polymorphic_get());
return *result;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// polymorphic_strict_get
//
template
inline
typename add_pointer::type
polymorphic_strict_get(
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT_MSG(
(boost::detail::variant::holds_element_polymorphic, U >::value),
"boost::variant does not contain specified type U, "
"call to boost::polymorphic_get(boost::variant*) will always return NULL"
);
return polymorphic_relaxed_get(operand);
}
template
inline
typename add_pointer::type
polymorphic_strict_get(
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT_MSG(
(boost::detail::variant::holds_element_polymorphic, U >::value),
"boost::variant does not contain specified type U, "
"call to boost::polymorphic_get(const boost::variant*) will always return NULL"
);
return polymorphic_relaxed_get(operand);
}
template
inline
typename add_reference::type
polymorphic_strict_get(
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
)
{
BOOST_STATIC_ASSERT_MSG(
(boost::detail::variant::holds_element_polymorphic, U >::value),
"boost::variant does not contain specified type U, "
"call to boost::polymorphic_get(boost::variant&) will always throw boost::bad_polymorphic_get exception"
);
return polymorphic_relaxed_get(operand);
}
template
inline
typename add_reference::type
polymorphic_strict_get(
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
)
{
BOOST_STATIC_ASSERT_MSG(
(boost::detail::variant::holds_element_polymorphic, U >::value),
"boost::variant does not contain specified type U, "
"call to boost::polymorphic_get(const boost::variant&) will always throw boost::bad_polymorphic_get exception"
);
return polymorphic_relaxed_get(operand);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// polymorphic_get(variant) methods
//
template
inline
typename add_pointer::type
polymorphic_get(
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
) BOOST_NOEXCEPT
{
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
return polymorphic_relaxed_get(operand);
#else
return polymorphic_strict_get(operand);
#endif
}
template
inline
typename add_pointer::type
polymorphic_get(
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
) BOOST_NOEXCEPT
{
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
return polymorphic_relaxed_get(operand);
#else
return polymorphic_strict_get(operand);
#endif
}
template
inline
typename add_reference::type
polymorphic_get(
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
)
{
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
return polymorphic_relaxed_get(operand);
#else
return polymorphic_strict_get(operand);
#endif
}
template
inline
typename add_reference::type
polymorphic_get(
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
)
{
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
return polymorphic_relaxed_get(operand);
#else
return polymorphic_strict_get(operand);
#endif
}
} // namespace boost
#endif // BOOST_VARIANT_POLYMORPHIC_GET_HPP