Header file range/v3/utility/common_tuple.hpp

#include <meta/meta.hpp>

#include <range/v3/range_fwd.hpp>

#include <range/v3/utility/concepts.hpp>

#include <range/v3/utility/functional.hpp>

#include <range/v3/utility/tuple_algorithm.hpp>

namespace ranges
{
    inline namespace v3
    {
        namespace detail
        {
            template <typename ... Us, typename Tup, std::size_t ... Is>
            std::tuple<Us...> to_std_tuple(Tup&& tup, meta::index_sequence<Is...>);
        }
        
        template <typename ... Ts>
        struct common_tuple
        : std::tuple<Ts...>
        {
            template <int _concept_requires_67 = 42, typename std::enable_if<(_concept_requires_67==43)||(meta::and_c<(bool)DefaultConstructible<Ts>()>::value), int>::type ... = 0>
            common_tuple() noexcept(meta::and_c<std::is_nothrow_default_constructible<Ts>::value...>::value);
            
            template <typename ... Us, int _concept_requires_73 = 42, typename std::enable_if<(_concept_requires_73==43)||(meta::and_c<(bool)Constructible<Ts, Us&&>()>::value), int>::type ... = 0>
            explicit common_tuple(Us&&... us) noexcept(meta::and_c<std::is_nothrow_constructible<Ts, Us&&>::value...>::value);
            
            template <typename ... Us, int _concept_requires_79 = 42, typename std::enable_if<(_concept_requires_79==43)||(meta::and_c<(bool)Constructible<Ts, Us&>()>::value), int>::type ... = 0>
            common_tuple(std::tuple<Us...>& that) noexcept(meta::and_c<std::is_nothrow_constructible<Ts, Us&>::value...>::value);
            
            template <typename ... Us, int _concept_requires_85 = 42, typename std::enable_if<(_concept_requires_85==43)||(meta::and_c<(bool)Constructible<Ts, Us const&>()>::value), int>::type ... = 0>
            common_tuple(std::tuple<Us...>const& that) noexcept(meta::and_c<std::is_nothrow_constructible<Ts, Us const&>::value...>::value);
            
            template <typename ... Us, int _concept_requires_91 = 42, typename std::enable_if<(_concept_requires_91==43)||(meta::and_c<(bool)Constructible<Ts, Us&&>()>::value), int>::type ... = 0>
            common_tuple(std::tuple<Us...>&& that) noexcept(meta::and_c<std::is_nothrow_constructible<Ts, Us&&>::value...>::value);
            
            template <typename ... Us, int _concept_requires_99 = 42, typename std::enable_if<(_concept_requires_99==43)||(meta::and_c<(bool)Assignable<Ts&, Us&>()>::value), int>::type ... = 0>
            common_tuple& operator=(std::tuple<Us...>& that) noexcept(meta::and_c<std::is_nothrow_assignable<Ts&, Us&>::value...>::value);
            
            template <typename ... Us, int _concept_requires_107 = 42, typename std::enable_if<(_concept_requires_107==43)||(meta::and_c<(bool)Assignable<Ts&, Us const&>()>::value), int>::type ... = 0>
            common_tuple& operator=(std::tuple<Us...>const& that) noexcept(meta::and_c<std::is_nothrow_assignable<Ts&, Us const&>::value...>::value);
            
            template <typename ... Us, int _concept_requires_115 = 42, typename std::enable_if<(_concept_requires_115==43)||(meta::and_c<(bool)Assignable<Ts&, Us&&>()>::value), int>::type ... = 0>
            common_tuple& operator=(std::tuple<Us...>&& that) noexcept(meta::and_c<std::is_nothrow_assignable<Ts&, Us&&>::value...>::value);
            
            template <typename ... Us, int _concept_requires_125 = 42, typename std::enable_if<(_concept_requires_125==43)||(meta::and_c<(bool)Constructible<Us, Ts&>()>::value), int>::type ... = 0>
            operator std::tuple<Us...>() & noexcept(meta::and_c<std::is_nothrow_constructible<Us, Ts&>::value...>::value);
            
            template <typename ... Us, int _concept_requires_132 = 42, typename std::enable_if<(_concept_requires_132==43)||(meta::and_c<(bool)Constructible<Us, Ts const&>()>::value), int>::type ... = 0>
            operator std::tuple<Us...>() const & noexcept(meta::and_c<std::is_nothrow_constructible<Us, Ts const&>::value...>::value);
            
            template <typename ... Us, int _concept_requires_139 = 42, typename std::enable_if<(_concept_requires_139==43)||(meta::and_c<(bool)Constructible<Us, Ts&&>()>::value), int>::type ... = 0>
            operator std::tuple<Us...>() && noexcept(meta::and_c<std::is_nothrow_constructible<Us, Ts&&>::value...>::value);
        };
        
        template <typename ... Ts, typename ... Us, int _concept_requires_168 = 42, typename std::enable_if<(_concept_requires_168==43)||(meta::and_c<(bool)EqualityComparable<Ts, Us>()>::value), int>::type ... = 0>
        bool operator==(common_tuple<Ts...>const& a, common_tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_168 = 42, typename std::enable_if<(_concept_requires_168==43)||(meta::and_c<(bool)EqualityComparable<Ts, Us>()>::value), int>::type ... = 0>
        bool operator==(std::tuple<Ts...>const& a, common_tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_168 = 42, typename std::enable_if<(_concept_requires_168==43)||(meta::and_c<(bool)EqualityComparable<Ts, Us>()>::value), int>::type ... = 0>
        bool operator==(common_tuple<Ts...>const& a, std::tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_169 = 42, typename std::enable_if<(_concept_requires_169==43)||(meta::and_c<(bool)EqualityComparable<Ts, Us>()>::value), int>::type ... = 0>
        bool operator!=(common_tuple<Ts...>const& a, common_tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_169 = 42, typename std::enable_if<(_concept_requires_169==43)||(meta::and_c<(bool)EqualityComparable<Ts, Us>()>::value), int>::type ... = 0>
        bool operator!=(std::tuple<Ts...>const& a, common_tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_169 = 42, typename std::enable_if<(_concept_requires_169==43)||(meta::and_c<(bool)EqualityComparable<Ts, Us>()>::value), int>::type ... = 0>
        bool operator!=(common_tuple<Ts...>const& a, std::tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_170 = 42, typename std::enable_if<(_concept_requires_170==43)||(meta::and_c<(bool)TotallyOrdered<Ts, Us>()>::value), int>::type ... = 0>
        bool operator<(common_tuple<Ts...>const& a, common_tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_170 = 42, typename std::enable_if<(_concept_requires_170==43)||(meta::and_c<(bool)TotallyOrdered<Ts, Us>()>::value), int>::type ... = 0>
        bool operator<(std::tuple<Ts...>const& a, common_tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_170 = 42, typename std::enable_if<(_concept_requires_170==43)||(meta::and_c<(bool)TotallyOrdered<Ts, Us>()>::value), int>::type ... = 0>
        bool operator<(common_tuple<Ts...>const& a, std::tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_171 = 42, typename std::enable_if<(_concept_requires_171==43)||(meta::and_c<(bool)TotallyOrdered<Ts, Us>()>::value), int>::type ... = 0>
        bool operator<=(common_tuple<Ts...>const& a, common_tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_171 = 42, typename std::enable_if<(_concept_requires_171==43)||(meta::and_c<(bool)TotallyOrdered<Ts, Us>()>::value), int>::type ... = 0>
        bool operator<=(std::tuple<Ts...>const& a, common_tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_171 = 42, typename std::enable_if<(_concept_requires_171==43)||(meta::and_c<(bool)TotallyOrdered<Ts, Us>()>::value), int>::type ... = 0>
        bool operator<=(common_tuple<Ts...>const& a, std::tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_172 = 42, typename std::enable_if<(_concept_requires_172==43)||(meta::and_c<(bool)TotallyOrdered<Ts, Us>()>::value), int>::type ... = 0>
        bool operator>(common_tuple<Ts...>const& a, common_tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_172 = 42, typename std::enable_if<(_concept_requires_172==43)||(meta::and_c<(bool)TotallyOrdered<Ts, Us>()>::value), int>::type ... = 0>
        bool operator>(std::tuple<Ts...>const& a, common_tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_172 = 42, typename std::enable_if<(_concept_requires_172==43)||(meta::and_c<(bool)TotallyOrdered<Ts, Us>()>::value), int>::type ... = 0>
        bool operator>(common_tuple<Ts...>const& a, std::tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_173 = 42, typename std::enable_if<(_concept_requires_173==43)||(meta::and_c<(bool)TotallyOrdered<Ts, Us>()>::value), int>::type ... = 0>
        bool operator>=(common_tuple<Ts...>const& a, common_tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_173 = 42, typename std::enable_if<(_concept_requires_173==43)||(meta::and_c<(bool)TotallyOrdered<Ts, Us>()>::value), int>::type ... = 0>
        bool operator>=(std::tuple<Ts...>const& a, common_tuple<Us...>const& b);
        
        template <typename ... Ts, typename ... Us, int _concept_requires_173 = 42, typename std::enable_if<(_concept_requires_173==43)||(meta::and_c<(bool)TotallyOrdered<Ts, Us>()>::value), int>::type ... = 0>
        bool operator>=(common_tuple<Ts...>const& a, std::tuple<Us...>const& b);
        
        struct make_common_tuple_fn
        {
            template <typename ... Args>
            common_tuple<bind_element_t<Args>...> operator()(Args&&... args) const noexcept(meta::and_c<std::is_nothrow_constructible<bind_element_t<Args>, unwrap_reference_t<Args>>::value...>::value);
        };
        
        inline namespace 
        {
            constexpr auto& make_common_tuple = static_const<make_common_tuple_fn>::value;
        }
        
        template <typename F, typename S>
        struct common_pair
        : std::pair<F, S>
        {
            template <int _concept_requires_205 = 42, typename std::enable_if<(_concept_requires_205==43)||(DefaultConstructible<F>()&&DefaultConstructible<S>()), int>::type=0>
            common_pair() noexcept(std::is_nothrow_default_constructible<F>::value&&std::is_nothrow_default_constructible<S>::value);
            
            template <typename F2, typename S2, int _concept_requires_212 = 42, typename std::enable_if<(_concept_requires_212==43)||(Constructible<F, F2&&>()&&Constructible<S, S2&&>()), int>::type=0>
            common_pair(F2&& f2, S2&& s2) noexcept(std::is_nothrow_constructible<F, F2&&>::value&&std::is_nothrow_constructible<S, S2&&>::value);
            
            template <typename F2, typename S2, int _concept_requires_219 = 42, typename std::enable_if<(_concept_requires_219==43)||(Constructible<F, F2&>()&&Constructible<S, S2&>()), int>::type=0>
            common_pair(std::pair<F2, S2>& that) noexcept(std::is_nothrow_constructible<F, F2&>::value&&std::is_nothrow_constructible<S, S2&>::value);
            
            template <typename F2, typename S2, int _concept_requires_226 = 42, typename std::enable_if<(_concept_requires_226==43)||(Constructible<F, F2 const&>()&&Constructible<S, S2 const&>()), int>::type=0>
            common_pair(std::pair<F2, S2>const& that) noexcept(std::is_nothrow_constructible<F, F2 const&>::value&&std::is_nothrow_constructible<S, S2 const&>::value);
            
            template <typename F2, typename S2, int _concept_requires_233 = 42, typename std::enable_if<(_concept_requires_233==43)||(Constructible<F, F2&&>()&&Constructible<S, S2&&>()), int>::type=0>
            common_pair(std::pair<F2, S2>&& that) noexcept(std::is_nothrow_constructible<F, F2&&>::value&&std::is_nothrow_constructible<S, S2&&>::value);
            
            template <typename F2, typename S2, int _concept_requires_242 = 42, typename std::enable_if<(_concept_requires_242==43)||(Constructible<F2, F&>()&&Constructible<S2, S&>()), int>::type=0>
            operator std::pair<F2, S2>() & noexcept(std::is_nothrow_constructible<F2, F&>::value&&std::is_nothrow_constructible<S2, S&>::value);
            
            template <typename F2, typename S2, int _concept_requires_250 = 42, typename std::enable_if<(_concept_requires_250==43)||(Constructible<F2, F const&>()&&Constructible<S2, S const&>()), int>::type=0>
            operator std::pair<F2, S2>() const & noexcept(std::is_nothrow_constructible<F2, F const&>::value&&std::is_nothrow_constructible<S2, S const&>::value);
            
            template <typename F2, typename S2, int _concept_requires_258 = 42, typename std::enable_if<(_concept_requires_258==43)||(Constructible<F2, F&&>()&&Constructible<S2, S&&>()), int>::type=0>
            operator std::pair<F2, S2>() && noexcept(std::is_nothrow_constructible<F2, F&&>::value&&std::is_nothrow_constructible<S2, S&&>::value);
            
            template <typename F2, typename S2, int _concept_requires_268 = 42, typename std::enable_if<(_concept_requires_268==43)||(Assignable<F&, F2&>()&&Assignable<S&, S2&>()), int>::type=0>
            common_pair& operator=(std::pair<F2, S2>& that) noexcept(std::is_nothrow_assignable<F&, F2&>::value&&std::is_nothrow_assignable<S&, S2&>::value);
            
            template <typename F2, typename S2, int _concept_requires_278 = 42, typename std::enable_if<(_concept_requires_278==43)||(Assignable<F&, F2 const&>()&&Assignable<S&, S2 const&>()), int>::type=0>
            common_pair& operator=(std::pair<F2, S2>const& that) noexcept(std::is_nothrow_assignable<F&, F2 const&>::value&&std::is_nothrow_assignable<S&, S2 const&>::value);
            
            template <typename F2, typename S2, int _concept_requires_288 = 42, typename std::enable_if<(_concept_requires_288==43)||(Assignable<F&, F2&&>()&&Assignable<S&, S2&&>()), int>::type=0>
            common_pair& operator=(std::pair<F2, S2>&& that) noexcept(std::is_nothrow_assignable<F&, F2&&>::value&&std::is_nothrow_assignable<S&, S2&&>::value);
        };
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_301 = 42, typename std::enable_if<(_concept_requires_301==43)||(EqualityComparable<F1, F2>()&&EqualityComparable<S1, S2>()), int>::type=0>
        bool operator==(common_pair<F1, S1>const& a, common_pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_307 = 42, typename std::enable_if<(_concept_requires_307==43)||(EqualityComparable<F1, F2>()&&EqualityComparable<S1, S2>()), int>::type=0>
        bool operator==(common_pair<F1, S1>const& a, std::pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_313 = 42, typename std::enable_if<(_concept_requires_313==43)||(EqualityComparable<F1, F2>()&&EqualityComparable<S1, S2>()), int>::type=0>
        bool operator==(std::pair<F1, S1>const& a, common_pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_319 = 42, typename std::enable_if<(_concept_requires_319==43)||(TotallyOrdered<F1, F2>()&&TotallyOrdered<S1, S2>()), int>::type=0>
        bool operator<(common_pair<F1, S1>const& a, common_pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_325 = 42, typename std::enable_if<(_concept_requires_325==43)||(TotallyOrdered<F1, F2>()&&TotallyOrdered<S1, S2>()), int>::type=0>
        bool operator<(std::pair<F1, S1>const& a, common_pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_331 = 42, typename std::enable_if<(_concept_requires_331==43)||(TotallyOrdered<F1, F2>()&&TotallyOrdered<S1, S2>()), int>::type=0>
        bool operator<(common_pair<F1, S1>const& a, std::pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_356 = 42, typename std::enable_if<(_concept_requires_356==43)||(EqualityComparable<F1, F2>()&&EqualityComparable<S1, S2>()), int>::type=0>
        bool operator!=(common_pair<F1, S1>const& a, common_pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_356 = 42, typename std::enable_if<(_concept_requires_356==43)||(EqualityComparable<F1, F2>()&&EqualityComparable<S1, S2>()), int>::type=0>
        bool operator!=(std::pair<F1, S1>const& a, common_pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_356 = 42, typename std::enable_if<(_concept_requires_356==43)||(EqualityComparable<F1, F2>()&&EqualityComparable<S1, S2>()), int>::type=0>
        bool operator!=(common_pair<F1, S1>const& a, std::pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_357 = 42, typename std::enable_if<(_concept_requires_357==43)||(TotallyOrdered<F1, F2>()&&TotallyOrdered<S1, S2>()), int>::type=0>
        bool operator<=(common_pair<F1, S1>const& a, common_pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_357 = 42, typename std::enable_if<(_concept_requires_357==43)||(TotallyOrdered<F1, F2>()&&TotallyOrdered<S1, S2>()), int>::type=0>
        bool operator<=(std::pair<F1, S1>const& a, common_pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_357 = 42, typename std::enable_if<(_concept_requires_357==43)||(TotallyOrdered<F1, F2>()&&TotallyOrdered<S1, S2>()), int>::type=0>
        bool operator<=(common_pair<F1, S1>const& a, std::pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_358 = 42, typename std::enable_if<(_concept_requires_358==43)||(TotallyOrdered<F1, F2>()&&TotallyOrdered<S1, S2>()), int>::type=0>
        bool operator>(common_pair<F1, S1>const& a, common_pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_358 = 42, typename std::enable_if<(_concept_requires_358==43)||(TotallyOrdered<F1, F2>()&&TotallyOrdered<S1, S2>()), int>::type=0>
        bool operator>(std::pair<F1, S1>const& a, common_pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_358 = 42, typename std::enable_if<(_concept_requires_358==43)||(TotallyOrdered<F1, F2>()&&TotallyOrdered<S1, S2>()), int>::type=0>
        bool operator>(common_pair<F1, S1>const& a, std::pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_359 = 42, typename std::enable_if<(_concept_requires_359==43)||(TotallyOrdered<F1, F2>()&&TotallyOrdered<S1, S2>()), int>::type=0>
        bool operator>=(common_pair<F1, S1>const& a, common_pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_359 = 42, typename std::enable_if<(_concept_requires_359==43)||(TotallyOrdered<F1, F2>()&&TotallyOrdered<S1, S2>()), int>::type=0>
        bool operator>=(std::pair<F1, S1>const& a, common_pair<F2, S2>const& b);
        
        template <typename F1, typename S1, typename F2, typename S2, int _concept_requires_359 = 42, typename std::enable_if<(_concept_requires_359==43)||(TotallyOrdered<F1, F2>()&&TotallyOrdered<S1, S2>()), int>::type=0>
        bool operator>=(common_pair<F1, S1>const& a, std::pair<F2, S2>const& b);
        
        struct make_common_pair_fn
        {
            template <typename First, typename Second, typename F = bind_element_t<First>, typename S = bind_element_t<Second>>
            common_pair<F, S> operator()(First&& f, Second&& s) const noexcept(std::is_nothrow_constructible<F, unwrap_reference_t<First>>::value&&std::is_nothrow_constructible<F, unwrap_reference_t<Second>>::value);
        };
        
        inline namespace 
        {
            constexpr auto& make_common_pair = static_const<make_common_pair_fn>::value;
        }
        
        namespace detail
        {
            template <typename, typename, typename, typename = void>
            struct common_type_tuple_like{};
            
            template <template <typename> typename T0, typename ... Ts, template <typename> typename T1, typename ... Us, typename TupleLike>
            struct common_type_tuple_like<T0<Ts...>, T1<Us...>, TupleLike, meta::if_c<sizeof...(Ts)==sizeof...(Us)>>
            : meta::lazy::let<meta::lazy::invoke<TupleLike, meta::lazy::_t<common_type<Ts, Us> >...> >
            {};
            
            template <typename T, typename U>
            using make_common_pair = meta::if_<meta::or_<std::is_reference<T>, std::is_reference<U>>, common_pair<T, U>, std::pair<T, U>>;
            
            template <typename ... Ts>
            using make_common_tuple = meta::if_<meta::any_of<meta::list<Ts...>, meta::quote<std::is_reference>>, common_tuple<Ts...>, std::tuple<Ts...>>;
        }
        
        namespace detail
        {
            template <typename, typename, typename, typename = void>
            struct common_ref_tuple_like{};
            
            template <template <typename> typename T0, typename ... Ts, template <typename> typename T1, typename ... Us, typename TupleLike>
            struct common_ref_tuple_like<T0<Ts...>, T1<Us...>, TupleLike, meta::if_c<sizeof...(Ts)==sizeof...(Us)>>
            : meta::lazy::let<meta::lazy::invoke<TupleLike, meta::lazy::_t<common_reference<Ts, Us> >...> >
            {};
        }
    }
}

namespace std{}

Variable ranges::v3::make_common_tuple

constexpr auto& make_common_tuple = static_const<make_common_tuple_fn>::value;

make_common_tuple_fn


Variable ranges::v3::make_common_pair

constexpr auto& make_common_pair = static_const<make_common_pair_fn>::value;

make_common_pair_fn