📄 variant.hpp
字号:
// Hint: Are any of the bounded types const-qualified or references?
//
lhs_content = *static_cast< const T* >(rhs_storage_);
BOOST_VARIANT_AUX_RETURN_VOID;
}
};
///////////////////////////////////////////////////////////////////////////////
// (detail) class direct_assigner
//
// Generic static visitor that: if and only if the visited value is of the
// specified type, assigns the given value to the visited value and returns
// true; else returns false.
//
template <typename T>
class direct_assigner
: public static_visitor<bool>
{
private: // representation
T& rhs_;
public: // structors
explicit direct_assigner(T& rhs)
: rhs_(rhs)
{
}
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
public: // visitor interface
bool operator()(T& lhs)
{
lhs = rhs_;
return true;
}
template <typename U>
bool operator()(U&)
{
return false;
}
#else // MSVC6
private: // helpers, for visitor interface (below)
bool execute(T& lhs, mpl::true_)
{
lhs = rhs_;
return true;
}
template <typename U>
bool execute(U&, mpl::false_)
{
return false;
}
public: // visitor interface
template <typename U>
bool operator()(U& lhs)
{
typedef typename is_same<U,T>::type U_is_T;
return execute(lhs, U_is_T());
}
#endif // MSVC6 workaround
};
///////////////////////////////////////////////////////////////////////////////
// (detail) class backup_assigner
//
// Internal visitor that "assigns" the given value to the visited value,
// using backup to recover if the destroy-copy sequence fails.
//
// NOTE: This needs to be a friend of variant, as it needs access to
// indicate_which, indicate_backup_which, etc.
//
template <typename Variant, typename RhsT>
class backup_assigner
: public static_visitor<>
{
private: // representation
Variant& lhs_;
int rhs_which_;
const RhsT& rhs_content_;
public: // structors
backup_assigner(Variant& lhs, int rhs_which, const RhsT& rhs_content)
: lhs_(lhs)
, rhs_which_(rhs_which)
, rhs_content_(rhs_content)
{
}
private: // helpers, for visitor interface (below)
template <typename LhsT>
void backup_assign_impl(
LhsT& lhs_content
, mpl::true_// has_nothrow_move
)
{
// Move lhs content to backup...
LhsT backup_lhs_content(
::boost::detail::variant::move(lhs_content)
); // nothrow
// ...destroy lhs content...
lhs_content.~LhsT(); // nothrow
try
{
// ...and attempt to copy rhs content into lhs storage:
new(lhs_.storage_.address()) RhsT(rhs_content_);
}
catch (...)
{
// In case of failure, restore backup content to lhs storage...
new(lhs_.storage_.address())
LhsT(
::boost::detail::variant::move(backup_lhs_content)
); // nothrow
// ...and rethrow:
throw;
}
// In case of success, indicate new content type:
lhs_.indicate_which(rhs_which_); // nothrow
}
template <typename LhsT>
void backup_assign_impl(
LhsT& lhs_content
, mpl::false_// has_nothrow_move
)
{
// Backup lhs content...
LhsT* backup_lhs_ptr = new LhsT(lhs_content);
// ...destroy lhs content...
lhs_content.~LhsT(); // nothrow
try
{
// ...and attempt to copy rhs content into lhs storage:
new(lhs_.storage_.address()) RhsT(rhs_content_);
}
catch (...)
{
// In case of failure, copy backup pointer to lhs storage...
new(lhs_.storage_.address())
backup_holder<LhsT>( backup_lhs_ptr ); // nothrow
// ...indicate now using backup...
lhs_.indicate_backup_which( lhs_.which() ); // nothrow
// ...and rethrow:
throw;
}
// In case of success, indicate new content type...
lhs_.indicate_which(rhs_which_); // nothrow
// ...and delete backup:
delete backup_lhs_ptr; // nothrow
}
public: // visitor interface
template <typename LhsT>
BOOST_VARIANT_AUX_RETURN_VOID_TYPE
internal_visit(LhsT& lhs_content, int)
{
typedef typename has_nothrow_move_constructor<LhsT>::type
nothrow_move;
backup_assign_impl( lhs_content, nothrow_move() );
BOOST_VARIANT_AUX_RETURN_VOID;
}
};
///////////////////////////////////////////////////////////////////////////////
// (detail) class swap_with
//
// Visitor that swaps visited value with content of given variant.
//
// Precondition: Given variant MUST have same logical type as visited value.
//
template <typename Variant>
struct swap_with
: public static_visitor<>
{
private: // representation
Variant& toswap_;
public: // structors
explicit swap_with(Variant& toswap)
: toswap_(toswap)
{
}
public: // internal visitor interfaces
template <typename T>
void operator()(T& operand) const
{
// Since the precondition ensures types are same, get T...
known_get<T> getter;
T& other = toswap_.apply_visitor(getter);
// ...and swap:
::boost::detail::variant::move_swap( operand, other );
}
};
///////////////////////////////////////////////////////////////////////////////
// (detail) class reflect
//
// Generic static visitor that performs a typeid on the value it visits.
//
class reflect
: public static_visitor<const std::type_info&>
{
public: // visitor interfaces
template <typename T>
const std::type_info& operator()(const T&) const
{
return typeid(T);
}
};
///////////////////////////////////////////////////////////////////////////////
// (detail) class comparer
//
// Generic static visitor that compares the content of the given lhs variant
// with the visited rhs content using Comp.
//
// Precondition: lhs.which() == rhs.which()
//
template <typename Variant, typename Comp>
class comparer
: public static_visitor<bool>
{
private: // representation
const Variant& lhs_;
public: // structors
explicit comparer(const Variant& lhs)
: lhs_(lhs)
{
}
public: // visitor interfaces
template <typename T>
bool operator()(const T& rhs_content) const
{
// Since the precondition ensures lhs and rhs types are same, get T...
known_get<const T> getter;
const T& lhs_content = lhs_.apply_visitor(getter);
// ...and compare lhs and rhs contents:
return Comp()(lhs_content, rhs_content);
}
};
///////////////////////////////////////////////////////////////////////////////
// (detail) class equal_comp
//
// Generic function object compares lhs with rhs using operator==.
//
struct equal_comp
{
template <typename T>
bool operator()(const T& lhs, const T& rhs) const
{
return lhs == rhs;
}
};
///////////////////////////////////////////////////////////////////////////////
// (detail) class less_comp
//
// Generic function object compares lhs with rhs using operator<.
//
struct less_comp
{
template <typename T>
bool operator()(const T& lhs, const T& rhs) const
{
return lhs < rhs;
}
};
///////////////////////////////////////////////////////////////////////////////
// (detail) class template invoke_visitor
//
// Internal visitor that invokes the given visitor using:
// * for wrappers (e.g., recursive_wrapper), the wrapper's held value.
// * for all other values, the value itself.
//
template <typename Visitor>
class invoke_visitor
{
private: // representation
Visitor& visitor_;
public: // visitor typedefs
typedef typename Visitor::result_type
result_type;
public: // structors
explicit invoke_visitor(Visitor& visitor)
: visitor_(visitor)
{
}
#if !defined(BOOST_NO_VOID_RETURNS)
public: // internal visitor interfaces
template <typename T>
result_type internal_visit(T& operand, int)
{
return visitor_(operand);
}
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564))
template <typename T>
result_type internal_visit(const T& operand, int)
{
return visitor_(operand);
}
# endif
#else // defined(BOOST_NO_VOID_RETURNS)
private: // helpers, for internal visitor interfaces (below)
template <typename T>
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
visit_impl(T& operand, mpl::false_)
{
return visitor_(operand);
}
template <typename T>
BOOST_VARIANT_AUX_RETURN_VOID_TYPE
visit_impl(T& operand, mpl::true_)
{
visitor_(operand);
BOOST_VARIANT_AUX_RETURN_VOID;
}
public: // internal visitor interfaces
template <typename T>
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
internal_visit(T& operand, int)
{
typedef typename is_same<result_type, void>::type
has_void_result_type;
return visit_impl(operand, has_void_result_type());
}
#endif // BOOST_NO_VOID_RETURNS) workaround
public: // internal visitor interfaces, cont.
template <typename T>
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
internal_visit(boost::recursive_wrapper<T>& operand, long)
{
return internal_visit( operand.get(), 1L );
}
template <typename T>
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
internal_visit(const boost::recursive_wrapper<T>& operand, long)
{
return internal_visit( operand.get(), 1L );
}
template <typename T>
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
internal_visit(boost::detail::reference_content<T>& operand, long)
{
return internal_visit( operand.get(), 1L );
}
template <typename T>
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
internal_visit(const boost::detail::reference_content<T>& operand, long)
{
return internal_visit( operand.get(), 1L );
}
template <typename T>
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
internal_visit(boost::detail::variant::backup_holder<T>& operand, long)
{
return internal_visit( operand.get(), 1L );
}
template <typename T>
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
internal_visit(const boost::detail::variant::backup_holder<T>& operand, long)
{
return internal_visit( operand.get(), 1L );
}
};
}} // namespace detail::variant
///////////////////////////////////////////////////////////////////////////////
// class template variant (concept inspired by Andrei Alexandrescu)
//
// See docs and boost/variant/variant_fwd.hpp for more information.
//
template <
typename T0_
, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename T)
>
class variant
{
private: // helpers, for typedefs (below)
typedef variant wknd_self_t;
struct is_recursive_
: detail::variant::is_recursive_flag<T0_>
{
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -