Horizon
push_front.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_FRONT_HPP
15 #define RANGES_V3_ACTION_PUSH_FRONT_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_front_detail
38  {
40  template<typename Cont, typename T>
41  using push_front_t = decltype(static_cast<void>(
42  unwrap_reference(std::declval<Cont &>()).push_front(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<iterator_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_front_t<Cont, T> push_front(Cont && cont, T && t)
53  {
54  unwrap_reference(cont).push_front(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_front(Cont && cont, Rng && rng)
60  {
61  ranges::insert(cont, begin(cont), static_cast<Rng &&>(rng));
62  }
63 
65  // clang-format off
68  template<typename Rng, typename T>
69  CPP_requires(can_push_front_frag_,
70  requires(Rng && rng, T && t) //
71  (
72  push_front(rng, (T &&) t)
73  ));
76  template<typename Rng, typename T>
77  CPP_concept can_push_front_ =
78  CPP_requires_ref(adl_push_front_detail::can_push_front_frag_, Rng, T);
79  // clang-format on
81 
83  {
84  template<typename T>
85  constexpr auto operator()(T && val) const
86  {
87  return make_action_closure(
88  bind_back(push_front_fn{}, static_cast<T &&>(val)));
89  }
90 
91  template<typename T>
92  constexpr auto operator()(std::initializer_list<T> val) const
93  {
94  return make_action_closure(bind_back(push_front_fn{}, val));
95  }
96 
97  template(typename T)(
98  requires range<T &>)
99  constexpr auto operator()(T & t) const
100  {
101  return make_action_closure(
102  bind_back(push_front_fn{}, detail::reference_wrapper_<T>(t)));
103  }
104 
105  template(typename Rng, typename T)(
106  requires input_range<Rng> AND can_push_front_<Rng, T> AND
107  (range<T> || constructible_from<range_value_t<Rng>, T>)) //
108  Rng operator()(Rng && rng, T && t) const //
109  {
110  push_front(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_front_<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_front(rng, t);
121  return static_cast<Rng &&>(rng);
122  }
123 
125  template<typename Rng, typename T>
126  invoke_result_t<push_front_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_front_detail
136 
137  namespace actions
138  {
139  RANGES_INLINE_VARIABLE(adl_push_front_detail::push_front_fn, push_front)
140  } // namespace actions
141 
142  using actions::push_front;
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_front< quote< list >, Ts... >, L > push_front
Return a new meta::list by adding the element T to the front of L.
Definition: meta.hpp:2120
Tiny meta-programming library.
Definition: push_front.hpp:83