Dune Core Modules (unstable)

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// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5#ifndef DUNE_COMMON_OVERLOADSET_HH
6#define DUNE_COMMON_OVERLOADSET_HH
7
8#include <utility>
9#include <type_traits>
11
12namespace Dune {
13
14namespace Impl {
15
16 template<typename... F>
17 class OverloadSet
18 : public F...
19 {
20
21 public:
22
23 template<typename... FF>
24 OverloadSet(FF&&... ff)
25 : F(std::forward<FF>(ff))...
26 {}
27
28 using F::operator()...;
29
30 };
31
32} // end namespace Impl
33
34
35
60template<class... F>
61auto overload(F&&... f)
62{
63 return Impl::OverloadSet<std::decay_t<F>...>(std::forward<F>(f)...);
64}
65
66
67
68namespace Impl {
69
70 template<class F0, class... F>
71 class OrderedOverloadSet: public OrderedOverloadSet<F...>, F0
72 {
73 using Base = OrderedOverloadSet<F...>;
74 public:
75
76 template<class FF0, class... FF>
77 OrderedOverloadSet(FF0&& f0, FF&&... ff) :
78 Base(std::forward<FF>(ff)...),
79 F0(std::forward<FF0>(f0))
80 {}
81
82 // Forward to operator() of F0 if it can be called with the given arguments.
83 template<class... Args,
84 std::enable_if_t<IsCallable<F0(Args&&...)>::value, int> = 0>
85 decltype(auto) operator()(Args&&... args)
86 {
87 return F0::operator()(std::forward<Args>(args)...);
88 }
89
90 // Forward to operator() of base class if F0 cannot be called with the given
91 // arguments. In this case the base class will successively try operator()
92 // of all F... .
93 template<class... Args,
94 std::enable_if_t<not IsCallable<F0(Args&&...)>::value, int> = 0>
95 decltype(auto) operator()(Args&&... args)
96 {
97 return Base::operator()(std::forward<Args>(args)...);
98 }
99
100 };
101
102 template<class F0>
103 class OrderedOverloadSet<F0>: public F0
104 {
105 public:
106
107 template<class FF0>
108 OrderedOverloadSet(FF0&& f0) :
109 F0(std::forward<FF0>(f0))
110 {}
111
112 // Forward to operator() of F0. If it cannot be called with
113 // the given arguments a static assertion will fail.
114 template<class... Args>
115 decltype(auto) operator()(Args&&... args)
116 {
117 static_assert(IsCallable<F0(Args&&...)>::value,
118 "No matching overload found in OrderedOverloadSet");
119 return F0::operator()(std::forward<Args>(args)...);
120 }
121 };
122
123} // end namespace Impl
124
125
126
149template<class... F>
150auto orderedOverload(F&&... f)
151{
152 return Impl::OrderedOverloadSet<std::decay_t<F>...>(std::forward<F>(f)...);
153}
154
155
156
157} // end namespace Dune
158
159#endif // DUNE_COMMON_OVERLOADSET_HH
auto orderedOverload(F &&... f)
Create an ordered overload set.
Definition: overloadset.hh:150
auto overload(F &&... f)
Create an overload set.
Definition: overloadset.hh:61
Dune namespace.
Definition: alignedallocator.hh:13
STL namespace.
Traits for type conversions and type information.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 21, 23:30, 2024)