File indexing completed on 2025-01-31 10:02:37
0001
0002
0003
0004
0005
0006
0007 #if !defined(BOOST_SPIRIT_X3_VARIANT_AUGUST_6_2011_0859AM)
0008 #define BOOST_SPIRIT_X3_VARIANT_AUGUST_6_2011_0859AM
0009
0010 #include <boost/config.hpp>
0011 #include <boost/variant.hpp>
0012 #include <boost/mpl/list.hpp>
0013 #include <utility>
0014 #include <type_traits>
0015
0016
0017 namespace boost { namespace spirit { namespace x3
0018 {
0019 template <typename T>
0020 class forward_ast
0021 {
0022 public:
0023
0024 typedef T type;
0025
0026 public:
0027
0028 forward_ast() : p_(new T) {}
0029
0030 forward_ast(forward_ast const& operand)
0031 : p_(new T(operand.get())) {}
0032
0033 forward_ast(forward_ast&& operand) BOOST_NOEXCEPT
0034 : p_(operand.p_)
0035 {
0036 operand.p_ = 0;
0037 }
0038
0039 forward_ast(T const& operand)
0040 : p_(new T(operand)) {}
0041
0042 forward_ast(T&& operand)
0043 : p_(new T(std::move(operand))) {}
0044
0045 ~forward_ast()
0046 {
0047 boost::checked_delete(p_);
0048 }
0049
0050 forward_ast& operator=(forward_ast const& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<T>::value)
0051 {
0052 assign(rhs.get());
0053 return *this;
0054 }
0055
0056 void swap(forward_ast& operand) BOOST_NOEXCEPT
0057 {
0058 T* temp = operand.p_;
0059 operand.p_ = p_;
0060 p_ = temp;
0061 }
0062
0063 forward_ast& operator=(T const& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<T>::value)
0064 {
0065 assign(rhs);
0066 return *this;
0067 }
0068
0069 forward_ast& operator=(forward_ast&& rhs) BOOST_NOEXCEPT
0070 {
0071 swap(rhs);
0072 return *this;
0073 }
0074
0075 forward_ast& operator=(T&& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_move_assignable<T>::value)
0076 {
0077 get() = std::move(rhs);
0078 return *this;
0079 }
0080
0081 T& get() BOOST_NOEXCEPT { return *get_pointer(); }
0082 const T& get() const BOOST_NOEXCEPT { return *get_pointer(); }
0083
0084 T* get_pointer() BOOST_NOEXCEPT { return p_; }
0085 const T* get_pointer() const BOOST_NOEXCEPT { return p_; }
0086
0087 operator T const&() const BOOST_NOEXCEPT { return this->get(); }
0088 operator T&() BOOST_NOEXCEPT { return this->get(); }
0089
0090 private:
0091
0092 void assign(const T& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<T>::value)
0093 {
0094 this->get() = rhs;
0095 }
0096
0097 T* p_;
0098 };
0099
0100
0101
0102
0103
0104 template <typename T>
0105 inline void swap(forward_ast<T>& lhs, forward_ast<T>& rhs) BOOST_NOEXCEPT
0106 {
0107 lhs.swap(rhs);
0108 }
0109
0110 namespace detail
0111 {
0112 template <typename T>
0113 struct remove_forward : mpl::identity<T>
0114 {};
0115
0116 template <typename T>
0117 struct remove_forward<forward_ast<T>> : mpl::identity<T>
0118 {};
0119 }
0120
0121 #if defined(BOOST_MSVC)
0122 # pragma warning(push)
0123 # pragma warning(disable: 4521)
0124 #endif
0125 template <typename ...Types>
0126 struct variant
0127 {
0128
0129 struct adapted_variant_tag;
0130
0131 using variant_type = boost::variant<Types...>;
0132 using types = mpl::list<typename detail::remove_forward<Types>::type...>;
0133 using base_type = variant;
0134
0135 template<typename T>
0136 using non_self_t
0137 = std::enable_if_t<!(std::is_base_of<base_type
0138 ,std::remove_reference_t<T>
0139 >
0140 ::value)
0141 >;
0142
0143 variant() BOOST_NOEXCEPT_IF(std::is_nothrow_default_constructible<variant_type>::value) : var() {}
0144
0145 template <typename T, class = non_self_t<T>>
0146 explicit variant(T const& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_constructible<variant_type, T const&>::value))
0147 : var(rhs) {}
0148
0149 template <typename T, class = non_self_t<T>>
0150 explicit variant(T&& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_constructible<variant_type, T&&>::value))
0151 : var(std::forward<T>(rhs)) {}
0152
0153 variant(variant const& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_constructible<variant_type>::value)
0154 : var(rhs.var) {}
0155
0156 variant(variant& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_constructible<variant_type, variant_type&>::value))
0157 : var(rhs.var) {}
0158
0159 variant(variant&& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_move_constructible<variant_type>::value)
0160 : var(std::move(rhs.var)) {}
0161
0162 variant& operator=(variant const& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<variant_type>::value)
0163 {
0164 var = rhs.get();
0165 return *this;
0166 }
0167
0168 variant& operator=(variant&& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_move_assignable<variant_type>::value)
0169 {
0170 var = std::move(rhs.get());
0171 return *this;
0172 }
0173
0174 template <typename T, class = non_self_t<T>>
0175 variant& operator=(T const& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_assignable<variant_type, T const&>::value))
0176 {
0177 var = rhs;
0178 return *this;
0179 }
0180
0181 template <typename T, class = non_self_t<T>>
0182 variant& operator=(T&& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_assignable<variant_type, T&&>::value))
0183 {
0184 var = std::forward<T>(rhs);
0185 return *this;
0186 }
0187
0188 template <typename F>
0189 typename F::result_type apply_visitor(F const& v)
0190 {
0191 return var.apply_visitor(v);
0192 }
0193
0194 template <typename F>
0195 typename F::result_type apply_visitor(F const& v) const
0196 {
0197 return var.apply_visitor(v);
0198 }
0199
0200 template <typename F>
0201 typename F::result_type apply_visitor(F& v)
0202 {
0203 return var.apply_visitor(v);
0204 }
0205
0206 template <typename F>
0207 typename F::result_type apply_visitor(F& v) const
0208 {
0209 return var.apply_visitor(v);
0210 }
0211
0212 variant_type const& get() const BOOST_NOEXCEPT
0213 {
0214 return var;
0215 }
0216
0217 variant_type& get() BOOST_NOEXCEPT
0218 {
0219 return var;
0220 }
0221
0222 void swap(variant& rhs) BOOST_NOEXCEPT
0223 {
0224 var.swap(rhs.var);
0225 }
0226
0227 variant_type var;
0228 };
0229 #if defined(BOOST_MSVC)
0230 # pragma warning(pop)
0231 #endif
0232 }}}
0233
0234 namespace boost
0235 {
0236 template <typename T, typename ...Types>
0237 inline T const&
0238 get(boost::spirit::x3::variant<Types...> const& x) BOOST_NOEXCEPT
0239 {
0240 return boost::get<T>(x.get());
0241 }
0242
0243 template <typename T, typename ...Types>
0244 inline T&
0245 get(boost::spirit::x3::variant<Types...>& x) BOOST_NOEXCEPT
0246 {
0247 return boost::get<T>(x.get());
0248 }
0249
0250 template <typename T, typename ...Types>
0251 inline T const*
0252 get(boost::spirit::x3::variant<Types...> const* x) BOOST_NOEXCEPT
0253 {
0254 return boost::get<T>(&x->get());
0255 }
0256
0257 template <typename T, typename ...Types>
0258 inline T*
0259 get(boost::spirit::x3::variant<Types...>* x) BOOST_NOEXCEPT
0260 {
0261 return boost::get<T>(&x->get());
0262 }
0263 }
0264
0265 #endif