Horizon
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 
24 #include <range/v3/range_fwd.hpp>
25 
26 #include <range/v3/utility/static_const.hpp>
27 
28 #include <range/v3/detail/prologue.hpp>
29 
30 namespace 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>
52  struct bind_element
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 
98  struct protect_fn
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 
121 } // namespace ranges
122 
123 #include <range/v3/detail/epilogue.hpp>
124 
125 #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
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.
detail::protect_< T > protect
For preventing the evaluation of a nested defered computation in a let or lambda expression.
Definition: meta.hpp:3615
Definition: bind.hpp:55
Definition: bind.hpp:99
Definition: bind.hpp:74
Definition: reference_wrapper.hpp:76