00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef PRODUCT_HH
00018 # define PRODUCT_HH
00019
00020 # include "concept_tools.hh"
00021 # include "../axioms/axioms.hh"
00022 # include "../utils/call_tuple.hh"
00023 # include "../utils/call_with.hh"
00024 # include "../wrappers/function_wrappers.hh"
00025 # include "../type_traits/is_callable.hh"
00026 # include "congruence.hh"
00027
00028 namespace catsfoot {
00029
00030 template <typename Type,
00031 typename Constructor,
00032 typename... Projections>
00033 struct product: public concept {
00034 typedef concept_list<
00035 is_callable<Projections(const Type&)>...,
00036 is_callable
00037 <Constructor(typename is_callable<Projections(const Type&)>
00038 ::result_type...)>,
00039 std::is_convertible
00040 <typename is_callable
00041 <Constructor(typename is_callable
00042 <Projections(const Type&)>::result_type...)>::result_type,
00043 Type>,
00044 equivalence_eq<Type>,
00045 equivalence_eq
00046 <typename is_callable<Projections(const Type&)>::result_type>...
00047 > requirements;
00048
00049 static void projections(const std::tuple
00050 <typename is_callable<Projections(const Type&)>
00051 ::result_type...>& comps,
00052 const std::tuple<Projections...>& p,
00053 const Constructor& constr) {
00054 axiom_assert(call_tuple(p, call_with(constr, comps)) == comps);
00055 }
00056
00057 static void universality(const Type& t,
00058 const std::tuple<Projections...>& p,
00059 const Constructor& constr) {
00060 axiom_assert(call_with(constr, call_tuple(p, t)) == t);
00061 }
00062
00063 AXIOMS(projections, universality);
00064 };
00065
00066 template <typename Type,
00067 typename... Projections>
00068 struct simple_product: public concept {
00069 typedef concept_list<
00070 is_constructible
00071 <Type(typename is_callable<Projections(const Type&)>::result_type...)>,
00072 product<Type, constructor_wrap<Type>,
00073 Projections...>
00074 > requirements;
00075 };
00076
00077 template <typename Type, typename... Projections>
00078 struct verified<product
00079 <Type,
00080 constructor_wrap
00081 <Type>, Projections...> >:
00082 public verified<simple_product<Type, Projections...> > {};
00083
00084 }
00085
00086 #endif