blitz/ops.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  * blitz/ops.h           Function objects for math operators
00004  *
00005  * $Id: ops.h,v 1.7 2004/03/09 21:56:00 julianc Exp $
00006  *
00007  * Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org>
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU General Public License
00011  * as published by the Free Software Foundation; either version 2
00012  * of the License, or (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * Suggestions:          blitz-dev@oonumerics.org
00020  * Bugs:                 blitz-bugs@oonumerics.org
00021  *
00022  * For more information, please see the Blitz++ Home Page:
00023  *    http://oonumerics.org/blitz/
00024  *
00025  *************************************************************************/
00026 
00027 #ifndef BZ_OPS_H
00028 #define BZ_OPS_H
00029 
00030 #include <blitz/blitz.h>
00031 #include <blitz/promote.h>
00032 #include <blitz/prettyprint.h>
00033 
00034 BZ_NAMESPACE(blitz)
00035 
00036 /*
00037  * Originally these function objects had no template arguments, e.g.
00038  *
00039  * struct Add {
00040  *     template<typename T_numtype1, typename T_numtype2>
00041  *     static inline BZ_PROMOTE(T_numtype1, T_numtype2)
00042  *     apply(T_numtype1 a, T_numtype2 b)
00043  *     { return a + b; }
00044  * };
00045  *
00046  * This made for neater expression templates syntax.  However, there are
00047  * some situations in which users may want to override type promotion
00048  * for certain operations.  For example, in theoretical physics, there
00049  * are U1 objects which when multiplied yield U1 objects, but when added
00050  * yield a different type.  To allow for this kind of behaviour, function
00051  * objects have been changed to take template parameters:
00052  *
00053  * template<typename T_numtype1, typename T_numtype2>
00054  * struct Add {
00055  *     typedef BZ_PROMOTE(T_numtype1, T_numtype2) T_numtype;
00056  *
00057  *     static inline T_numtype apply(T_numtype1 a, T_numtype2 b)
00058  *     { return a + b; }
00059  * };
00060  *
00061  * Type promotion is performed inside the function object.  The expression
00062  * templates code always looks inside the function object to determine
00063  * the type promotion, e.g. Add<int,float>::T_numtype
00064  *
00065  * Users are free to specialize these function objects for their own types.
00066  */
00067     
00068 /* Unary operators that return same type as argument */
00069     
00070 #define BZ_DEFINE_UNARY_OP(name,op)                            \
00071 template<typename T_numtype1>                                  \
00072 struct name {                                                  \
00073     typedef T_numtype1 T_numtype;                              \
00074                                                                \
00075     static inline T_numtype                                    \
00076     apply(T_numtype1 a)                                        \
00077     { return op a; }                                           \
00078                      \
00079     template<typename T1>                                      \
00080     static inline void prettyPrint(BZ_STD_SCOPE(string) &str,  \
00081         prettyPrintFormat& format, const T1& t1)               \
00082     {                                                          \
00083         str += #op;                                            \
00084         t1.prettyPrint(str, format);                           \
00085     }                                                          \
00086 };
00087 
00088 BZ_DEFINE_UNARY_OP(BitwiseNot,~)
00089 BZ_DEFINE_UNARY_OP(UnaryPlus,+)
00090 BZ_DEFINE_UNARY_OP(UnaryMinus,-)
00091     
00092     
00093 /* Unary operators that return a specified type */
00094     
00095 #define BZ_DEFINE_UNARY_OP_RET(name,op,ret)                    \
00096 template<typename T_numtype1>                                  \
00097 struct name {                                                  \
00098     typedef ret T_numtype;                                     \
00099     static inline T_numtype                                    \
00100     apply(T_numtype1 a)                                        \
00101     { return op a; }                                           \
00102                                                                \
00103     template<typename T1>                                      \
00104     static inline void prettyPrint(BZ_STD_SCOPE(string) &str,  \
00105         prettyPrintFormat& format, const T1& t1)               \
00106     {                                                          \
00107         str += #op;                                            \
00108         t1.prettyPrint(str, format);                           \
00109     }                                                          \
00110 };
00111 
00112 BZ_DEFINE_UNARY_OP_RET(LogicalNot,!,bool)
00113     
00114     
00115 /* Binary operators that return type based on type promotion */
00116     
00117 #define BZ_DEFINE_BINARY_OP(name,op)                              \
00118 template<typename T_numtype1, typename T_numtype2>                \
00119 struct name {                                                     \
00120     typedef BZ_PROMOTE(T_numtype1, T_numtype2) T_numtype;         \
00121                                                                   \
00122     static inline T_numtype                                       \
00123     apply(T_numtype1 a, T_numtype2 b)                             \
00124     { return a op b; }                                            \
00125                         \
00126     template<typename T1, typename T2>                            \
00127     static inline void prettyPrint(BZ_STD_SCOPE(string) &str,     \
00128         prettyPrintFormat& format, const T1& t1,                  \
00129         const T2& t2)                                             \
00130     {                                                             \
00131         str += "(";                                               \
00132         t1.prettyPrint(str, format);                              \
00133         str += #op;                                               \
00134         t2.prettyPrint(str, format);                              \
00135         str += ")";                                               \
00136     }                                                             \
00137 };
00138 
00139 BZ_DEFINE_BINARY_OP(Add,+)
00140 BZ_DEFINE_BINARY_OP(Subtract,-)
00141 BZ_DEFINE_BINARY_OP(Multiply,*)
00142 BZ_DEFINE_BINARY_OP(Divide,/)
00143 BZ_DEFINE_BINARY_OP(Modulo,%)
00144 BZ_DEFINE_BINARY_OP(BitwiseXor,^)
00145 BZ_DEFINE_BINARY_OP(BitwiseAnd,&)
00146 BZ_DEFINE_BINARY_OP(BitwiseOr,|)
00147 BZ_DEFINE_BINARY_OP(ShiftRight,>>)
00148 BZ_DEFINE_BINARY_OP(ShiftLeft,<<)
00149     
00150     
00151 /* Binary operators that return a specified type */
00152     
00153 #define BZ_DEFINE_BINARY_OP_RET(name,op,ret)                      \
00154 template<typename T_numtype1, typename T_numtype2>                \
00155 struct name {                                                     \
00156     typedef ret T_numtype;                                        \
00157     static inline T_numtype                                       \
00158     apply(T_numtype1 a, T_numtype2 b)                             \
00159     { return a op b; }                                            \
00160                                                                   \
00161     template<typename T1, typename T2>                            \
00162     static inline void prettyPrint(BZ_STD_SCOPE(string) &str,     \
00163         prettyPrintFormat& format, const T1& t1,                  \
00164         const T2& t2)                                             \
00165     {                                                             \
00166         str += "(";                                               \
00167         t1.prettyPrint(str, format);                              \
00168         str += #op;                                               \
00169         t2.prettyPrint(str, format);                              \
00170         str += ")";                                               \
00171     }                                                             \
00172 };
00173 
00174 BZ_DEFINE_BINARY_OP_RET(Greater,>,bool)
00175 BZ_DEFINE_BINARY_OP_RET(Less,<,bool)
00176 BZ_DEFINE_BINARY_OP_RET(GreaterOrEqual,>=,bool)
00177 BZ_DEFINE_BINARY_OP_RET(LessOrEqual,<=,bool)
00178 BZ_DEFINE_BINARY_OP_RET(Equal,==,bool)
00179 BZ_DEFINE_BINARY_OP_RET(NotEqual,!=,bool)
00180 BZ_DEFINE_BINARY_OP_RET(LogicalAnd,&&,bool)
00181 BZ_DEFINE_BINARY_OP_RET(LogicalOr,||,bool)
00182     
00183     
00184 BZ_NAMESPACE_END
00185 
00186 #endif // BZ_OPS_H
00187 
00188 

Generated on Wed Oct 17 17:20:04 2007 for blitz by  doxygen 1.5.2