📄 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, <= 1200)public: // visitor interface bool operator()(T& lhs) { lhs = rhs_; return true; } template <typename U> bool operator()(U&) { return false; }#else // MSVC6private: // 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) workaroundpublic: // 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 + -