Horizon
push_back.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_ACTION_PUSH_BACK_HPP
15 #define RANGES_V3_ACTION_PUSH_BACK_HPP
16 
17 #include <utility>
18 
19 #include <meta/meta.hpp>
20 
21 #include <range/v3/range_fwd.hpp>
22 
25 #include <range/v3/detail/with_braced_init_args.hpp>
27 #include <range/v3/utility/static_const.hpp>
28 
29 #include <range/v3/detail/prologue.hpp>
30 
31 namespace ranges
32 {
35 
37  namespace adl_push_back_detail
38  {
40  template<typename Cont, typename T>
41  using push_back_t = decltype(static_cast<void>(
42  unwrap_reference(std::declval<Cont &>()).push_back(std::declval<T>())));
43 
44  template<typename Cont, typename Rng>
45  using insert_t = decltype(static_cast<void>(
46  ranges::insert(std::declval<Cont &>(), std::declval<sentinel_t<Cont>>(),
47  std::declval<Rng>())));
48 
49  template(typename Cont, typename T)(
50  requires lvalue_container_like<Cont> AND
51  (!range<T>) AND constructible_from<range_value_t<Cont>, T>)
52  push_back_t<Cont, T> push_back(Cont && cont, T && t)
53  {
54  unwrap_reference(cont).push_back(static_cast<T &&>(t));
55  }
56 
57  template(typename Cont, typename Rng)(
58  requires lvalue_container_like<Cont> AND range<Rng>)
59  insert_t<Cont, Rng> push_back(Cont && cont, Rng && rng)
60  {
61  ranges::insert(cont, end(cont), static_cast<Rng &&>(rng));
62  }
63 
65  // clang-format off
68  template<typename Rng, typename T>
69  CPP_requires(can_push_back_frag_,
70  requires(Rng && rng, T && t) //
71  (
72  push_back(rng, (T &&) t)
73  ));
76  template<typename Rng, typename T>
77  CPP_concept can_push_back_ =
78  CPP_requires_ref(adl_push_back_detail::can_push_back_frag_, Rng, T);
79  // clang-format on
81 
82  struct push_back_fn
83  {
84  template<typename T>
85  constexpr auto operator()(T && val) const
86  {
87  return make_action_closure(
88  bind_back(push_back_fn{}, static_cast<T &&>(val)));
89  }
90 
91  template(typename T)(
92  requires range<T &>)
93  constexpr auto operator()(T & t) const
94  {
95  return make_action_closure(
96  bind_back(push_back_fn{}, detail::reference_wrapper_<T>(t)));
97  }
98 
99  template<typename T>
100  constexpr auto operator()(std::initializer_list<T> val) const
101  {
102  return make_action_closure(bind_back(push_back_fn{}, val));
103  }
104 
105  template(typename Rng, typename T)(
106  requires input_range<Rng> AND can_push_back_<Rng, T> AND
107  (range<T> || constructible_from<range_value_t<Rng>, T>)) //
108  Rng operator()(Rng && rng, T && t) const //
109  {
110  push_back(rng, static_cast<T &&>(t));
111  return static_cast<Rng &&>(rng);
112  }
113 
114  template(typename Rng, typename T)(
115  requires input_range<Rng> AND
116  can_push_back_<Rng, std::initializer_list<T>> AND
117  constructible_from<range_value_t<Rng>, T const &>)
118  Rng operator()(Rng && rng, std::initializer_list<T> t) const //
119  {
120  push_back(rng, t);
121  return static_cast<Rng &&>(rng);
122  }
123 
125  template<typename Rng, typename T>
126  invoke_result_t<push_back_fn, Rng, T &> //
127  operator()(Rng && rng, detail::reference_wrapper_<T> r) const
128  {
129  return (*this)(static_cast<Rng &&>(rng), r.get());
130  }
132  };
134  } // namespace adl_push_back_detail
136 
137  namespace actions
138  {
139  RANGES_INLINE_VARIABLE(adl_push_back_detail::push_back_fn, push_back)
140  } // namespace actions
141 
142  using actions::push_back;
143 
145 } // namespace ranges
146 
147 #include <range/v3/detail/epilogue.hpp>
148 
149 #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
defer< bind_back, Fn, Ts... > bind_back
Definition: meta.hpp:994
apply< bind_back< quote< list >, Ts... >, L > push_back
Return a new meta::list by adding the element T to the back of L.
Definition: meta.hpp:2173
Tiny meta-programming library.
Definition: push_back.hpp:83