00001
00002
00003 #ifndef DUNE_COMMON_OVERLOADSET_HH
00004 #define DUNE_COMMON_OVERLOADSET_HH
00005
00006 #include <utility>
00007 #include <type_traits>
00008
00009 #include <dune/common/std/type_traits.hh>
00010
00011
00012
00013 namespace Dune {
00014
00015 namespace Impl {
00016
00017
00018
00019
00020
00021 template<class F0, class... F>
00022 class OverloadSet: public OverloadSet<F...>, F0
00023 {
00024 using Base = OverloadSet<F...>;
00025 public:
00026
00027 template<class FF0, class... FF>
00028 OverloadSet(FF0&& f0, FF&&... ff) :
00029 Base(std::forward<FF>(ff)...),
00030 F0(std::forward<FF0>(f0))
00031 {}
00032
00033
00034 using F0::operator();
00035 using Base::operator();
00036 };
00037
00038 template<class F0>
00039 class OverloadSet<F0>: public F0
00040 {
00041 public:
00042
00043 template<class FF0>
00044 OverloadSet(FF0&& f0) :
00045 F0(std::forward<FF0>(f0))
00046 {}
00047
00048
00049 using F0::operator();
00050 };
00051
00052 }
00053
00054
00055
00078 template<class... F>
00079 auto overload(F&&... f)
00080 {
00081 return Impl::OverloadSet<std::decay_t<F>...>(std::forward<F>(f)...);
00082 }
00083
00084
00085
00086 namespace Impl {
00087
00088 template<class F0, class... F>
00089 class OrderedOverloadSet: public OrderedOverloadSet<F...>, F0
00090 {
00091 using Base = OrderedOverloadSet<F...>;
00092 public:
00093
00094 template<class FF0, class... FF>
00095 OrderedOverloadSet(FF0&& f0, FF&&... ff) :
00096 Base(std::forward<FF>(ff)...),
00097 F0(std::forward<FF0>(f0))
00098 {}
00099
00100
00101 template<class... Args,
00102 std::enable_if_t<Std::is_callable<F0(Args&&...)>::value, int> = 0>
00103 decltype(auto) operator()(Args&&... args)
00104 {
00105 return F0::operator()(std::forward<Args>(args)...);
00106 }
00107
00108
00109
00110
00111 template<class... Args,
00112 std::enable_if_t< not Std::is_callable<F0(Args&&...)>::value, int> = 0>
00113 decltype(auto) operator()(Args&&... args)
00114 {
00115 return Base::operator()(std::forward<Args>(args)...);
00116 }
00117
00118 };
00119
00120 template<class F0>
00121 class OrderedOverloadSet<F0>: public F0
00122 {
00123 public:
00124
00125 template<class FF0>
00126 OrderedOverloadSet(FF0&& f0) :
00127 F0(std::forward<FF0>(f0))
00128 {}
00129
00130
00131
00132 template<class... Args>
00133 decltype(auto) operator()(Args&&... args)
00134 {
00135 static_assert(Std::is_callable<F0(Args&&...)>::value, "No matching overload found in OrderedOverloadSet");
00136 return F0::operator()(std::forward<Args>(args)...);
00137 }
00138 };
00139
00140 }
00141
00142
00143
00164 template<class... F>
00165 auto orderedOverload(F&&... f)
00166 {
00167 return Impl::OrderedOverloadSet<std::decay_t<F>...>(std::forward<F>(f)...);
00168 }
00169
00170
00171
00172 }
00173
00174 #endif // DUNE_COMMON_OVERLOADSET_HH