summaryrefslogtreecommitdiff
path: root/boost/spirit/home/x3/support/ast/variant.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/spirit/home/x3/support/ast/variant.hpp')
-rw-r--r--boost/spirit/home/x3/support/ast/variant.hpp249
1 files changed, 249 insertions, 0 deletions
diff --git a/boost/spirit/home/x3/support/ast/variant.hpp b/boost/spirit/home/x3/support/ast/variant.hpp
new file mode 100644
index 0000000000..cf626e88be
--- /dev/null
+++ b/boost/spirit/home/x3/support/ast/variant.hpp
@@ -0,0 +1,249 @@
+/*=============================================================================
+ 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
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/variant.hpp>
+#include <boost/mpl/list.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+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)
+ : 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)
+ {
+ 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)
+ {
+ assign(rhs);
+ return *this;
+ }
+
+ forward_ast& operator=(forward_ast&& rhs) BOOST_NOEXCEPT
+ {
+ swap(rhs);
+ return *this;
+ }
+
+ forward_ast& operator=(T&& rhs)
+ {
+ get() = std::move(rhs);
+ return *this;
+ }
+
+ T& get() { return *get_pointer(); }
+ const T& get() const { return *get_pointer(); }
+
+ T* get_pointer() { return p_; }
+ const T* get_pointer() const { return p_; }
+
+ operator T const&() const { return this->get(); }
+ operator T&() { return this->get(); }
+
+ private:
+
+ void assign(const T& rhs)
+ {
+ 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>
+ {};
+ }
+
+ template <typename ...Types>
+ struct variant
+ {
+ // tell spirit that this is an adapted variant
+ struct adapted_variant_tag;
+
+ typedef boost::variant<Types...> variant_type;
+ typedef mpl::list<typename detail::remove_forward<Types>::type...> types;
+ typedef variant<Types...> base_type;
+
+ variant() : var() {}
+
+ template <typename T, typename disable_if<is_base_of<base_type, T>>::type>
+ explicit variant(T const& rhs)
+ : var(rhs) {}
+
+ template <typename T, typename disable_if<is_base_of<base_type, T>>::type>
+ explicit variant(T&& rhs)
+ : var(std::forward<T>(rhs)) {}
+
+ variant(variant const& rhs)
+ : var(rhs.var) {}
+
+ variant(variant& rhs)
+ : var(rhs.var) {}
+
+ variant(variant&& rhs)
+ : var(std::forward<variant_type>(rhs.var)) {}
+
+ variant& operator=(variant const& rhs)
+ {
+ var = rhs.get();
+ return *this;
+ }
+
+ variant& operator=(variant&& rhs)
+ {
+ var = std::forward<variant_type>(rhs.get());
+ return *this;
+ }
+
+ template <typename T>
+ //typename disable_if<is_base_of<base_type, T>, variant&>::type
+ variant& operator=(T const& rhs)
+ {
+ var = rhs;
+ return *this;
+ }
+
+ template <typename T>
+ //typename disable_if<is_base_of<base_type, T>, variant&>::type
+ variant& operator=(T&& rhs)
+ {
+ 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
+ {
+ return var;
+ }
+
+ variant_type& get()
+ {
+ return var;
+ }
+
+ variant_type var;
+ };
+}}}
+
+namespace boost
+{
+ template <typename T, typename ...Types>
+ inline T const&
+ get(boost::spirit::x3::variant<Types...> const& x)
+ {
+ return boost::get<T>(x.get());
+ }
+
+ template <typename T, typename ...Types>
+ inline T&
+ get(boost::spirit::x3::variant<Types...>& x)
+ {
+ return boost::get<T>(x.get());
+ }
+
+ template <typename T, typename ...Types>
+ inline T const*
+ get(boost::spirit::x3::variant<Types...> const* x)
+ {
+ return boost::get<T>(&x->get());
+ }
+
+ template <typename T, typename ...Types>
+ inline T*
+ get(boost::spirit::x3::variant<Types...>* x)
+ {
+ return boost::get<T>(&x->get());
+ }
+}
+
+#endif