/// \file // Range v3 library // // Copyright Eric Niebler 2013-present // Copyright Casey Carter 2016 // // Use, modification and distribution is subject to the // Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Project home: https://github.com/ericniebler/range-v3 // #ifndef RANGES_V3_UTILITY_COMPRESSED_PAIR_HPP #define RANGES_V3_UTILITY_COMPRESSED_PAIR_HPP #include #include #include #include #include #include #include namespace ranges { /// \cond namespace compressed_tuple_detail { // tagging individual elements with the complete type list disambiguates // base classes when composing compressed_tuples recursively. template using storage = box, Ts...>>; template struct compressed_tuple_; template struct RANGES_EMPTY_BASES compressed_tuple_, meta::index_sequence> : storage... { static_assert(same_as, meta::make_index_sequence>, "What madness is this?!?"); compressed_tuple_() = default; template, int> = 0> constexpr compressed_tuple_(Args &&... args) noexcept( meta::strict_and, Args>...>::value) : storage{static_cast(args)}... {} template< typename... Us, meta::if_, int> = 0> constexpr operator std::tuple() const noexcept( meta::strict_and...>::value) { return std::tuple{get(*this)...}; } template, I>> friend constexpr T & get(compressed_tuple_ & tuple) noexcept { return static_cast &>(tuple).get(); } template, I>> friend constexpr T const & get(compressed_tuple_ const & tuple) noexcept { return static_cast const &>(tuple).get(); } template, I>> friend constexpr T && get(compressed_tuple_ && tuple) noexcept { return static_cast &&>(tuple).get(); } template, I>> friend constexpr T const && get(compressed_tuple_ const && tuple) noexcept { return static_cast const &&>(tuple).get(); } }; template using compressed_tuple RANGES_DEPRECATED( "ranges::compressed_tuple is deprecated.") = compressed_tuple_, meta::make_index_sequence>; } // namespace compressed_tuple_detail /// \endcond using compressed_tuple_detail::compressed_tuple; struct make_compressed_tuple_fn { // clang-format off template constexpr auto CPP_auto_fun(operator())(Args &&... args) (const) ( return compressed_tuple...>{static_cast(args)...} ) // clang-format on }; /// \ingroup group-utility /// \sa `make_compressed_tuple_fn` RANGES_INLINE_VARIABLE(make_compressed_tuple_fn, make_compressed_tuple) template struct RANGES_EMPTY_BASES compressed_pair : box> , box> { using first_type = First; using second_type = Second; compressed_pair() = default; CPP_template(typename U, typename V)( // requires constructible_from && constructible_from) // constexpr compressed_pair(U && u, V && v) noexcept(noexcept(First((U &&) u)) && noexcept(Second((V &&) v))) : box>{(U &&) u} , box>{(V &&) v} {} constexpr First & first() & { return this->box>::get(); } constexpr First const & first() const & { return this->box>::get(); } constexpr First && first() && { return static_cast(this->box>::get()); } constexpr Second & second() & { return this->box>::get(); } constexpr Second const & second() const & { return this->box>::get(); } constexpr Second && second() && { return static_cast(this->box>::get()); } CPP_template(typename F, typename S)( // requires convertible_to && convertible_to) // constexpr operator std::pair() const { return std::pair{first(), second()}; } }; struct make_compressed_pair_fn { // clang-format off template constexpr auto CPP_auto_fun(operator())(First &&f, Second &&s) (const) ( return compressed_pair, bind_element_t>{ static_cast(f), static_cast(s) } ) // clang-format on }; /// \ingroup group-utility /// \sa `make_compressed_pair_fn` RANGES_INLINE_VARIABLE(make_compressed_pair_fn, make_compressed_pair) } // namespace ranges RANGES_DIAGNOSTIC_PUSH RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS namespace std { template struct tuple_size<::ranges::compressed_tuple_detail::compressed_tuple_< ::meta::list, ::meta::index_sequence>> : integral_constant {}; template struct tuple_element, ::meta::index_sequence>> { using type = ::meta::at_c<::meta::list, I>; }; template struct tuple_size<::ranges::compressed_pair> : integral_constant {}; template struct tuple_element<0, ::ranges::compressed_pair> { using type = First; }; template struct tuple_element<1, ::ranges::compressed_pair> { using type = Second; }; } // namespace std RANGES_DIAGNOSTIC_POP #endif