| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- /***************************************************************************
- * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
- * Copyright (c) QuantStack *
- * *
- * Distributed under the terms of the BSD 3-Clause License. *
- * *
- * The full license is in the file LICENSE, distributed with this software. *
- ****************************************************************************/
- #ifndef XTL_XVARIANT_HPP
- #define XTL_XVARIANT_HPP
- #include "xvariant_impl.hpp"
- #include "xclosure.hpp"
- #include "xmeta_utils.hpp"
- namespace xtl
- {
- using mpark::variant;
- using mpark::monostate;
- using mpark::bad_variant_access;
- using mpark::variant_size;
- #ifdef MPARK_VARIABLE_TEMPLATES
- using mpark::variant_size_v;
- #endif
- using mpark::variant_alternative;
- using mpark::variant_alternative_t;
- using mpark::variant_npos;
- using mpark::visit;
- using mpark::holds_alternative;
- using mpark::get;
- using mpark::get_if;
- namespace detail
- {
- template <class T>
- struct xgetter
- {
- template <class... Ts>
- static constexpr T& get(xtl::variant<Ts...>& v)
- {
- return xtl::get<T>(v);
- }
- template <class... Ts>
- static constexpr T&& get(xtl::variant<Ts...>&& v)
- {
- return xtl::get<T>(std::move(v));
- }
- template <class... Ts>
- static constexpr const T& get(const xtl::variant<Ts...>& v)
- {
- return xtl::get<T>(v);
- }
- template <class... Ts>
- static constexpr const T&& get(const xtl::variant<Ts...>&& v)
- {
- return xtl::get<T>(std::move(v));
- }
- };
- template <class T>
- struct xgetter<T&>
- {
- template <class... Ts>
- static constexpr T& get(xtl::variant<Ts...>& v)
- {
- return xtl::get<xtl::xclosure_wrapper<T&>>(v).get();
- }
- template <class... Ts>
- static constexpr T& get(xtl::variant<Ts...>&& v)
- {
- return xtl::get<xtl::xclosure_wrapper<T&>>(std::move(v)).get();
- }
- template <class... Ts>
- static constexpr const T& get(const xtl::variant<Ts...>& v)
- {
- return xtl::get<xtl::xclosure_wrapper<T&>>(v).get();
- }
- template <class... Ts>
- static constexpr const T& get(const xtl::variant<Ts...>&& v)
- {
- return xtl::get<xtl::xclosure_wrapper<T&>>(std::move(v)).get();
- }
- };
- template <class T>
- struct xgetter<const T&>
- {
- template <class... Ts>
- static constexpr const T& get(const xtl::variant<Ts...>& v)
- {
- using cl_type = xtl::xclosure_wrapper<const T&>;
- return get_impl(v, xtl::mpl::contains<xtl::mpl::vector<Ts...>, cl_type>());
- }
- template <class... Ts>
- static constexpr const T& get(const xtl::variant<Ts...>&& v)
- {
- using cl_type = xtl::xclosure_wrapper<const T&>;
- return get_impl(std::move(v), xtl::mpl::contains<xtl::mpl::vector<Ts...>, cl_type>());
- }
- template <class... Ts>
- static constexpr const T& get(xtl::variant<Ts...>& v)
- {
- return get(static_cast<const xtl::variant<Ts...>&>(v));
- }
- template <class... Ts>
- static constexpr const T& get(xtl::variant<Ts...>&& v)
- {
- return get(static_cast<const xtl::variant<Ts...>&&>(v));
- }
- private:
- template <class... Ts>
- static constexpr const T& get_impl(const xtl::variant<Ts...>& v, xtl::mpl::bool_<true>)
- {
- return xtl::get<xtl::xclosure_wrapper<const T&>>(v).get();
- }
- template <class... Ts>
- static constexpr const T& get_impl(const xtl::variant<Ts...>& v, xtl::mpl::bool_<false>)
- {
- return static_cast<const xtl::xclosure_wrapper<T&>&>(xtl::get<xtl::xclosure_wrapper<T&>>(v)).get();
- }
- template <class... Ts>
- static constexpr const T& get_impl(const xtl::variant<Ts...>&& v, xtl::mpl::bool_<true>)
- {
- return xtl::get<xtl::closure_wrapper<const T&>>(std::move(v)).get();
- }
- template <class... Ts>
- static constexpr const T& get_impl(const xtl::variant<Ts...>&& v, xtl::mpl::bool_<false>)
- {
- return static_cast<const xtl::xclosure_wrapper<T&>&&>(xtl::get<xtl::xclosure_wrapper<T&>>(std::move(v))).get();
- }
- };
- }
- template <class T, class... Ts>
- constexpr decltype(auto) xget(xtl::variant<Ts...>& v)
- {
- return detail::xgetter<T>::get(v);
- }
- template <class T, class... Ts>
- constexpr decltype(auto) xget(xtl::variant<Ts...>&& v)
- {
- return detail::xgetter<T>::get(std::move(v));
- }
- template <class T, class... Ts>
- constexpr decltype(auto) xget(const xtl::variant<Ts...>& v)
- {
- return detail::xgetter<T>::get(v);
- }
- template <class T, class... Ts>
- constexpr decltype(auto) xget(const xtl::variant<Ts...>&& v)
- {
- return detail::xgetter<T>::get(std::move(v));
- }
- /************************
- * overload for lambdas *
- ************************/
- // This hierarchy is required since ellipsis in using declarations are not supported until C++17
- template <class... Ts>
- struct overloaded;
- template <class T>
- struct overloaded<T> : T
- {
- overloaded(T arg) : T(arg) {}
- using T::operator();
- };
- template <class T1, class T2, class... Ts>
- struct overloaded<T1, T2, Ts...> : T1, overloaded<T2, Ts...>
- {
- template <class... Us>
- overloaded(T1 t1, T2 t2, Us... args) : T1(t1), overloaded<T2, Ts...>(t2, args...) {}
- using T1::operator();
- using overloaded<T2, Ts...>::operator();
- };
- template <class... Ts>
- inline overloaded<Ts...> make_overload(Ts... arg)
- {
- return overloaded<Ts...>{arg...};
- }
- }
- #endif
|