Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:09:57

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2013-present
0005 //
0006 //  Use, modification and distribution is subject to the
0007 //  Boost Software License, Version 1.0. (See accompanying
0008 //  file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 // Project home: https://github.com/ericniebler/range-v3
0012 //
0013 
0014 #ifndef RANGES_V3_VIEW_MAP_HPP
0015 #define RANGES_V3_VIEW_MAP_HPP
0016 
0017 #include <utility>
0018 
0019 #include <meta/meta.hpp>
0020 
0021 #include <concepts/concepts.hpp>
0022 
0023 #include <range/v3/range_fwd.hpp>
0024 
0025 #include <range/v3/utility/static_const.hpp>
0026 #include <range/v3/view/transform.hpp>
0027 #include <range/v3/view/view.hpp>
0028 
0029 #include <range/v3/detail/prologue.hpp>
0030 
0031 // TODO: Reuse subrange's pair_like concept here and have get_first and get_second
0032 // dispatch through get<>()
0033 
0034 namespace ranges
0035 {
0036     /// \cond
0037     namespace detail
0038     {
0039         template<typename T>
0040         constexpr T & get_first_second_helper(T & t, std::true_type) noexcept
0041         {
0042             return t;
0043         }
0044 
0045         template(typename T)(
0046             requires move_constructible<T>)
0047         constexpr T get_first_second_helper(T & t, std::false_type) //
0048             noexcept(std::is_nothrow_move_constructible<T>::value)
0049         {
0050             return std::move(t);
0051         }
0052 
0053         template<typename P, typename E>
0054         using get_first_second_tag = meta::bool_<std::is_lvalue_reference<P>::value ||
0055                                                  std::is_lvalue_reference<E>::value>;
0056 
0057         struct get_first
0058         {
0059             // clang-format off
0060             template<typename Pair>
0061             constexpr auto CPP_auto_fun(operator())(Pair &&p)(const)
0062             (
0063                 return get_first_second_helper(
0064                     p.first,
0065                     get_first_second_tag<Pair, decltype(p.first)>{})
0066             )
0067             // clang-format on
0068         };
0069 
0070         struct get_second
0071         {
0072             // clang-format off
0073             template<typename Pair>
0074             constexpr auto CPP_auto_fun(operator())(Pair &&p)(const)
0075             (
0076                 return get_first_second_helper(
0077                     p.second,
0078                     get_first_second_tag<Pair, decltype(p.second)>{})
0079             )
0080             // clang-format on
0081         };
0082 
0083         // clang-format off
0084         /// \concept kv_pair_like_
0085         /// \brief The \c kv_pair_like_ concept
0086         template<typename T>
0087         CPP_concept kv_pair_like_ =
0088             invocable<get_first const &, T> &&
0089             invocable<get_second const &, T>;
0090         // clang-format on
0091     } // namespace detail
0092     /// \endcond
0093 
0094     /// \addtogroup group-views
0095     /// @{
0096     namespace views
0097     {
0098         struct keys_fn
0099         {
0100             template(typename Rng)(
0101                 requires viewable_range<Rng> AND input_range<Rng> AND
0102                     detail::kv_pair_like_<range_reference_t<Rng>>)
0103             keys_range_view<all_t<Rng>> operator()(Rng && rng) const
0104             {
0105                 return {all(static_cast<Rng &&>(rng)), detail::get_first{}};
0106             }
0107         };
0108 
0109         struct values_fn
0110         {
0111             template(typename Rng)(
0112                 requires viewable_range<Rng> AND input_range<Rng> AND
0113                     detail::kv_pair_like_<range_reference_t<Rng>>)
0114             values_view<all_t<Rng>> operator()(Rng && rng) const
0115             {
0116                 return {all(static_cast<Rng &&>(rng)), detail::get_second{}};
0117             }
0118         };
0119 
0120         /// \relates keys_fn
0121         /// \ingroup group-views
0122         RANGES_INLINE_VARIABLE(view_closure<keys_fn>, keys)
0123 
0124         /// \relates values_fn
0125         /// \ingroup group-views
0126         RANGES_INLINE_VARIABLE(view_closure<values_fn>, values)
0127     } // namespace views
0128 
0129     template<typename Rng>
0130     RANGES_INLINE_VAR constexpr bool enable_borrowed_range<keys_range_view<Rng>> =
0131         enable_borrowed_range<Rng>;
0132     template<typename Rng>
0133     RANGES_INLINE_VAR constexpr bool enable_borrowed_range<values_view<Rng>> =
0134         enable_borrowed_range<Rng>;
0135 
0136     namespace cpp20
0137     {
0138         namespace views
0139         {
0140             using ranges::views::keys;
0141             using ranges::views::values;
0142         } // namespace views
0143         // TODO(@cjdb): provide implementation for elements_view
0144     } // namespace cpp20
0145     /// @}
0146 } // namespace ranges
0147 
0148 #include <range/v3/detail/epilogue.hpp>
0149 
0150 #endif