basix_doc 0.1
|
00001 00002 /****************************************************************************** 00003 * MODULE : category_meta.hpp 00004 * DESCRIPTION: Abstract categorical meta-properties of types 00005 * COPYRIGHT : (C) 2006 Joris van der Hoeven 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 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 * Boolean structure 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 * And 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 * Different types 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 * Basic macros for defining structure 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 * Basic arithmetic categories 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 * Factorial ring structure 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 * Elementary functions 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 * Ordered structures 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 * Complex structure 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 * Ball structure 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 } // namespace mmx 00247 #endif // __CATEGORY_META_HPP