EVOLUTION-MANAGER
Edit File: variant.hpp
/*============================================================================= Copyright (c) 2001-2014 Joel de Guzman 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) ==============================================================================*/ #if !defined(BOOST_SPIRIT_X3_VARIANT_AUGUST_6_2011_0859AM) #define BOOST_SPIRIT_X3_VARIANT_AUGUST_6_2011_0859AM #include <boost/config.hpp> #include <boost/variant.hpp> #include <boost/mpl/list.hpp> #include <utility> #include <type_traits> /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { namespace x3 { template <typename T> class forward_ast { public: typedef T type; public: forward_ast() : p_(new T) {} forward_ast(forward_ast const& operand) : p_(new T(operand.get())) {} forward_ast(forward_ast&& operand) BOOST_NOEXCEPT : p_(operand.p_) { operand.p_ = 0; } forward_ast(T const& operand) : p_(new T(operand)) {} forward_ast(T&& operand) : p_(new T(std::move(operand))) {} ~forward_ast() { boost::checked_delete(p_); } forward_ast& operator=(forward_ast const& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<T>::value) { assign(rhs.get()); return *this; } void swap(forward_ast& operand) BOOST_NOEXCEPT { T* temp = operand.p_; operand.p_ = p_; p_ = temp; } forward_ast& operator=(T const& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<T>::value) { assign(rhs); return *this; } forward_ast& operator=(forward_ast&& rhs) BOOST_NOEXCEPT { swap(rhs); return *this; } forward_ast& operator=(T&& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_move_assignable<T>::value) { get() = std::move(rhs); return *this; } T& get() BOOST_NOEXCEPT { return *get_pointer(); } const T& get() const BOOST_NOEXCEPT { return *get_pointer(); } T* get_pointer() BOOST_NOEXCEPT { return p_; } const T* get_pointer() const BOOST_NOEXCEPT { return p_; } operator T const&() const BOOST_NOEXCEPT { return this->get(); } operator T&() BOOST_NOEXCEPT { return this->get(); } private: void assign(const T& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<T>::value) { this->get() = rhs; } T* p_; }; // function template swap // // Swaps two forward_ast<T> objects of the same type T. // template <typename T> inline void swap(forward_ast<T>& lhs, forward_ast<T>& rhs) BOOST_NOEXCEPT { lhs.swap(rhs); } namespace detail { template <typename T> struct remove_forward : mpl::identity<T> {}; template <typename T> struct remove_forward<forward_ast<T>> : mpl::identity<T> {}; } #if defined(BOOST_MSVC) # pragma warning(push) # pragma warning(disable: 4521) // multiple copy constructors specified #endif template <typename ...Types> struct variant { // tell spirit that this is an adapted variant struct adapted_variant_tag; using variant_type = boost::variant<Types...>; using types = mpl::list<typename detail::remove_forward<Types>::type...>; using base_type = variant; // The current instantiation template<typename T> using non_self_t // used only for SFINAE checks below = std::enable_if_t<!(std::is_base_of<base_type ,std::remove_reference_t<T> > ::value) >; variant() BOOST_NOEXCEPT_IF(std::is_nothrow_default_constructible<variant_type>::value) : var() {} template <typename T, class = non_self_t<T>> explicit variant(T const& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_constructible<variant_type, T const&>::value)) : var(rhs) {} template <typename T, class = non_self_t<T>> explicit variant(T&& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_constructible<variant_type, T&&>::value)) : var(std::forward<T>(rhs)) {} variant(variant const& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_constructible<variant_type>::value) : var(rhs.var) {} variant(variant& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_constructible<variant_type, variant_type&>::value)) : var(rhs.var) {} variant(variant&& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_move_constructible<variant_type>::value) : var(std::move(rhs.var)) {} variant& operator=(variant const& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<variant_type>::value) { var = rhs.get(); return *this; } variant& operator=(variant&& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_move_assignable<variant_type>::value) { var = std::move(rhs.get()); return *this; } template <typename T, class = non_self_t<T>> variant& operator=(T const& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_assignable<variant_type, T const&>::value)) { var = rhs; return *this; } template <typename T, class = non_self_t<T>> variant& operator=(T&& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_assignable<variant_type, T&&>::value)) { var = std::forward<T>(rhs); return *this; } template <typename F> typename F::result_type apply_visitor(F const& v) { return var.apply_visitor(v); } template <typename F> typename F::result_type apply_visitor(F const& v) const { return var.apply_visitor(v); } template <typename F> typename F::result_type apply_visitor(F& v) { return var.apply_visitor(v); } template <typename F> typename F::result_type apply_visitor(F& v) const { return var.apply_visitor(v); } variant_type const& get() const BOOST_NOEXCEPT { return var; } variant_type& get() BOOST_NOEXCEPT { return var; } void swap(variant& rhs) BOOST_NOEXCEPT { var.swap(rhs.var); } variant_type var; }; #if defined(BOOST_MSVC) # pragma warning(pop) #endif }}} namespace boost { template <typename T, typename ...Types> inline T const& get(boost::spirit::x3::variant<Types...> const& x) BOOST_NOEXCEPT { return boost::get<T>(x.get()); } template <typename T, typename ...Types> inline T& get(boost::spirit::x3::variant<Types...>& x) BOOST_NOEXCEPT { return boost::get<T>(x.get()); } template <typename T, typename ...Types> inline T const* get(boost::spirit::x3::variant<Types...> const* x) BOOST_NOEXCEPT { return boost::get<T>(&x->get()); } template <typename T, typename ...Types> inline T* get(boost::spirit::x3::variant<Types...>* x) BOOST_NOEXCEPT { return boost::get<T>(&x->get()); } } #endif