/*************************************************************************** * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and * * Martin Renou * * 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_OPTIONAL_META_HPP #define XTL_OPTIONAL_META_HPP #include #include "xmasked_value_meta.hpp" #include "xmeta_utils.hpp" #include "xtype_traits.hpp" namespace xtl { template class xoptional; namespace detail { template struct is_xoptional_impl : std::false_type { }; template struct is_xoptional_impl> : std::true_type { }; template using converts_from_xoptional = disjunction< std::is_constructible&>, std::is_constructible&>, std::is_constructible&&>, std::is_constructible&&>, std::is_convertible&, CT>, std::is_convertible&, CT>, std::is_convertible&&, CT>, std::is_convertible&&, CT> >; template using assigns_from_xoptional = disjunction< std::is_assignable, const xoptional&>, std::is_assignable, xoptional&>, std::is_assignable, const xoptional&&>, std::is_assignable, xoptional&&> >; template struct common_optional_impl; template struct common_optional_impl { using type = std::conditional_t::value, T, xoptional>; }; template struct identity { using type = T; }; template struct get_value_type { using type = typename T::value_type; }; template struct common_optional_impl { using decay_t1 = std::decay_t; using decay_t2 = std::decay_t; using type1 = xtl::mpl::eval_if_t, identity, get_value_type>; using type2 = xtl::mpl::eval_if_t, identity, get_value_type>; using type = xoptional>; }; template struct common_optional_impl> : common_optional_impl { }; template struct common_optional_impl, T2> : common_optional_impl { }; template struct common_optional_impl, xoptional> : common_optional_impl { }; template struct common_optional_impl { using type = typename common_optional_impl< typename common_optional_impl::type, Args... >::type; }; } template using is_xoptional = detail::is_xoptional_impl; template using disable_xoptional = std::enable_if_t::value, R>; template struct at_least_one_xoptional : disjunction...> { }; template struct common_optional : detail::common_optional_impl { }; template using common_optional_t = typename common_optional::type; template struct is_not_xoptional_nor_xmasked_value : negation, is_xmasked_value>> { }; } #endif