Horizon
Loading...
Searching...
No Matches
push_front.hpp
Go to the documentation of this file.
1
2// 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
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
31namespace 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
The input_range concept.
The range concept.
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