File indexing completed on 2025-01-18 10:09:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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
0032
0033
0034 namespace ranges
0035 {
0036
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
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
0068 };
0069
0070 struct get_second
0071 {
0072
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
0081 };
0082
0083
0084
0085
0086 template<typename T>
0087 CPP_concept kv_pair_like_ =
0088 invocable<get_first const &, T> &&
0089 invocable<get_second const &, T>;
0090
0091 }
0092
0093
0094
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
0121
0122 RANGES_INLINE_VARIABLE(view_closure<keys_fn>, keys)
0123
0124
0125
0126 RANGES_INLINE_VARIABLE(view_closure<values_fn>, values)
0127 }
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 }
0143
0144 }
0145
0146 }
0147
0148 #include <range/v3/detail/epilogue.hpp>
0149
0150 #endif