Dune Core Modules (2.5.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 // This overload set derives from
18 // all passed functions. Since we
19 // cannot do argument pack expansion
20 // on using statements this is done recursively.
21 template<class F0, class... F>
22 class OverloadSet: public OverloadSet<F...>, F0
23 {
24 using Base = OverloadSet<F...>;
25 public:
26
27 template<class FF0, class... FF>
28 OverloadSet(FF0&& f0, FF&&... ff) :
29 Base(std::forward<FF>(ff)...),
30 F0(std::forward<FF0>(f0))
31 {}
32
33 // pull in operator() of F0 and of all F... via the base class
34 using F0::operator();
35 using Base::operator();
36 };
37
38 template<class F0>
39 class OverloadSet<F0>: public F0
40 {
41 public:
42
43 template<class FF0>
44 OverloadSet(FF0&& f0) :
45 F0(std::forward<FF0>(f0))
46 {}
47
48 // pull in operator() of F0
49 using F0::operator();
50 };
51
52} // end namespace Impl
53
54
55
78template<class... F>
79auto overload(F&&... f)
80{
81 return Impl::OverloadSet<std::decay_t<F>...>(std::forward<F>(f)...);
82}
83
84
85
86namespace Impl {
87
88 template<class F0, class... F>
89 class OrderedOverloadSet: public OrderedOverloadSet<F...>, F0
90 {
91 using Base = OrderedOverloadSet<F...>;
92 public:
93
94 template<class FF0, class... FF>
95 OrderedOverloadSet(FF0&& f0, FF&&... ff) :
96 Base(std::forward<FF>(ff)...),
97 F0(std::forward<FF0>(f0))
98 {}
99
100 // Forward to operator() of F0 if it can be called with the given arguments.
101 template<class... Args,
102 std::enable_if_t<Std::is_callable<F0(Args&&...)>::value, int> = 0>
103 decltype(auto) operator()(Args&&... args)
104 {
105 return F0::operator()(std::forward<Args>(args)...);
106 }
107
108 // Forward to operator() of base class if F0 cannot be called with the given
109 // arguments. In this case the base class will successively try operator()
110 // of all F... .
111 template<class... Args,
112 std::enable_if_t< not Std::is_callable<F0(Args&&...)>::value, int> = 0>
113 decltype(auto) operator()(Args&&... args)
114 {
115 return Base::operator()(std::forward<Args>(args)...);
116 }
117
118 };
119
120 template<class F0>
121 class OrderedOverloadSet<F0>: public F0
122 {
123 public:
124
125 template<class FF0>
126 OrderedOverloadSet(FF0&& f0) :
127 F0(std::forward<FF0>(f0))
128 {}
129
130 // Forward to operator() of F0. If it cannot be called with
131 // the given arguments a static assertion will fail.
132 template<class... Args>
133 decltype(auto) operator()(Args&&... args)
134 {
135 static_assert(Std::is_callable<F0(Args&&...)>::value, "No matching overload found in OrderedOverloadSet");
136 return F0::operator()(std::forward<Args>(args)...);
137 }
138 };
139
140} // end namespace Impl
141
142
143
164template<class... F>
165auto orderedOverload(F&&... f)
166{
167 return Impl::OrderedOverloadSet<std::decay_t<F>...>(std::forward<F>(f)...);
168}
169
170
171
172} // end namespace Dune
173
174#endif // DUNE_COMMON_OVERLOADSET_HH
Dune namespace.
Definition: alignment.hh:11
auto orderedOverload(F &&... f)
Create an ordered overload set.
Definition: overloadset.hh:165
auto overload(F &&... f)
Create an overload set.
Definition: overloadset.hh:79
STL namespace.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 23, 23:29, 2024)