Horizon
Loading...
Searching...
No Matches
overload.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#ifndef RANGES_V3_FUNCTIONAL_OVERLOAD_HPP
14#define RANGES_V3_FUNCTIONAL_OVERLOAD_HPP
15
16#include <meta/meta.hpp>
17
18#include <concepts/concepts.hpp>
19
21
24#include <range/v3/utility/static_const.hpp>
25
26#include <range/v3/detail/prologue.hpp>
27
28namespace ranges
29{
33 namespace detail
34 {
35 struct _id
36 {
37 template<typename T>
38 using invoke = T;
39 };
40 struct _ref
41 {
42 template<typename T>
43 using invoke = T &;
44 };
45 struct _cref
46 {
47 template<typename T>
48 using invoke = T const &;
49 };
50 template<typename T>
51 struct _bind_front
52 {
53 template<typename... Args>
54 using invoke = invoke_result_t<T, Args...>;
55 };
56 } // namespace detail
58
59 template<typename... Ts>
60 struct overloaded;
61
62 template<>
63 struct overloaded<>
64 {
65 private:
66 template<typename...>
67 friend struct overloaded;
68 template<typename, typename...>
69 using _result_t = void;
70 };
71
72 template<typename First, typename... Rest>
73 struct overloaded<First, Rest...>
74 {
75 private:
76 template<typename...>
77 friend struct overloaded;
78
79 RANGES_NO_UNIQUE_ADDRESS
80 First first_;
81 RANGES_NO_UNIQUE_ADDRESS
82 overloaded<Rest...> second_;
83
84 template<typename Qual>
85 using _result_first = detail::_bind_front<meta::invoke<Qual, First>>;
86 template<typename Qual>
87 struct _result_second
88 {
89 template<typename... Args>
90 using invoke = typename overloaded<Rest...>
91 ::template _result_t<Qual, Args...>;
92 };
93
94 template<typename Qual, typename... Args>
95 using _result_t =
98 (bool) invocable<meta::invoke<Qual, First>, Args...>,
99 _result_first<Qual>,
100 _result_second<Qual>>,
101 Args...>;
102
103 public:
104 overloaded() = default;
105 constexpr overloaded(First first, Rest... rest)
106 : first_(static_cast<First &&>(first))
107 , second_{static_cast<Rest &&>(rest)...}
108 {}
109
110 template(typename... Args)(
112 constexpr _result_t<detail::_id, Args...> operator()(Args &&... args) &&
113 {
114 return invoke((First &&) first_, (Args &&) args...);
115 }
116 template(typename... Args)(
117 requires (!invocable<First, Args...>) AND
118 invocable<overloaded<Rest...>, Args...>)
119 constexpr _result_t<detail::_id, Args...> operator()(Args &&... args) &&
120 {
121 return invoke((overloaded<Rest...> &&) second_, (Args &&) args...);
122 }
123
124 template(typename... Args)(
126 constexpr _result_t<detail::_ref, Args...> operator()(Args &&... args) &
127 {
128 return invoke(first_, (Args &&) args...);
129 }
130 template(typename... Args)(
131 requires (!invocable<First &, Args...>) AND
132 invocable<overloaded<Rest...> &, Args...>)
133 constexpr _result_t<detail::_ref, Args...> operator()(Args &&... args) &
134 {
135 return invoke(second_, (Args &&) args...);
136 }
137
138 template(typename... Args)(
140 constexpr _result_t<detail::_cref, Args...> operator()(Args &&... args) const &
141 {
142 return invoke(first_, (Args &&) args...);
143 }
144 template(typename... Args)(
146 invocable<overloaded<Rest...> const &, Args...>)
147 constexpr _result_t<detail::_cref, Args...> operator()(Args &&... args) const &
148 {
149 return invoke(second_, (Args &&) args...);
150 }
151 };
152
154 {
155 template<typename Fn>
156 constexpr Fn operator()(Fn fn) const
157 {
158 return fn;
159 }
160 template<typename... Fns>
161 constexpr overloaded<Fns...> operator()(Fns... fns) const
162 {
163 return overloaded<Fns...>{static_cast<Fns &&>(fns)...};
164 }
165 };
166
169 RANGES_INLINE_VARIABLE(overload_fn, overload)
171} // namespace ranges
172
173#include <range/v3/detail/epilogue.hpp>
174
175#endif
The invocable concept.
typename Fn::template invoke< Args... > invoke
Evaluate the invocable Fn with the arguments Args.
Definition meta.hpp:541
typename detail::_cond< If >::template invoke< Then, Else > conditional_t
Select one type or another depending on a compile-time Boolean.
Definition meta.hpp:1148
Tiny meta-programming library.
Definition overload.hpp:154
Definition overload.hpp:60