functional.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     functional.hpp -- class-functional interfaces for existing functions.
00004 
00005     This file is a part of the Arageli library.
00006 
00007     Copyright (C) Nikolai Yu. Zolotykh, 1999--2006
00008     Copyright (C) Sergey S. Lyalin, 2005
00009     University of Nizhni Novgorod, Russia
00010 
00011 *****************************************************************************/
00012 
00019 #ifndef _ARAGELI_functional_hpp_
00020 #define _ARAGELI_functional_hpp_
00021 
00022 #include "config.hpp"
00023 
00024 #include <functional>
00025 
00026 #include "basefuncs.hpp"
00027 #include "function_traits.hpp"
00028 #include "factory.hpp"
00029 #include "cmp.hpp"
00030 
00031 // WARNING! Need more headers to include.
00032 
00033 //#include "std_import.hpp"
00034 //#include "prime.hpp"
00035 //#include "powerest.hpp"
00036 
00037 
00038 namespace Arageli
00039 {
00040 
00041 //#define _ARAGELI_RIGHT_ASSIGN(MNEM, OPER)             \
00042 //  template <typename T1, typename T2>                 \
00043 //  inline T2& left_assign_##MNEM (const T1& x, T2& y)  \
00044 //  { return y = x OPER y; }
00045 //
00048 //  
00049 //_ARAGELI_RIGHT_ASSIGN(plus, +);
00050 //_ARAGELI_RIGHT_ASSIGN(minus, -);
00051 //_ARAGELI_RIGHT_ASSIGN(multiplies, *);
00052 //_ARAGELI_RIGHT_ASSIGN(divides, /);
00053 //_ARAGELI_RIGHT_ASSIGN(modulus, %);
00054 //_ARAGELI_RIGHT_ASSIGN(bitwise_or, |);
00055 //_ARAGELI_RIGHT_ASSIGN(bitwise_and, &);
00056 //_ARAGELI_RIGHT_ASSIGN(bitwise_xor, ^);
00057 //_ARAGELI_RIGHT_ASSIGN(shift_left, <<);
00058 //_ARAGELI_RIGHT_ASSIGN(shift_right, >>);
00059 //
00061 
00062 
00065 //
00066 //
00067 //
00069 
00070 // These prototypes are here temporary.
00071 template <typename T>
00072 bool is_prime (const T& x);
00073 
00074 //template <typename T>
00075 //bool is_null (const T& x);
00076 
00077 
00079 namespace func
00080 {
00081 
00082 #define _ARAGELI_FUNC_BUILDER_1(NAME, RES)                  \
00083     template <typename T>                                   \
00084     struct NAME : public std::unary_function<T, RES>        \
00085     {                                                       \
00086         RES operator() (const T& x) const                   \
00087         { return Arageli::NAME(x); }                        \
00088                                                             \
00089         RES operator() (T& x) const                         \
00090         { return Arageli::NAME(x); }                        \
00091     }
00092 
00093 _ARAGELI_FUNC_BUILDER_1(is_null, bool);
00094 _ARAGELI_FUNC_BUILDER_1(is_unit, bool);
00095 _ARAGELI_FUNC_BUILDER_1(is_opposite_unit, bool);
00096 _ARAGELI_FUNC_BUILDER_1(is_negative, bool);
00097 _ARAGELI_FUNC_BUILDER_1(is_positive, bool);
00098 _ARAGELI_FUNC_BUILDER_1(sign, int);
00099 _ARAGELI_FUNC_BUILDER_1(is_prime, bool);
00100 _ARAGELI_FUNC_BUILDER_1(is_even, bool);
00101 _ARAGELI_FUNC_BUILDER_1(is_odd, bool);
00102 // and so on
00103 
00104 #undef _ARAGELI_FUNC_BUILDER_1
00105 
00106 #define _ARAGELI_UNARY_OPERATOR_FUNC_BUILDER_1(NAME, OPER)  \
00107     template <typename Arg, typename Res = Arg>             \
00108     struct NAME : public std::unary_function<Arg, Res>      \
00109     {                                                       \
00110         Res operator() (const Arg& x) const                 \
00111         { return OPER x; }                                  \
00112                                                             \
00113         Res operator() (Arg& x) const                       \
00114         { return OPER x; }                                  \
00115     };
00116 
00117 _ARAGELI_UNARY_OPERATOR_FUNC_BUILDER_1(indirection, *);
00118 _ARAGELI_UNARY_OPERATOR_FUNC_BUILDER_1(address, &);
00119 _ARAGELI_UNARY_OPERATOR_FUNC_BUILDER_1(unary_plus, +);
00120 _ARAGELI_UNARY_OPERATOR_FUNC_BUILDER_1(unary_minus, -);
00121 _ARAGELI_UNARY_OPERATOR_FUNC_BUILDER_1(logical_not, !);
00122 _ARAGELI_UNARY_OPERATOR_FUNC_BUILDER_1(bitwise_not, ~);
00123 _ARAGELI_UNARY_OPERATOR_FUNC_BUILDER_1(prefix_increment, ++);
00124 _ARAGELI_UNARY_OPERATOR_FUNC_BUILDER_1(prefix_decrement, --);
00125 
00126 
00127 template <typename Arg, typename Res = Arg>
00128 struct postfix_increment : public std::unary_function<Arg, Res>
00129 {
00130     Res operator() (const Arg& x) const
00131     { return x++; }
00132 
00133     Res operator() (Arg& x) const
00134     { return x++; }
00135 };
00136 
00137 template <typename Arg, typename Res = Arg>
00138 struct postfix_decrement : public std::unary_function<Arg, Res>
00139 {
00140     Res operator() (const Arg& x) const
00141     { return x--; }
00142 
00143     Res operator() (Arg& x) const
00144     { return x--; }
00145 };
00146 
00147 
00148 #define _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_1(NAME, OPER)     \
00149     template <typename Arg1, typename Arg2 = Arg1,              \
00150         typename Res = Arg1>                                    \
00151     struct NAME : public std::binary_function<Arg1, Arg2, Res>  \
00152     {                                                           \
00153         Res operator() (const Arg1& x, const Arg2& y) const     \
00154         { return OPER(x, y); }                                  \
00155                                                                 \
00156         Res operator() (const Arg1& x, Arg2& y) const           \
00157         { return OPER(x, y); }                                  \
00158                                                                 \
00159         Res operator() (Arg1& x, const Arg2& y) const           \
00160         { return OPER(x, y); }                                  \
00161                                                                 \
00162         Res operator() (Arg1& x, Arg2& y) const                 \
00163         { return OPER(x, y); }                                  \
00164     };
00165 
00166 #define _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(NAME, OPER)     \
00167     template <typename Arg1, typename Arg2 = Arg1,              \
00168         typename Res = Arg1>                                    \
00169     struct NAME : public std::binary_function<Arg1, Arg2, Res>  \
00170     {                                                           \
00171         Res operator() (const Arg1& x, const Arg2& y) const     \
00172         { return x OPER y; }                                    \
00173                                                                 \
00174         Res operator() (const Arg1& x, Arg2& y) const           \
00175         { return x OPER y; }                                    \
00176                                                                 \
00177         Res operator() (Arg1& x, const Arg2& y) const           \
00178         { return x OPER y; }                                    \
00179                                                                 \
00180         Res operator() (Arg1& x, Arg2& y) const                 \
00181         { return x OPER y; }                                    \
00182     };
00183 
00184 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(plus, +);
00185 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(minus, -);
00186 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(multiplies, *);
00187 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(divides, /);
00188 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(modulus, %);
00189 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(logical_or, ||);
00190 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(logical_and, &&);
00191 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(equal_to, ==);
00192 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(not_equal_to, !=);
00193 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(greater, >);
00194 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(less, <);
00195 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(greater_equal, >=);
00196 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(less_equal, <=);
00197 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(bitwise_or, |);
00198 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(bitwise_and, &);
00199 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(bitwise_xor, ^);
00200 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(shift_left, <<);
00201 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(shift_right, >>);
00202 
00203 
00204 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(assign, =);
00205 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(assign_plus, +=);
00206 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(assign_minus, -=);
00207 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(assign_multiplies, *=);
00208 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(assign_divides, /=);
00209 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(assign_modulus, %=);
00210 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(assign_bitwise_or, |=);
00211 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(assign_bitwise_and, &=);
00212 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(assign_bitwise_xor, ^=);
00213 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(assign_shift_left, <<=);
00214 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(assign_shift_right, >>=);
00215 
00216 
00217 //template <typename Arg1, typename Arg2 = Arg1,
00218 //  typename Res = Arg1>
00219 //struct assign_shift_left : public std::binary_function<Arg1, Arg2, Res>
00220 //{
00221 //  Res operator() (const Arg1& x, const Arg2& y) const
00222 //  { return operator<<=(x, y); }
00223 //                      
00224 //  Res operator() (const Arg1& x, Arg2& y) const
00225 //  { return operator<<=(x, y); }                       
00226 //                                              
00227 //  Res operator() (Arg1& x, const Arg2& y) const
00228 //  { return x <<= y; }                     
00229 //                                              
00230 //  Res operator() (Arg1& x, Arg2& y) const     
00231 //  { return operator<<=(x, y); }                       
00232 //};
00233 //
00234 //
00235 //template <typename Arg1, typename Arg2 = Arg1,
00236 //  typename Res = Arg1>
00237 //struct assign_shift_right : public std::binary_function<Arg1, Arg2, Res>
00238 //{
00239 //  Res operator() (const Arg1& x, const Arg2& y) const
00240 //  { return operator>>=(x, y); }
00241 //                      
00242 //  Res operator() (const Arg1& x, Arg2& y) const
00243 //  { return operator>>=(x, y); }                       
00244 //                                              
00245 //  Res operator() (Arg1& x, const Arg2& y) const
00246 //  { return operator>>=(x, y); }                       
00247 //                                              
00248 //  Res operator() (Arg1& x, Arg2& y) const     
00249 //  { return operator>>=(x, y); }                       
00250 //};
00251 //
00252 
00253 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(right_assign_plus, +=);
00254 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(right_assign_minus, -=);
00255 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(right_assign_multiplies, *=);
00256 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(right_assign_divides, /=);
00257 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(right_assign_modulus, %=);
00258 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(right_assign_bitwise_or, |=);
00259 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(right_assign_bitwise_and, &=);
00260 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(right_assign_bitwise_xor, ^=);
00261 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(right_assign_shift_left, <<=);
00262 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_2(right_assign_shift_right, >>=);
00263 
00264 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_1
00265     (left_assign_plus, Arageli::left_assign_plus);
00266 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_1
00267     (left_assign_minus, Arageli::left_assign_minus);
00268 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_1
00269     (left_assign_multiplies, Arageli::left_assign_multiplies);
00270 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_1
00271     (left_assign_divides, Arageli::left_assign_divides);
00272 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_1
00273     (left_assign_modulus, Arageli::left_assign_modulus);
00274 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_1
00275     (left_assign_bitwise_or, Arageli::left_assign_bitwise_or);
00276 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_1
00277     (left_assign_bitwise_and, Arageli::left_assign_bitwise_and);
00278 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_1
00279     (left_assign_bitwise_xor, Arageli::left_assign_bitwise_xor);
00280 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_1
00281     (left_assign_shift_left, Arageli::left_assign_shift_left);
00282 _ARAGELI_BINARY_OPERATOR_FUNC_BUILDER_1
00283     (left_assign_shift_right, Arageli::left_assign_shift_right);
00284 
00285 
00286 template <typename Arg, typename Res = Arg>
00287 struct parentheses_0 : public std::unary_function<Arg, Res>
00288 {
00289     Res operator() (const Arg& x) const { return x(); }
00290     Res operator() (Arg& x) const { return x(); }
00291 };
00292 
00293 template <typename Arg1, typename Arg2, typename Res = Arg2>
00294 struct parentheses_1 : public std::binary_function<Arg1, Arg2, Res>
00295 {
00296     Res operator() (const Arg1& x, const Arg2& y) const { return x(y); }
00297     Res operator() (const Arg1& x, Arg2& y) const { return x(y); }
00298     Res operator() (Arg1& x, const Arg2& y) const { return x(y); }
00299     Res operator() (Arg1& x, Arg2& y) const { return x(y); }
00300 };
00301 
00302 template <typename Arg1, typename Arg2, typename Res = Arg2>
00303 struct subscript : public std::binary_function<Arg1, Arg2, Res>
00304 {
00305     Res operator() (const Arg1& x, const Arg2& y) const { return x[y]; }
00306     Res operator() (const Arg1& x, Arg2& y) const { return x[y]; }
00307     Res operator() (Arg1& x, const Arg2& y) const { return x[y]; }
00308     Res operator() (Arg1& x, Arg2& y) const { return x[y]; }
00309 };
00310 
00311 template
00312 <
00313     typename Func,
00314     typename Arg1 = typename Func::first_argument_type,
00315     typename Arg2 = typename Func::second_argument_type,
00316     typename Res = typename Func::result_type
00317 >
00318 struct swap_args : public std::binary_function<Arg1, Arg2, Res>
00319 {
00320     Res operator() (const Arg1& x, const Arg2& y) const
00321     { return base(y, x); }
00322 
00323     Res operator() (const Arg1& x, Arg2& y) const
00324     { return base(y, x); }
00325 
00326     Res operator() (Arg1& x, const Arg2& y) const
00327     { return base(y, x); }
00328 
00329     Res operator() (Arg1& x, Arg2& y) const     
00330     { return base(y, x); }
00331 
00332     swap_args (const Func& func_a) : base(func_a) {}
00333 
00334     Func base;
00335 };
00336 
00337 template <typename Func>
00338 inline swap_args<Func> make_swap_args (const Func& func)
00339 { return swap_args<Func>(func); }
00340 
00341 
00342 
00343 }
00344 
00345 namespace gfunc
00346 {
00347 
00348 #define _ARAGELI_FUNC_BUILDER_1(NAME, RES)      \
00349     struct NAME                                 \
00350     {                                           \
00351         template <typename T>                   \
00352         RES operator() (const T& x) const       \
00353         { return Arageli::NAME(x); }            \
00354     };
00355 
00356 #define _ARAGELI_FUNC_BUILDER_2(NAME, RES)              \
00357     struct NAME                                         \
00358     {                                                   \
00359         template <typename T1, typename T2>             \
00360         RES operator() (const T1& x, const T2& y) const \
00361         { return Arageli::NAME(x, y); }                 \
00362     };
00363 
00364 _ARAGELI_FUNC_BUILDER_2(cmp, int)
00365 
00366 
00367 template <typename Tag> struct by_tag;
00368 
00369 #define ARAGELI_FUNCTIONAL_PREFIX_NONMODIF_UNARY_GFUNC_BY_TAG(NAME, OPER)   \
00370     template<> struct by_tag<function_tag::NAME>        \
00371     {                                                   \
00372         template <typename T1>                          \
00373             typename unary_function_traits              \
00374                 <function_tag::NAME, T1>::result_type   \
00375         operator() (const T1& x) const                  \
00376         { return OPER x; }                              \
00377     };
00378 
00379 ARAGELI_FUNCTIONAL_PREFIX_NONMODIF_UNARY_GFUNC_BY_TAG(indirection, *)
00380 ARAGELI_FUNCTIONAL_PREFIX_NONMODIF_UNARY_GFUNC_BY_TAG(address, &)
00381 ARAGELI_FUNCTIONAL_PREFIX_NONMODIF_UNARY_GFUNC_BY_TAG(unary_plus, +)
00382 ARAGELI_FUNCTIONAL_PREFIX_NONMODIF_UNARY_GFUNC_BY_TAG(unary_minus, -)
00383 ARAGELI_FUNCTIONAL_PREFIX_NONMODIF_UNARY_GFUNC_BY_TAG(logical_not, !)
00384 ARAGELI_FUNCTIONAL_PREFIX_NONMODIF_UNARY_GFUNC_BY_TAG(bitwise_not, ~)
00385 
00386 
00387 #define ARAGELI_FUNCTIONAL_PREFIX_MODIF_UNARY_GFUNC_BY_TAG(NAME, OPER)  \
00388     template<> struct by_tag<function_tag::NAME>        \
00389     {                                                   \
00390         template <typename T1>                          \
00391             typename unary_function_traits              \
00392                 <function_tag::NAME, T1>::result_type   \
00393         operator() (T1& x) const                        \
00394         { return OPER x; }                              \
00395     };
00396 
00397 
00398 ARAGELI_FUNCTIONAL_PREFIX_MODIF_UNARY_GFUNC_BY_TAG(prefix_increment, ++)
00399 ARAGELI_FUNCTIONAL_PREFIX_MODIF_UNARY_GFUNC_BY_TAG(prefix_decrement, --)
00400 
00401 
00402 #define ARAGELI_FUNCTIONAL_POSTFIX_MODIF_UNARY_GFUNC_BY_TAG(NAME, OPER) \
00403     template<> struct by_tag<function_tag::NAME>        \
00404     {                                                   \
00405         template <typename T1>                          \
00406             typename unary_function_traits              \
00407                 <function_tag::NAME, T1>::result_type   \
00408         operator() (T1& x) const                        \
00409         { return x OPER; }                              \
00410     };
00411 
00412 
00413 ARAGELI_FUNCTIONAL_POSTFIX_MODIF_UNARY_GFUNC_BY_TAG(postfix_increment, ++)
00414 ARAGELI_FUNCTIONAL_POSTFIX_MODIF_UNARY_GFUNC_BY_TAG(postfix_decrement, --)
00415 
00416 
00417 #define ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(NAME, OPER)  \
00418     template<> struct by_tag<function_tag::NAME>            \
00419     {                                                       \
00420         template <typename T1, typename T2>                 \
00421             typename binary_function_traits                 \
00422                 <function_tag::NAME, const T1&, const T2&>::result_type \
00423         operator() (const T1& x, const T2& y) const         \
00424         { return x OPER y; }                                \
00425     };
00426 
00427 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(plus, +);
00428 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(minus, -);
00429 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(multiplies, *);
00430 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(divides, /);
00431 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(modulus, %);
00432 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(logical_or, ||);
00433 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(logical_and, &&);
00434 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(equal_to, ==);
00435 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(not_equal_to, !=);
00436 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(greater, >);
00437 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(less, <);
00438 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(greater_equal, >=);
00439 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(less_equal, <=);
00440 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(bitwise_or, |);
00441 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(bitwise_and, &);
00442 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(bitwise_xor, ^);
00443 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(shift_left, <<);
00444 ARAGELI_FUNCTIONAL_BINARY_GFUNC_BY_TAG(shift_right, >>);
00445 
00446 
00447 }
00448 
00449 }
00450 
00451 
00452 //#ifdef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE
00453 //  #define ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_VECTOR
00454 //  #include "vector.cpp"
00455 //  #undef  ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_VECTOR
00456 //#endif
00457 
00458 
00459 #endif  //  #ifndef _ARAGELI_functional_hpp_
00460 

Generated on Thu Aug 31 17:38:05 2006 for Arageli by  doxygen 1.4.7