Horizon
Loading...
Searching...
No Matches
bind.hpp
Go to the documentation of this file.
1
3// Range v3 library
4//
5// Copyright Eric Niebler 2013-present
6//
7// Use, modification and distribution is subject to the
8// Boost Software License, Version 1.0. (See accompanying
9// file LICENSE_1_0.txt or copy at
10// http://www.boost.org/LICENSE_1_0.txt)
11//
12// Project home: https://github.com/ericniebler/range-v3
13//
14#ifndef RANGES_V3_FUNCTIONAL_BIND_HPP
15#define RANGES_V3_FUNCTIONAL_BIND_HPP
16
17#include <functional>
18#include <type_traits>
19
20#include <meta/meta.hpp>
21
22#include <concepts/concepts.hpp>
23
25
26#include <range/v3/utility/static_const.hpp>
27
28#include <range/v3/detail/prologue.hpp>
29
30namespace ranges
31{
34 template<typename T,
35 typename U = meta::if_<
36 std::is_lvalue_reference<T>,
37 std::reference_wrapper<meta::_t<std::remove_reference<T>>>, T &&>>
38 U bind_forward(meta::_t<std::remove_reference<T>> & t) noexcept
39 {
40 return static_cast<U>(t);
41 }
42
43 template<typename T>
44 T && bind_forward(meta::_t<std::remove_reference<T>> && t) noexcept
45 {
46 // This is to catch way sketchy stuff like: forward<int const &>(42)
47 static_assert(!std::is_lvalue_reference<T>::value, "You didn't just do that!");
48 return static_cast<T &&>(t);
49 }
50
51 template<typename T>
53 : meta::if_c<RANGES_IS_SAME(detail::decay_t<T>, T), meta::id<T>,
54 bind_element<detail::decay_t<T>>>
55 {};
56
57 template<typename T>
59 {
60 using type = T &;
61 };
62
63 template<typename T>
65 {
66 using type = typename reference_wrapper<T>::reference;
67 };
68
69 template<typename T>
70 using bind_element_t = meta::_t<bind_element<T>>;
71
72 template<typename Bind>
73 struct protector
74 {
75 private:
76 Bind bind_;
77
78 public:
79 protector() = default;
80 protector(Bind b)
81 : bind_(std::move(b))
82 {}
83 // clang-format off
84 template<typename...Ts>
85 auto CPP_auto_fun(operator())(Ts &&...ts)
86 (
87 return bind_(static_cast<Ts &&>(ts)...)
88 )
90 template<typename...Ts>
91 auto CPP_auto_fun(operator())(Ts &&...ts) (const)
92 (
93 return bind_(static_cast<Ts &&>(ts)...)
94 )
95 // clang-format on
96 };
97
99 {
100 template(typename F)(
101 requires std::is_bind_expression<uncvref_t<F>>::value) //
102 protector<uncvref_t<F>> operator()(F && f) const
103 {
104 return {static_cast<F &&>(f)};
105 }
107 template(typename F)(
108 requires (!std::is_bind_expression<uncvref_t<F>>::value)) //
109 F operator()(F && f) const
110 {
111 return static_cast<F &&>(f);
112 }
113 };
114
119 RANGES_INLINE_VARIABLE(protect_fn, protect)
121} // namespace ranges
122
123#include <range/v3/detail/epilogue.hpp>
124
125#endif
typename T::type _t
Type alias for T::type.
Definition meta.hpp:141
_t< detail::_if_< list< Args... > > > if_
Select one type or another depending on a compile-time Boolean.
Definition meta.hpp:1247
Tiny meta-programming library.
Definition bind.hpp:55
Definition bind.hpp:99
Definition bind.hpp:74
Definition reference_wrapper.hpp:76