Dune Core Modules (2.6.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
102template<class... F>
103auto overload(F&&... f)
104{
105 return Impl::OverloadSet<std::decay_t<F>...>(std::forward<F>(f)...);
106}
107
108
109
110namespace Impl {
111
112 template<class F0, class... F>
113 class OrderedOverloadSet: public OrderedOverloadSet<F...>, F0
114 {
115 using Base = OrderedOverloadSet<F...>;
116 public:
117
118 template<class FF0, class... FF>
119 OrderedOverloadSet(FF0&& f0, FF&&... ff) :
120 Base(std::forward<FF>(ff)...),
121 F0(std::forward<FF0>(f0))
122 {}
123
124 // Forward to operator() of F0 if it can be called with the given arguments.
125 template<class... Args,
126 std::enable_if_t<Std::is_callable<F0(Args&&...)>::value, int> = 0>
127 decltype(auto) operator()(Args&&... args)
128 {
129 return F0::operator()(std::forward<Args>(args)...);
130 }
131
132 // Forward to operator() of base class if F0 cannot be called with the given
133 // arguments. In this case the base class will successively try operator()
134 // of all F... .
135 template<class... Args,
136 std::enable_if_t< not Std::is_callable<F0(Args&&...)>::value, int> = 0>
137 decltype(auto) operator()(Args&&... args)
138 {
139 return Base::operator()(std::forward<Args>(args)...);
140 }
141
142 };
143
144 template<class F0>
145 class OrderedOverloadSet<F0>: public F0
146 {
147 public:
148
149 template<class FF0>
150 OrderedOverloadSet(FF0&& f0) :
151 F0(std::forward<FF0>(f0))
152 {}
153
154 // Forward to operator() of F0. If it cannot be called with
155 // the given arguments a static assertion will fail.
156 template<class... Args>
157 decltype(auto) operator()(Args&&... args)
158 {
159 static_assert(Std::is_callable<F0(Args&&...)>::value, "No matching overload found in OrderedOverloadSet");
160 return F0::operator()(std::forward<Args>(args)...);
161 }
162 };
163
164} // end namespace Impl
165
166
167
190template<class... F>
191auto orderedOverload(F&&... f)
192{
193 return Impl::OrderedOverloadSet<std::decay_t<F>...>(std::forward<F>(f)...);
194}
195
196
197
198} // end namespace Dune
199
200#endif // DUNE_COMMON_OVERLOADSET_HH
auto orderedOverload(F &&... f)
Create an ordered overload set.
Definition: overloadset.hh:191
auto overload(F &&... f)
Create an overload set.
Definition: overloadset.hh:103
Dune namespace.
Definition: alignedallocator.hh:10
STL namespace.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)