Horizon
map.hpp
Go to the documentation of this file.
1 // Range v3 library
3 //
4 // Copyright Eric Niebler 2013-present
5 //
6 // Use, modification and distribution is subject to the
7 // Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 //
11 // Project home: https://github.com/ericniebler/range-v3
12 //
13 
14 #ifndef RANGES_V3_VIEW_MAP_HPP
15 #define RANGES_V3_VIEW_MAP_HPP
16 
17 #include <utility>
18 
19 #include <meta/meta.hpp>
20 
21 #include <concepts/concepts.hpp>
22 
23 #include <range/v3/range_fwd.hpp>
24 
25 #include <range/v3/utility/static_const.hpp>
27 #include <range/v3/view/view.hpp>
28 
29 #include <range/v3/detail/prologue.hpp>
30 
31 // TODO: Reuse subrange's pair_like concept here and have get_first and get_second
32 // dispatch through get<>()
33 
34 namespace ranges
35 {
37  namespace detail
38  {
39  template<typename T>
40  constexpr T & get_first_second_helper(T & t, std::true_type) noexcept
41  {
42  return t;
43  }
44 
45  template(typename T)(
46  requires move_constructible<T>)
47  constexpr T get_first_second_helper(T & t, std::false_type) //
48  noexcept(std::is_nothrow_move_constructible<T>::value)
49  {
50  return std::move(t);
51  }
52 
53  template<typename P, typename E>
54  using get_first_second_tag = meta::bool_<std::is_lvalue_reference<P>::value ||
55  std::is_lvalue_reference<E>::value>;
56 
57  struct get_first
58  {
59  // clang-format off
60  template<typename Pair>
61  constexpr auto CPP_auto_fun(operator())(Pair &&p)(const)
62  (
63  return get_first_second_helper(
64  p.first,
65  get_first_second_tag<Pair, decltype(p.first)>{})
66  )
67  // clang-format on
68  };
69 
70  struct get_second
71  {
72  // clang-format off
73  template<typename Pair>
74  constexpr auto CPP_auto_fun(operator())(Pair &&p)(const)
75  (
76  return get_first_second_helper(
77  p.second,
78  get_first_second_tag<Pair, decltype(p.second)>{})
79  )
80  // clang-format on
81  };
82 
83  // clang-format off
86  template<typename T>
87  CPP_concept kv_pair_like_ =
88  invocable<get_first const &, T> &&
89  invocable<get_second const &, T>;
90  // clang-format on
91  } // namespace detail
93 
96  namespace views
97  {
98  struct keys_fn
99  {
100  template(typename Rng)(
101  requires viewable_range<Rng> AND input_range<Rng> AND
102  detail::kv_pair_like_<range_reference_t<Rng>>)
103  keys_range_view<all_t<Rng>> operator()(Rng && rng) const
104  {
105  return {all(static_cast<Rng &&>(rng)), detail::get_first{}};
106  }
107  };
108 
109  struct values_fn
110  {
111  template(typename Rng)(
112  requires viewable_range<Rng> AND input_range<Rng> AND
113  detail::kv_pair_like_<range_reference_t<Rng>>)
114  values_view<all_t<Rng>> operator()(Rng && rng) const
115  {
116  return {all(static_cast<Rng &&>(rng)), detail::get_second{}};
117  }
118  };
119 
123 
124 
127  } // namespace views
128 
129  template<typename Rng>
130  RANGES_INLINE_VAR constexpr bool enable_borrowed_range<keys_range_view<Rng>> =
131  enable_borrowed_range<Rng>;
132  template<typename Rng>
133  RANGES_INLINE_VAR constexpr bool enable_borrowed_range<values_view<Rng>> =
134  enable_borrowed_range<Rng>;
135 
136  namespace cpp20
137  {
138  namespace views
139  {
140  using ranges::views::keys;
141  using ranges::views::values;
142  } // namespace views
143  // TODO(@cjdb): provide implementation for elements_view
144  } // namespace cpp20
146 } // namespace ranges
147 
148 #include <range/v3/detail/epilogue.hpp>
149 
150 #endif
RANGES_INLINE_VARIABLE(detail::to_container_fn< detail::from_range< std::vector >>, to_vector) template< template< typename... > class ContT > auto to(RANGES_HIDDEN_DETAIL(detail
For initializing a container of the specified type with the elements of an Range.
Definition: conversion.hpp:399
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition: meta.hpp:168
Tiny meta-programming library.
Definition: transform.hpp:201
Definition: map.hpp:99
Definition: map.hpp:110
Definition: view.hpp:178