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