dune-common  2.9.0
overloadset.hh
Go to the documentation of this file.
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 (C) 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 
12 namespace Dune {
13 
14 namespace 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 
60 template<class... F>
61 auto overload(F&&... f)
62 {
63  return Impl::OverloadSet<std::decay_t<F>...>(std::forward<F>(f)...);
64 }
65 
66 
67 
68 namespace 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 
149 template<class... F>
150 auto 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
Traits for type conversions and type information.
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