Dune Core Modules (2.7.0)

overloadset.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_COMMON_OVERLOADSET_HH
4#define DUNE_COMMON_OVERLOADSET_HH
5
6#include <utility>
7#include <type_traits>
8
9#include <dune/common/std/type_traits.hh>
10
11
12
13namespace Dune {
14
15namespace Impl {
16
17#if __cpp_variadic_using >= 201611
18
19 template<typename... F>
20 class OverloadSet
21 : public F...
22 {
23
24 public:
25
26 template<typename... FF>
27 OverloadSet(FF&&... ff)
28 : F(std::forward<FF>(ff))...
29 {}
30
31 using F::operator()...;
32
33 };
34
35#else // __cpp_variadic_using >= 201611
36
37 // This overload set derives from
38 // all passed functions. Since we
39 // cannot do argument pack expansion
40 // on using statements this is done recursively.
41 template<class F0, class... F>
42 class OverloadSet: public OverloadSet<F...>, F0
43 {
44 using Base = OverloadSet<F...>;
45 public:
46
47 template<class FF0, class... FF>
48 OverloadSet(FF0&& f0, FF&&... ff) :
49 Base(std::forward<FF>(ff)...),
50 F0(std::forward<FF0>(f0))
51 {}
52
53 // pull in operator() of F0 and of all F... via the base class
54 using F0::operator();
55 using Base::operator();
56 };
57
58 template<class F0>
59 class OverloadSet<F0>: public F0
60 {
61 public:
62
63 template<class FF0>
64 OverloadSet(FF0&& f0) :
65 F0(std::forward<FF0>(f0))
66 {}
67
68 // pull in operator() of F0
69 using F0::operator();
70 };
71
72#endif // __cpp_variadic_using >= 201611
73
74} // end namespace Impl
75
76
77
108template<class... F>
109auto overload(F&&... f)
110{
111 return Impl::OverloadSet<std::decay_t<F>...>(std::forward<F>(f)...);
112}
113
114
115
116namespace Impl {
117
118 template<class F0, class... F>
119 class OrderedOverloadSet: public OrderedOverloadSet<F...>, F0
120 {
121 using Base = OrderedOverloadSet<F...>;
122 public:
123
124 template<class FF0, class... FF>
125 OrderedOverloadSet(FF0&& f0, FF&&... ff) :
126 Base(std::forward<FF>(ff)...),
127 F0(std::forward<FF0>(f0))
128 {}
129
130 // Forward to operator() of F0 if it can be called with the given arguments.
131 template<class... Args,
132 std::enable_if_t<Std::is_callable<F0(Args&&...)>::value, int> = 0>
133 decltype(auto) operator()(Args&&... args)
134 {
135 return F0::operator()(std::forward<Args>(args)...);
136 }
137
138 // Forward to operator() of base class if F0 cannot be called with the given
139 // arguments. In this case the base class will successively try operator()
140 // of all F... .
141 template<class... Args,
142 std::enable_if_t< not Std::is_callable<F0(Args&&...)>::value, int> = 0>
143 decltype(auto) operator()(Args&&... args)
144 {
145 return Base::operator()(std::forward<Args>(args)...);
146 }
147
148 };
149
150 template<class F0>
151 class OrderedOverloadSet<F0>: public F0
152 {
153 public:
154
155 template<class FF0>
156 OrderedOverloadSet(FF0&& f0) :
157 F0(std::forward<FF0>(f0))
158 {}
159
160 // Forward to operator() of F0. If it cannot be called with
161 // the given arguments a static assertion will fail.
162 template<class... Args>
163 decltype(auto) operator()(Args&&... args)
164 {
165 static_assert(Std::is_callable<F0(Args&&...)>::value, "No matching overload found in OrderedOverloadSet");
166 return F0::operator()(std::forward<Args>(args)...);
167 }
168 };
169
170} // end namespace Impl
171
172
173
202template<class... F>
203auto orderedOverload(F&&... f)
204{
205 return Impl::OrderedOverloadSet<std::decay_t<F>...>(std::forward<F>(f)...);
206}
207
208
209
210} // end namespace Dune
211
212#endif // DUNE_COMMON_OVERLOADSET_HH
auto orderedOverload(F &&... f)
Create an ordered overload set.
Definition: overloadset.hh:203
auto overload(F &&... f)
Create an overload set.
Definition: overloadset.hh:109
Dune namespace.
Definition: alignedallocator.hh:14
STL namespace.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)