Header file range/v3/utility/compressed_pair.hpp

#include <meta/meta.hpp>

#include <range/v3/range_fwd.hpp>

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

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

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

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

namespace ranges
{
    inline namespace v3
    {
        namespace compressed_tuple_detail
        {
            template <typename T, std::size_t I, typename ... Ts>
            using storage = box<T, meta::list<meta::size_t<I>, Ts...>>;
            
            template <typename ... Ts, std::size_t ... Is>
            struct compressed_tuple_<meta::list<Ts...>, meta::index_sequence<Is...>>
            : storage<Ts, Is, Ts...>
            {
                compressed_tuple_() = default;
                
                template <typename ... Args, meta::if_<meta::strict_and<std::is_constructible<Ts, Args>>, int> ... = 0>
                constexpr compressed_tuple_(Args&&... args);
                
                template <typename ... Us, meta::if_<meta::strict_and<std::is_constructible<Us, Ts const&>>, int> ... = 0>
                constexpr operator std::tuple<Us...>() const;
            };
            
            template <typename ... Ts>
            using compressed_tuple = compressed_tuple_<meta::list<Ts...>, meta::make_index_sequence<sizeof...(Ts)>>;
            
            template <std::size_t I, typename ... Ts, std::size_t ... Is, typename T = meta::at_c<meta::list<Ts...>, I>>
            constexpr T& get(compressed_tuple_<meta::list<Ts...>, meta::index_sequence<Is...>>& tuple) noexcept;
            
            template <std::size_t I, typename ... Ts, std::size_t ... Is, typename T = meta::at_c<meta::list<Ts...>, I>>
            constexpr T const& get(compressed_tuple_<meta::list<Ts...>, meta::index_sequence<Is...>>const& tuple) noexcept;
            
            template <std::size_t I, typename ... Ts, std::size_t ... Is, typename T = meta::at_c<meta::list<Ts...>, I>>
            constexpr T&& get(compressed_tuple_<meta::list<Ts...>, meta::index_sequence<Is...>>&& tuple) noexcept;
        }
        
        using compressed_tuple_detail::compressed_tuple;
        
        struct make_compressed_tuple_fn
        {
            template <typename ... Args>
            constexpr compressed_tuple<bind_element_t<Args>...> operator()(Args&&... args) const;
        };
        
        inline namespace 
        {
            constexpr auto& make_compressed_tuple = static_const<make_compressed_tuple_fn>::value;
        }
        
        template <typename ... Ts>
        using tagged_compressed_tuple = tagged<compressed_tuple<detail::tag_elem<Ts>...>, detail::tag_spec<Ts>...>;
        
        namespace tag
        {
            struct first
            {
                template <typename Untagged, std::size_t I, typename Next>
                class getter
                : public Next
                {
                protected:
                    ~getter() = default;
                    
                public:
                    getter() = default;
                    
                    getter(getter&&) = default;
                    
                    getter(getter const&) = default;
                    
                    using Next::Next;
                    
                    template <int _concept_requires_106 = 42, typename std::enable_if<(_concept_requires_106==43)||(MoveConstructible<Untagged>()), int>::type=0>
                    constexpr getter(Untagged&& that) noexcept(std::is_nothrow_move_constructible<Untagged>::value);
                    
                    template <int _concept_requires_106 = 42, typename std::enable_if<(_concept_requires_106==43)||(CopyConstructible<Untagged>()), int>::type=0>
                    constexpr getter(Untagged const& that) noexcept(std::is_nothrow_copy_constructible<Untagged>::value);
                    
                    getter& operator=(getter&&) = default;
                    
                    getter& operator=(getter const&) = default;
                    
                    constexpr meta::_t<std::tuple_element<I, Untagged>>& first() & noexcept(noexcept(detail::adl_get<I>(std::declval<Untagged&>())));
                    
                    constexpr meta::_t<std::tuple_element<I, Untagged>>&& first() && noexcept(noexcept(detail::adl_get<I>(std::declval<Untagged>())));
                    
                    constexpr meta::_t<std::tuple_element<I, Untagged>>const& first() const & noexcept(noexcept(detail::adl_get<I>(std::declval<Untagged const&>())));
                };
            };
        }
        
        namespace tag
        {
            struct second
            {
                template <typename Untagged, std::size_t I, typename Next>
                class getter
                : public Next
                {
                protected:
                    ~getter() = default;
                    
                public:
                    getter() = default;
                    
                    getter(getter&&) = default;
                    
                    getter(getter const&) = default;
                    
                    using Next::Next;
                    
                    template <int _concept_requires_107 = 42, typename std::enable_if<(_concept_requires_107==43)||(MoveConstructible<Untagged>()), int>::type=0>
                    constexpr getter(Untagged&& that) noexcept(std::is_nothrow_move_constructible<Untagged>::value);
                    
                    template <int _concept_requires_107 = 42, typename std::enable_if<(_concept_requires_107==43)||(CopyConstructible<Untagged>()), int>::type=0>
                    constexpr getter(Untagged const& that) noexcept(std::is_nothrow_copy_constructible<Untagged>::value);
                    
                    getter& operator=(getter&&) = default;
                    
                    getter& operator=(getter const&) = default;
                    
                    constexpr meta::_t<std::tuple_element<I, Untagged>>& second() & noexcept(noexcept(detail::adl_get<I>(std::declval<Untagged&>())));
                    
                    constexpr meta::_t<std::tuple_element<I, Untagged>>&& second() && noexcept(noexcept(detail::adl_get<I>(std::declval<Untagged>())));
                    
                    constexpr meta::_t<std::tuple_element<I, Untagged>>const& second() const & noexcept(noexcept(detail::adl_get<I>(std::declval<Untagged const&>())));
                };
            };
        }
        
        template <typename First, typename Second>
        struct compressed_pair
        : tagged_compressed_tuple<tag::first (First), tag::second (Second)>
        {
            using base_t = tagged_compressed_tuple<tag::first(First), tag::second(Second)>;
            
            using first_type = First;
            
            using second_type = Second;
            
            using base_t::first;
            
            using base_t::second;
            
            compressed_pair() = default;
            
            using base_t::base_t;
            
            template <typename F, typename S, meta::if_<meta::strict_and<std::is_constructible<F, First const&>, std::is_constructible<S, Second const&>>, int>=0>
            constexpr operator std::pair<F, S>() const;
        };
        
        struct make_compressed_pair_fn
        {
            template <typename First, typename Second>
            constexpr compressed_pair<bind_element_t<First>, bind_element_t<Second>> operator()(First&& f, Second&& s) const;
        };
        
        inline namespace 
        {
            constexpr auto& make_compressed_pair = static_const<make_compressed_pair_fn>::value;
        }
    }
}

namespace std{}

Variable ranges::v3::make_compressed_tuple

constexpr auto& make_compressed_tuple = static_const<make_compressed_tuple_fn>::value;

make_compressed_tuple_fn


Variable ranges::v3::make_compressed_pair

constexpr auto& make_compressed_pair = static_const<make_compressed_pair_fn>::value;

make_compressed_pair_fn