00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00028 #ifndef _ARAGELI_function_traits_hpp_
00029 #define _ARAGELI_function_traits_hpp_
00030
00031 #include "config.hpp"
00032 #include "type_opers.hpp"
00033 #include "type_traits.hpp"
00034
00035
00036
00037
00038
00039 namespace Arageli
00040 {
00041
00043
00044 template
00045 <
00046 typename TAG,
00047 typename ARG,
00048 typename RETTYPE,
00049 bool ALARG,
00050 bool SE
00051 >
00052 struct unary_function_traits_base
00053 {
00054 static const bool is_specialized = true;
00055 typedef RETTYPE result_type;
00056 typedef ARG argument_type;
00057 typedef TAG tag;
00058 static const bool alternates_argument = ALARG;
00059 static const bool has_side_effect = SE;
00060 };
00061
00062
00063 template
00064 <
00065 typename TAG,
00066 typename ARG1, typename ARG2,
00067 typename RETTYPE,
00068 bool ALARG1, bool ALARG2,
00069 bool SE
00070 >
00071 struct binary_function_traits_base
00072 {
00073 static const bool is_specialized = true;
00074 typedef RETTYPE result_type;
00075 typedef ARG1 first_argument_type;
00076 typedef ARG2 second_argument_type;
00077 typedef TAG tag;
00078 static const bool alternates_first_argument = ALARG1;
00079 static const bool alternates_second_argument = ALARG2;
00080 static const bool has_side_effect = SE;
00081 };
00082
00083
00084 template
00085 <
00086 typename TAG,
00087 typename ARG1, typename ARG2, typename ARG3,
00088 typename RETTYPE,
00089 bool ALARG1, bool ALARG2, bool ALARG3,
00090 bool SE
00091 >
00092 struct ternary_function_traits_base
00093 {
00094 static const bool is_specialized = true;
00095 typedef RETTYPE result_type;
00096 typedef ARG1 first_argument_type;
00097 typedef ARG2 second_argument_type;
00098 typedef ARG3 third_argument_type;
00099 typedef TAG tag;
00100 static const bool alternates_first_argument = ALARG1;
00101 static const bool alternates_second_argument = ALARG2;
00102 static const bool alternates_third_argument = ALARG3;
00103 static const bool has_side_effect = SE;
00104 };
00105
00106
00107 namespace function_tag
00108 {
00109
00110
00111
00112 class function {};
00113
00114 class unary : public virtual function {};
00115 class binary : public virtual function {};
00116 class ternary : public virtual function {};
00117
00118 class arithmetic : public virtual function {};
00119 class logical : public virtual function {};
00120 class bitwise : public virtual function {};
00121
00122 class compare : public virtual function {};
00123 class each_compare : public binary, public compare {};
00124 class all_compare : public binary, public compare {};
00125
00126
00127
00128 class indirection : public unary {};
00129 class address : public unary {};
00130
00131 class unary_plus : public unary, public arithmetic {};
00132 class unary_minus : public unary, public arithmetic {};
00133 class logical_not : public unary, public logical {};
00134 class bitwise_not : public unary, public bitwise {};
00135 class prefix_increment : public unary, public arithmetic {};
00136 class prefix_decrement : public unary, public arithmetic {};
00137 class postfix_increment : public unary, public arithmetic {};
00138 class postfix_decrement : public unary, public arithmetic {};
00139
00140 class parentheses_0 : public unary {};
00141 class parentheses_1 : public binary {};
00142 class parentheses_2 : public ternary {};
00143 class subscript : public binary {};
00144
00145
00146
00147 class plus {};
00148 class minus {};
00149 class multiplies {};
00150 class divides {};
00151 class modulus {};
00152 class logical_or {};
00153 class logical_and {};
00154 class equal_to : public binary, public compare {};
00155 class not_equal_to : public binary, public compare {};
00156 class greater : public binary, public compare {};
00157 class less : public binary, public compare {};
00158 class greater_equal : public binary, public compare {};
00159 class less_equal : public binary, public compare {};
00160 class bitwise_or {};
00161 class bitwise_and {};
00162 class bitwise_xor {};
00163 class shift_left {};
00164 class shift_right {};
00165
00166 class assign {};
00167 class assign_plus {};
00168 class assign_minus {};
00169 class assign_multiplies {};
00170 class assign_divides {};
00171 class assign_modulus {};
00172 class assign_bitwise_or {};
00173 class assign_bitwise_and {};
00174 class assign_bitwise_xor {};
00175 class assign_shift_left {};
00176 class assign_shift_right {};
00177
00178 typedef assign_plus right_assign_plus;
00179 typedef assign_minus right_assign_minus;
00180 typedef assign_multiplies right_assign_multiplies;
00181 typedef assign_divides right_assign_divides;
00182 typedef assign_modulus right_assign_modulus;
00183 typedef assign_bitwise_or right_assign_bitwise_or;
00184 typedef assign_bitwise_and right_assign_bitwise_and;
00185 typedef assign_bitwise_xor right_assign_bitwise_xor;
00186 typedef assign_shift_left right_assign_shift_left;
00187 typedef assign_shift_right right_assign_shift_right;
00188
00189 class left_assign_plus {};
00190 class left_assign_minus {};
00191 class left_assign_multiplies {};
00192 class left_assign_modulus {};
00193 class left_assign_bitwise_or {};
00194 class left_assign_bitwise_and {};
00195 class left_assign_bitwise_xor {};
00196 class left_assign_shift_left {};
00197 class left_assign_shift_right {};
00198
00199 class cmp : public binary, public compare {};
00200
00201 class each_cmp : public each_compare {};
00202
00203 class each_equal_to : public each_compare {};
00204 class each_not_equal_to : public each_compare {};
00205 class each_greater : public each_compare {};
00206 class each_less : public each_compare {};
00207 class each_greater_equal : public each_compare {};
00208 class each_less_equal : public each_compare {};
00209 class all_equal_to : public all_compare {};
00210 class all_not_equal_to : public all_compare {};
00211 class all_greater : public all_compare {};
00212 class all_less : public all_compare {};
00213 class all_greater_equal : public all_compare {};
00214 class all_less_equal : public all_compare {};
00215
00216 template <typename T>
00217 struct omit_each;
00218
00219 #define ARAGELI_FUNCTION_TAG_AG2EL(NAME, PREFIX) \
00220 template <> \
00221 struct omit_each<PREFIX##_##NAME> \
00222 { typedef NAME type; };
00223
00224 ARAGELI_FUNCTION_TAG_AG2EL(cmp, each)
00225 ARAGELI_FUNCTION_TAG_AG2EL(equal_to, each)
00226 ARAGELI_FUNCTION_TAG_AG2EL(not_equal_to, each)
00227 ARAGELI_FUNCTION_TAG_AG2EL(less, each)
00228 ARAGELI_FUNCTION_TAG_AG2EL(greater, each)
00229 ARAGELI_FUNCTION_TAG_AG2EL(less_equal, each)
00230 ARAGELI_FUNCTION_TAG_AG2EL(greater_equal, each)
00231 ARAGELI_FUNCTION_TAG_AG2EL(equal_to, all)
00232 ARAGELI_FUNCTION_TAG_AG2EL(not_equal_to, all)
00233 ARAGELI_FUNCTION_TAG_AG2EL(less, all)
00234 ARAGELI_FUNCTION_TAG_AG2EL(greater, all)
00235 ARAGELI_FUNCTION_TAG_AG2EL(less_equal, all)
00236 ARAGELI_FUNCTION_TAG_AG2EL(greater_equal, all)
00237
00238
00239 template <typename T> struct compare_category
00240 { typedef function type; };
00241
00242 #define ARAGELI_FUNCTION_TAG_CMPCAT(TAG, CATEGORY) \
00243 template <> struct compare_category<TAG> \
00244 { typedef CATEGORY type; };
00245
00246 ARAGELI_FUNCTION_TAG_CMPCAT(each_equal_to, each_compare)
00247 ARAGELI_FUNCTION_TAG_CMPCAT(each_not_equal_to, each_compare)
00248 ARAGELI_FUNCTION_TAG_CMPCAT(each_greater, each_compare)
00249 ARAGELI_FUNCTION_TAG_CMPCAT(each_less, each_compare)
00250 ARAGELI_FUNCTION_TAG_CMPCAT(each_greater_equal, each_compare)
00251 ARAGELI_FUNCTION_TAG_CMPCAT(each_less_equal, each_compare)
00252 ARAGELI_FUNCTION_TAG_CMPCAT(all_equal_to, all_compare)
00253 ARAGELI_FUNCTION_TAG_CMPCAT(all_not_equal_to, all_compare)
00254 ARAGELI_FUNCTION_TAG_CMPCAT(all_greater, all_compare)
00255 ARAGELI_FUNCTION_TAG_CMPCAT(all_less, all_compare)
00256 ARAGELI_FUNCTION_TAG_CMPCAT(all_greater_equal, all_compare)
00257 ARAGELI_FUNCTION_TAG_CMPCAT(all_less_equal, all_compare)
00258
00259
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 template <typename TAG, typename ARG>
00311 struct unary_function_traits
00312 {
00313 static const bool is_specialized = false;
00314 typedef void result_type;
00315 typedef ARG argument_type;
00316 typedef TAG tag;
00317 static const bool alternates_argument = false;
00318 static const bool has_side_effect = false;
00319 };
00320
00321
00322 template <typename TAG, typename ARG1, typename ARG2>
00323 struct binary_function_traits
00324 {
00325 static const bool is_specialized = false;
00326 typedef void result_type;
00327 typedef ARG1 first_argument_type;
00328 typedef ARG2 second_argument_type;
00329 typedef TAG tag;
00330 static const bool alternates_first_argument = false;
00331 static const bool alternates_second_argument = false;
00332 static const bool has_side_effect = false;
00333 };
00334
00335
00336 template <typename TAG, typename ARG1, typename ARG2, typename ARG3>
00337 struct ternary_function_traits
00338 {
00339 static const bool is_specialized = false;
00340 typedef void result_type;
00341 typedef ARG1 first_argument_type;
00342 typedef ARG2 second_argument_type;
00343 typedef ARG3 third_argument_type;
00344 typedef TAG tag;
00345 static const bool alternates_first_argument = false;
00346 static const bool alternates_second_argument = false;
00347 static const bool alternates_third_argument = false;
00348 static const bool has_side_effect = false;
00349 };
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 #define ARAGELI_UNARY_FUNCTION_TRAITS(MNEM, RETTYPE, ALARG, SE) \
00360 template <typename Arg> \
00361 struct unary_function_traits<function_tag::MNEM, Arg> : \
00362 public unary_function_traits_base \
00363 <function_tag::MNEM, Arg, RETTYPE, ALARG, SE> \
00364 {};
00365
00366
00367 #define ARAGELI_BINARY_FUNCTION_TRAITS(MNEM, RETTYPE, ALARG1, ALARG2, SE) \
00368 template <typename Arg1, typename Arg2> \
00369 struct binary_function_traits<function_tag::MNEM, Arg1, Arg2> : \
00370 public binary_function_traits_base \
00371 <function_tag::MNEM, Arg1, Arg2, RETTYPE, ALARG1, ALARG2, SE> \
00372 {};
00373
00374 #define ARAGELI_TERNARY_FUNCTION_TRAITS(MNEM, RETTYPE, ALARG1, ALARG2, ALARG3, SE) \
00375 template <typename Arg1, typename Arg2, typename Arg3> \
00376 struct ternary_function_traits<function_tag::MNEM, Arg1, Arg2, Arg3> : \
00377 public ternary_function_traits_base \
00378 <function_tag::MNEM, Arg1, Arg2, Arg3, RETTYPE, ALARG1, ALARG2, ALARG3, SE> \
00379 {};
00380
00381 #define ARAGELI_EACH_CMP_FUNCTION_TRAITS(MNEM, ALARG1, ALARG2, SE) \
00382 template <typename Arg1, typename Arg2> \
00383 struct binary_function_traits<function_tag::MNEM, Arg1, Arg2> : \
00384 public binary_function_traits_base \
00385 < \
00386 function_tag::MNEM, Arg1, Arg2, \
00387 typename type_traits<Arg1>:: \
00388 template other_element_type_refcnt<bool, true>::type, \
00389 ALARG1, ALARG2, SE \
00390 > \
00391 {};
00392
00393
00394
00395 ARAGELI_UNARY_FUNCTION_TRAITS
00396 (indirection, typename omit_asterisk<Arg>::type, false, false);
00397 ARAGELI_UNARY_FUNCTION_TRAITS(address, Arg*, false, false);
00398 ARAGELI_UNARY_FUNCTION_TRAITS(unary_plus, typename omit_ref<Arg>::type, false, false);
00399 ARAGELI_UNARY_FUNCTION_TRAITS(unary_minus, typename omit_ref<Arg>::type, false, false);
00400 ARAGELI_UNARY_FUNCTION_TRAITS(logical_not, bool, false, false);
00401 ARAGELI_UNARY_FUNCTION_TRAITS(bitwise_not, typename omit_ref<Arg>::type, false, false);
00402 ARAGELI_UNARY_FUNCTION_TRAITS(prefix_increment, Arg&, true, false);
00403 ARAGELI_UNARY_FUNCTION_TRAITS(prefix_decrement, Arg&, true, false);
00404 ARAGELI_UNARY_FUNCTION_TRAITS
00405 (postfix_increment, typename omit_ref<Arg>::type, true, false);
00406 ARAGELI_UNARY_FUNCTION_TRAITS
00407 (postfix_decrement, typename omit_ref<Arg>::type, true, false);
00408
00409 ARAGELI_UNARY_FUNCTION_TRAITS(parentheses_0, Arg, false, false);
00410 ARAGELI_BINARY_FUNCTION_TRAITS(parentheses_1, Arg1, false, false, false);
00411 ARAGELI_TERNARY_FUNCTION_TRAITS(parentheses_2, Arg1, false, false, false, false);
00412 ARAGELI_BINARY_FUNCTION_TRAITS
00413 (subscript, typename omit_asterisk<Arg1>::type, false, false, false);
00414
00415 ARAGELI_BINARY_FUNCTION_TRAITS(plus, typename omit_ref<Arg1>::type, false, false, false);
00416 ARAGELI_BINARY_FUNCTION_TRAITS(minus, typename omit_ref<Arg1>::type, false, false, false);
00417 ARAGELI_BINARY_FUNCTION_TRAITS(multiplies, typename omit_ref<Arg1>::type, false, false, false);
00418 ARAGELI_BINARY_FUNCTION_TRAITS(divides, typename omit_ref<Arg1>::type, false, false, false);
00419 ARAGELI_BINARY_FUNCTION_TRAITS(modulus, typename omit_ref<Arg1>::type, false, false, false);
00420 ARAGELI_BINARY_FUNCTION_TRAITS(logical_or, bool, false, false, false);
00421 ARAGELI_BINARY_FUNCTION_TRAITS(logical_and, bool, false, false, false);
00422 ARAGELI_BINARY_FUNCTION_TRAITS(equal_to, bool, false, false, false);
00423 ARAGELI_BINARY_FUNCTION_TRAITS(not_equal_to, bool, false, false, false);
00424 ARAGELI_BINARY_FUNCTION_TRAITS(greater, bool, false, false, false);
00425 ARAGELI_BINARY_FUNCTION_TRAITS(less, bool, false, false, false);
00426 ARAGELI_BINARY_FUNCTION_TRAITS(greater_equal, bool, false, false, false);
00427 ARAGELI_BINARY_FUNCTION_TRAITS(less_equal, bool, false, false, false);
00428 ARAGELI_BINARY_FUNCTION_TRAITS(bitwise_or, typename omit_ref<Arg1>::type, false, false, false);
00429 ARAGELI_BINARY_FUNCTION_TRAITS(bitwise_and, typename omit_ref<Arg1>::type, false, false, false);
00430 ARAGELI_BINARY_FUNCTION_TRAITS(bitwise_xor, typename omit_ref<Arg1>::type, false, false, false);
00431 ARAGELI_BINARY_FUNCTION_TRAITS(shift_left, typename omit_ref<Arg1>::type, false, false, false);
00432 ARAGELI_BINARY_FUNCTION_TRAITS(shift_right, typename omit_ref<Arg1>::type, false, false, false);
00433 ARAGELI_BINARY_FUNCTION_TRAITS(all_equal_to, bool, false, false, false);
00434 ARAGELI_BINARY_FUNCTION_TRAITS(all_not_equal_to, bool, false, false, false);
00435 ARAGELI_BINARY_FUNCTION_TRAITS(all_greater, bool, false, false, false);
00436 ARAGELI_BINARY_FUNCTION_TRAITS(all_less, bool, false, false, false);
00437 ARAGELI_BINARY_FUNCTION_TRAITS(all_greater_equal, bool, false, false, false);
00438 ARAGELI_BINARY_FUNCTION_TRAITS(all_less_equal, bool, false, false, false);
00439 ARAGELI_EACH_CMP_FUNCTION_TRAITS(each_equal_to, false, false, false);
00440 ARAGELI_EACH_CMP_FUNCTION_TRAITS(each_not_equal_to, false, false, false);
00441 ARAGELI_EACH_CMP_FUNCTION_TRAITS(each_greater, false, false, false);
00442 ARAGELI_EACH_CMP_FUNCTION_TRAITS(each_less, false, false, false);
00443 ARAGELI_EACH_CMP_FUNCTION_TRAITS(each_greater_equal, false, false, false);
00444 ARAGELI_EACH_CMP_FUNCTION_TRAITS(each_less_equal, false, false, false);
00445
00446
00447 ARAGELI_BINARY_FUNCTION_TRAITS(assign, Arg1&, true, false, false);
00448 ARAGELI_BINARY_FUNCTION_TRAITS(assign_plus, Arg1&, true, false, false);
00449 ARAGELI_BINARY_FUNCTION_TRAITS(assign_minus, Arg1&, true, false, false);
00450 ARAGELI_BINARY_FUNCTION_TRAITS(assign_multiplies, Arg1&, true, false, false);
00451 ARAGELI_BINARY_FUNCTION_TRAITS(assign_divides, Arg1&, true, false, false);
00452 ARAGELI_BINARY_FUNCTION_TRAITS(assign_modulus, Arg1&, true, false, false);
00453 ARAGELI_BINARY_FUNCTION_TRAITS(assign_bitwise_or, Arg1&, true, false, false);
00454 ARAGELI_BINARY_FUNCTION_TRAITS(assign_bitwise_and, Arg1&, true, false, false);
00455 ARAGELI_BINARY_FUNCTION_TRAITS(assign_bitwise_xor, Arg1&, true, false, false);
00456 ARAGELI_BINARY_FUNCTION_TRAITS(assign_shift_left, Arg1&, true, false, false);
00457 ARAGELI_BINARY_FUNCTION_TRAITS(assign_shift_right, Arg1&, true, false, false);
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 ARAGELI_BINARY_FUNCTION_TRAITS(left_assign_plus, Arg2&, false, true, false);
00471 ARAGELI_BINARY_FUNCTION_TRAITS(left_assign_minus, Arg2&, false, true, false);
00472 ARAGELI_BINARY_FUNCTION_TRAITS(left_assign_multiplies, Arg2&, false, true, false);
00473 ARAGELI_BINARY_FUNCTION_TRAITS(left_assign_modulus, Arg2&, false, true, false);
00474 ARAGELI_BINARY_FUNCTION_TRAITS(left_assign_bitwise_or, Arg2&, false, true, false);
00475 ARAGELI_BINARY_FUNCTION_TRAITS(left_assign_bitwise_and, Arg2&, false, true, false);
00476 ARAGELI_BINARY_FUNCTION_TRAITS(left_assign_bitwise_xor, Arg2&, false, true, false);
00477 ARAGELI_BINARY_FUNCTION_TRAITS(left_assign_shift_left, Arg2&, false, true, false);
00478 ARAGELI_BINARY_FUNCTION_TRAITS(left_assign_shift_right, Arg2&, false, true, false);
00479
00480
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 #endif // #ifndef _ARAGELI_function_traits_hpp_