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