blitz  Version 1.0.2
ops.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  * blitz/ops.h Function objects for math operators
4  *
5  * $Id$
6  *
7  * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org>
8  *
9  * This file is a part of Blitz.
10  *
11  * Blitz is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License
13  * as published by the Free Software Foundation, either version 3
14  * of the License, or (at your option) any later version.
15  *
16  * Blitz is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with Blitz. If not, see <http://www.gnu.org/licenses/>.
23  *
24  * Suggestions: blitz-devel@lists.sourceforge.net
25  * Bugs: blitz-support@lists.sourceforge.net
26  *
27  * For more information, please see the Blitz++ Home Page:
28  * https://sourceforge.net/projects/blitz/
29  *
30  *************************************************************************/
31 
32 #ifndef BZ_OPS_H
33 #define BZ_OPS_H
34 
35 #include <blitz/blitz.h>
36 #include <blitz/promote.h>
37 #include <blitz/prettyprint.h>
38 
39 namespace blitz {
40 
41 /*
42  * Originally these function objects had no template arguments, e.g.
43  *
44  * struct Add {
45  * template<typename T_numtype1, typename T_numtype2>
46  * static inline BZ_PROMOTE(T_numtype1, T_numtype2)
47  * apply(T_numtype1 a, T_numtype2 b)
48  * { return a + b; }
49  * };
50  *
51  * This made for neater expression templates syntax. However, there are
52  * some situations in which users may want to override type promotion
53  * for certain operations. For example, in theoretical physics, there
54  * are U1 objects which when multiplied yield U1 objects, but when added
55  * yield a different type. To allow for this kind of behaviour, function
56  * objects have been changed to take template parameters:
57  *
58  * template<typename T_numtype1, typename T_numtype2>
59  * struct Add {
60  * typedef BZ_PROMOTE(T_numtype1, T_numtype2) T_numtype;
61  *
62  * static inline T_numtype apply(T_numtype1 a, T_numtype2 b)
63  * { return a + b; }
64  * };
65  *
66  * Type promotion is performed inside the function object. The expression
67  * templates code always looks inside the function object to determine
68  * the type promotion, e.g. Add<int,float>::T_numtype
69  *
70  * Users are free to specialize these function objects for their own types.
71  */
72 
73 /* Unary operators that return same type as argument */
74 
75 #define BZ_DEFINE_UNARY_OP(name,op) \
76 template<typename T_numtype1> \
77 struct name { \
78  typedef T_numtype1 T_numtype; \
79  \
80  static inline T_numtype \
81  apply(T_numtype1 a) \
82  { return op a; } \
83  \
84  template<typename T1> \
85  static inline void prettyPrint(std::string &str, \
86  prettyPrintFormat& format, const T1& t1) \
87  { \
88  str += #op; \
89  t1.prettyPrint(str, format); \
90  } \
91 };
92 
96 
97 
98 /* Unary operators that return a specified type */
99 
100 #define BZ_DEFINE_UNARY_OP_RET(name,op,ret) \
101 template<typename T_numtype1> \
102 struct name { \
103  typedef ret T_numtype; \
104  static inline T_numtype \
105  apply(T_numtype1 a) \
106  { return op a; } \
107  \
108  template<typename T1> \
109  static inline void prettyPrint(std::string &str, \
110  prettyPrintFormat& format, const T1& t1) \
111  { \
112  str += #op; \
113  t1.prettyPrint(str, format); \
114  } \
115 };
116 
118 
119 
120 /* Binary operators that return type based on type promotion */
121 
122 #define BZ_DEFINE_BINARY_OP(name,op) \
123 template<typename T_numtype1, typename T_numtype2> \
124 struct name { \
125  typedef BZ_PROMOTE(T_numtype1, T_numtype2) T_numtype; \
126  \
127  static inline T_numtype \
128  apply(T_numtype1 a, T_numtype2 b) \
129  { return a op b; } \
130  \
131  template<typename T1, typename T2> \
132  static inline void prettyPrint(std::string &str, \
133  prettyPrintFormat& format, const T1& t1, \
134  const T2& t2) \
135  { \
136  str += "("; \
137  t1.prettyPrint(str, format); \
138  str += #op; \
139  t2.prettyPrint(str, format); \
140  str += ")"; \
141  } \
142 };
143 
154 
155 
156 /* Binary operators that return a specified type */
157 
158 #define BZ_DEFINE_BINARY_OP_RET(name,op,ret) \
159 template<typename T_numtype1, typename T_numtype2> \
160 struct name { \
161  typedef ret T_numtype; \
162  static inline T_numtype \
163  apply(T_numtype1 a, T_numtype2 b) \
164  { return a op b; } \
165  \
166  template<typename T1, typename T2> \
167  static inline void prettyPrint(std::string &str, \
168  prettyPrintFormat& format, const T1& t1, \
169  const T2& t2) \
170  { \
171  str += "("; \
172  t1.prettyPrint(str, format); \
173  str += #op; \
174  t2.prettyPrint(str, format); \
175  str += ")"; \
176  } \
177 };
178 
187 
188 /* already defined in funcs
189 // We define these explicitly since they don't fit a pattern
190 template<typename P_numtype1, typename P_numtype2>
191 struct Min {
192 public:
193  typedef P_numtype1 T_numtype1;
194  typedef P_numtype2 T_numtype2;
195  typedef bool T_numtype;
196 
197  static inline T_numtype apply(T_numtype1 x, T_numtype2 y)
198  { return (x < y ? x : y); }
199 };
200 
201 template<typename P_numtype1, typename P_numtype2>
202 class Max {
203 public:
204  typedef P_numtype1 T_numtype1;
205  typedef P_numtype2 T_numtype2;
206  typedef bool T_numtype;
207 
208  static inline T_numtype apply(T_numtype1 x, T_numtype2 y)
209  { return (x > y ? x : y); }
210 };
211 */
212 
213 
214 }
215 
216 #endif // BZ_OPS_H
217 
218 
Definition: ops.h:149
#define BZ_DEFINE_BINARY_OP(name, op)
Definition: ops.h:122
Definition: ops.h:185
Definition: ops.h:182
Definition: ops.h:153
Definition: ops.h:117
Definition: ops.h:150
Definition: ops.h:147
Definition: ops.h:183
Definition: ops.h:181
#define BZ_DEFINE_UNARY_OP(name, op)
Definition: ops.h:75
Definition: ops.h:93
Definition: ops.h:151
Definition: ops.h:152
Definition: ops.h:94
Definition: ops.h:146
Definition: array-impl.h:66
Definition: ops.h:179
#define BZ_DEFINE_UNARY_OP_RET(name, op, ret)
Definition: ops.h:100
Definition: ops.h:95
Definition: ops.h:184
Definition: ops.h:145
Definition: ops.h:180
Definition: ops.h:148
Definition: ops.h:144
Definition: ops.h:186
#define BZ_DEFINE_BINARY_OP_RET(name, op, ret)
Definition: ops.h:158