00001
00002
00003 #ifndef DUNE_COMMON_CONCEPT_HH
00004 #define DUNE_COMMON_CONCEPT_HH
00005
00006 #include <type_traits>
00007 #include <utility>
00008 #include <tuple>
00009
00010 #include <dune/common/typeutilities.hh>
00011 #include <dune/common/typelist.hh>
00012 #include <dune/common/tupleutility.hh>
00013 #include <dune/common/std/type_traits.hh>
00014
00015
00016
00017 namespace Dune {
00018
00019
00020
00028 namespace Concept {
00029
00030
00031
00044 template<class... BaseConcepts>
00045 struct Refines
00046 {
00047 typedef TypeList<BaseConcepts...> BaseConceptList;
00048 };
00049
00050
00051
00052 namespace Imp {
00053
00054
00055
00056
00057
00058
00059
00060 template<class C, class... T>
00061 constexpr bool models();
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 template<class C, class... T,
00078 decltype(std::declval<C>().require(std::declval<T>()...), 0) =0>
00079 constexpr std::true_type matchesRequirement(PriorityTag<1>)
00080 { return {}; }
00081
00082
00083
00084
00085 template<class C, class... T>
00086 constexpr std::false_type matchesRequirement(PriorityTag<0>)
00087 { return {}; }
00088
00089
00090
00091
00092 template<class...T>
00093 constexpr bool modelsConceptList(TypeList<>)
00094 { return true; }
00095
00096
00097
00098
00099 template<class...T, class C0, class... CC>
00100 constexpr bool modelsConceptList(TypeList<C0, CC...>)
00101 { return Imp::models<C0, T...>() and modelsConceptList<T...>(TypeList<CC...>()); }
00102
00103
00104
00105
00106
00107 template<class C, class... T>
00108 constexpr bool modelsConcept(PriorityTag<0>)
00109 { return matchesRequirement<C, T...>(PriorityTag<42>()); }
00110
00111
00112
00113
00114
00115
00116
00117 template<class C, class... T,
00118 decltype(typename C::BaseConceptList(), 0) = 0>
00119 constexpr bool modelsConcept(PriorityTag<1>)
00120 { return matchesRequirement<C, T...>(PriorityTag<42>()) and modelsConceptList<T...>(typename C::BaseConceptList()); }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 template<class C, class... T>
00132 constexpr bool models()
00133 {
00134 return modelsConcept<C, T...>(PriorityTag<42>());
00135 }
00136
00137 }
00138
00139 }
00140
00141
00142
00171 template<class C, class... T>
00172 constexpr auto models()
00173 {
00174 return Std::bool_constant<Concept::Imp::models<C, T...>()>();
00175 }
00176
00177
00178
00179 namespace Concept {
00180
00181 namespace Imp {
00182
00183
00184
00185
00186
00187
00188 template<class C, class Tuple>
00189 struct TupleEntriesModelHelper
00190 {
00191 template<class Accumulated, class T>
00192 struct AccumulateFunctor
00193 {
00194 using type = typename std::integral_constant<bool, Accumulated::value and models<C, T>()>;
00195 };
00196 using Result = typename ReduceTuple<AccumulateFunctor, Tuple, std::true_type>::type;
00197 };
00198
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208 template<class C, class Tuple>
00209 constexpr auto tupleEntriesModel()
00210 -> typename Imp::TupleEntriesModelHelper<C, Tuple>::Result
00211 {
00212 return {};
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 template<bool b, typename std::enable_if<b, int>::type = 0>
00224 constexpr bool requireTrue()
00225 {
00226 return true;
00227 }
00228
00229
00230 template<class C, class... T, typename std::enable_if<models<C, T...>(), int>::type = 0>
00231 constexpr bool requireConcept()
00232 {
00233 return true;
00234 }
00235
00236
00237
00238 template<class C, class... T, typename std::enable_if<models<C, T...>(), int>::type = 0>
00239 constexpr bool requireConcept(T&&... t)
00240 {
00241 return true;
00242 }
00243
00244
00245
00246 template<class C, class Tuple, typename std::enable_if<tupleEntriesModel<C, Tuple>(), int>::type = 0>
00247 constexpr bool requireConceptForTupleEntries()
00248 {
00249 return true;
00250 }
00251
00252
00253
00254 template<class From, class To,
00255 typename std::enable_if< std::is_convertible<From, To>::value, int>::type = 0>
00256 constexpr bool requireConvertible()
00257 {
00258 return true;
00259 }
00260
00261
00262
00263 template<class To, class From,
00264 typename std::enable_if< std::is_convertible<From, To>::value, int>::type = 0>
00265 constexpr bool requireConvertible(const From&)
00266 {
00267 return true;
00268 }
00269
00270
00271
00272
00273
00274 template<typename T>
00275 constexpr bool requireType()
00276 {
00277 return true;
00278 }
00279
00280
00281
00282 template<class Base, class Derived,
00283 typename std::enable_if< std::is_base_of<Base, Derived>::value, int>::type = 0>
00284 constexpr bool requireBaseOf()
00285 {
00286 return true;
00287 }
00288
00289
00290
00291 template<class Base, class Derived,
00292 typename std::enable_if< std::is_base_of<Base, Derived>::value, int>::type = 0>
00293 constexpr bool requireBaseOf(const Derived&)
00294 {
00295 return true;
00296 }
00297
00298
00299
00300 template<class A, class B,
00301 typename std::enable_if< std::is_same<A, B>::value, int>::type = 0>
00302 constexpr bool requireSameType()
00303 {
00304 return true;
00305 }
00306
00307
00308
00309 }
00310
00311
00312
00313 }
00314
00315
00316
00317
00318 #endif // DUNE_COMMON_CONCEPT_HH