00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __CATEGORY_META_HPP
00014 #define __CATEGORY_META_HPP
00015 #include <basix/operators.hpp>
00016
00018
00019 namespace mmx {
00020
00021
00022
00023
00024
00025 template<bool val>
00026 struct boolean_helper {
00027 static const bool value;
00028 };
00029
00030 template<bool val> const bool
00031 boolean_helper<val>::value= val;
00032
00033 struct always {
00034 typedef boolean_helper<true> Cond;
00035 static inline bool value () { return Cond::value; }
00036 static inline generic lazy_value () {
00037 return as<generic> (true); }
00038 };
00039
00040 struct never {
00041 typedef boolean_helper<false> Cond;
00042 static inline bool value () { return Cond::value; }
00043 static inline generic lazy_value () {
00044 return as<generic> (false); }
00045 };
00046
00047
00048
00049
00050
00051 template<typename T1, typename T2>
00052 struct both_helper {
00053 static const bool value;
00054 };
00055
00056 template<typename T1, typename T2> const bool
00057 both_helper<T1,T2>::value= T1::value && T2::value;
00058
00059 template<typename T1, typename T2>
00060 struct both {
00061 typedef both_helper<typename T1::Cond, typename T2::Cond> Cond;
00062 static inline bool value () { return Cond::value; }
00063 static inline generic lazy_value () {
00064 return gen (GEN_AND, T1::lazy_value (), T2::lazy_value ()); }
00065 };
00066
00067
00068
00069
00070
00071 template<typename T1, typename T2>
00072 struct different_helper {
00073 static const bool value;
00074 };
00075
00076 template<typename T1, typename T2> const bool
00077 different_helper<T1,T2>::value= true;
00078
00079 template<typename T1>
00080 struct different_helper<T1,T1> {
00081 static const bool value;
00082 };
00083
00084 template<typename T1> const bool
00085 different_helper<T1,T1>::value= false;
00086
00087 template<typename T1, typename T2>
00088 struct different {
00089 typedef different_helper<T1,T2> Cond;
00090 static inline bool value () { return Cond::value; }
00091 static inline generic lazy_value () { return as_generic (Cond::value); }
00092 };
00093
00094
00095
00096
00097
00098 template<typename T, typename Op>
00099 struct has {
00100 typedef boolean_helper<false> Cond;
00101 static inline generic lazy_value () {
00102 return gen (GEN_HAS, T::name(), Op::name()); }
00103 };
00104
00105 template<typename Op>
00106 struct has<generic,Op> {
00107 typedef boolean_helper<true> Cond;
00108 static inline bool value () { return Cond::value; }
00109 static inline generic lazy_value () {
00110 return as<generic> (true); }
00111 };
00112
00113 #define HAS(Op) \
00114 META_TMPL \
00115 struct has<META_TYPE,Op > { \
00116 typedef META_COND Type; \
00117 typedef META_TPNM Type::Cond Cond; \
00118 static inline generic lazy_value () { \
00119 return META_COND::lazy_value (); } \
00120 };
00121
00122
00123
00124
00125
00126 struct ring_cat {
00127 static generic name () { return "Ring"; }
00128 };
00129
00130 #define HAS_RING() \
00131 HAS(neg_op) \
00132 HAS(add_op) \
00133 HAS(sub_op) \
00134 HAS(mul_op) \
00135 HAS(square_op) \
00136 HAS(ring_cat)
00137
00138 struct euclidean_ring_cat {
00139 static generic name () { return "Euclidean_ring"; }
00140 };
00141
00142 #define HAS_EUCLIDEAN_RING_ABOVE_RING() \
00143 HAS(quo_op) \
00144 HAS(rem_op) \
00145 HAS(euclidean_ring_cat)
00146
00147 #define HAS_EUCLIDEAN_RING() \
00148 HAS_RING() \
00149 HAS_EUCLIDEAN_RING_ABOVE_RING()
00150
00151 struct field_cat {
00152 static generic name () { return "Field"; }
00153 };
00154
00155 #define HAS_FIELD_ABOVE_EUCLIDEAN_RING() \
00156 HAS(div_op) \
00157 HAS(field_cat)
00158
00159 #define HAS_FIELD_ABOVE_RING() \
00160 HAS_EUCLIDEAN_RING_ABOVE_RING() \
00161 HAS_FIELD_ABOVE_EUCLIDEAN_RING()
00162
00163 #define HAS_FIELD() \
00164 HAS_EUCLIDEAN_RING() \
00165 HAS_FIELD_ABOVE_EUCLIDEAN_RING()
00166
00167
00168
00169
00170
00171 struct factorial_cat {
00172 static generic name () { return "Factorial"; }
00173 };
00174
00175 #define HAS_FACTORIAL() \
00176 HAS(gcd_op) \
00177 HAS(lcm_op)
00178
00179
00180
00181
00182
00183 struct elementary_cat {
00184 static generic name () { return "Elementary"; }
00185 };
00186
00187 #define HAS_ELEMENTARY() \
00188 HAS(sqrt_op) \
00189 HAS(pow_op) \
00190 HAS(exp_op) \
00191 HAS(log_op) \
00192 HAS(cos_op) \
00193 HAS(sin_op) \
00194 HAS(tan_op) \
00195 HAS(acos_op) \
00196 HAS(asin_op) \
00197 HAS(atan_op) \
00198 HAS(elementary_cat)
00199
00200
00201
00202
00203
00204 struct ordering_cat {
00205 static generic name () { return "Ordering"; }
00206 };
00207
00208 #define HAS_ORDERING() \
00209 HAS(less_op) \
00210 HAS(lesseq_op) \
00211 HAS(gtr_op) \
00212 HAS(gtreq_op) \
00213 HAS(ordering_cat)
00214
00215
00216
00217
00218
00219 struct complex_cat {
00220 static generic name () { return "Complex"; }
00221 };
00222
00223 #define HAS_COMPLEX() \
00224 HAS(gaussian_op) \
00225 HAS(Re_op) \
00226 HAS(Im_op) \
00227 HAS(abs_op) \
00228 HAS(arg_op) \
00229 HAS(conj_op) \
00230 HAS(complex_cat)
00231
00232
00233
00234
00235
00236 struct ball_cat {
00237 static generic name () { return "Ball"; }
00238 };
00239
00240 #define HAS_BALL() \
00241 HAS(ball_op) \
00242 HAS(center_op) \
00243 HAS(radius_op) \
00244 HAS(ball_cat)
00245
00246 }
00247 #endif // __CATEGORY_META_HPP