blitz  Version 0.9
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ops.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  * blitz/ops.h Function objects for math operators
4  *
5  * $Id: ops.h,v 1.7 2004/03/09 21:56:00 julianc Exp $
6  *
7  * Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * Suggestions: blitz-dev@oonumerics.org
20  * Bugs: blitz-bugs@oonumerics.org
21  *
22  * For more information, please see the Blitz++ Home Page:
23  * http://oonumerics.org/blitz/
24  *
25  *************************************************************************/
26 
27 #ifndef BZ_OPS_H
28 #define BZ_OPS_H
29 
30 #include <blitz/blitz.h>
31 #include <blitz/promote.h>
32 #include <blitz/prettyprint.h>
33 
34 BZ_NAMESPACE(blitz)
35 
36 /*
37  * Originally these function objects had no template arguments, e.g.
38  *
39  * struct Add {
40  * template<typename T_numtype1, typename T_numtype2>
41  * static inline BZ_PROMOTE(T_numtype1, T_numtype2)
42  * apply(T_numtype1 a, T_numtype2 b)
43  * { return a + b; }
44  * };
45  *
46  * This made for neater expression templates syntax. However, there are
47  * some situations in which users may want to override type promotion
48  * for certain operations. For example, in theoretical physics, there
49  * are U1 objects which when multiplied yield U1 objects, but when added
50  * yield a different type. To allow for this kind of behaviour, function
51  * objects have been changed to take template parameters:
52  *
53  * template<typename T_numtype1, typename T_numtype2>
54  * struct Add {
55  * typedef BZ_PROMOTE(T_numtype1, T_numtype2) T_numtype;
56  *
57  * static inline T_numtype apply(T_numtype1 a, T_numtype2 b)
58  * { return a + b; }
59  * };
60  *
61  * Type promotion is performed inside the function object. The expression
62  * templates code always looks inside the function object to determine
63  * the type promotion, e.g. Add<int,float>::T_numtype
64  *
65  * Users are free to specialize these function objects for their own types.
66  */
67 
68 /* Unary operators that return same type as argument */
69 
70 #define BZ_DEFINE_UNARY_OP(name,op) \
71 template<typename T_numtype1> \
72 struct name { \
73  typedef T_numtype1 T_numtype; \
74  \
75  static inline T_numtype \
76  apply(T_numtype1 a) \
77  { return op a; } \
78  \
79  template<typename T1> \
80  static inline void prettyPrint(BZ_STD_SCOPE(string) &str, \
81  prettyPrintFormat& format, const T1& t1) \
82  { \
83  str += #op; \
84  t1.prettyPrint(str, format); \
85  } \
86 };
87 
91 
92 
93 /* Unary operators that return a specified type */
94 
95 #define BZ_DEFINE_UNARY_OP_RET(name,op,ret) \
96 template<typename T_numtype1> \
97 struct name { \
98  typedef ret T_numtype; \
99  static inline T_numtype \
100  apply(T_numtype1 a) \
101  { return op a; } \
102  \
103  template<typename T1> \
104  static inline void prettyPrint(BZ_STD_SCOPE(string) &str, \
105  prettyPrintFormat& format, const T1& t1) \
106  { \
107  str += #op; \
108  t1.prettyPrint(str, format); \
109  } \
110 };
111 
113 
114 
115 /* Binary operators that return type based on type promotion */
116 
117 #define BZ_DEFINE_BINARY_OP(name,op) \
118 template<typename T_numtype1, typename T_numtype2> \
119 struct name { \
120  typedef BZ_PROMOTE(T_numtype1, T_numtype2) T_numtype; \
121  \
122  static inline T_numtype \
123  apply(T_numtype1 a, T_numtype2 b) \
124  { return a op b; } \
125  \
126  template<typename T1, typename T2> \
127  static inline void prettyPrint(BZ_STD_SCOPE(string) &str, \
128  prettyPrintFormat& format, const T1& t1, \
129  const T2& t2) \
130  { \
131  str += "("; \
132  t1.prettyPrint(str, format); \
133  str += #op; \
134  t2.prettyPrint(str, format); \
135  str += ")"; \
136  } \
137 };
138 
149 
150 
151 /* Binary operators that return a specified type */
152 
153 #define BZ_DEFINE_BINARY_OP_RET(name,op,ret) \
154 template<typename T_numtype1, typename T_numtype2> \
155 struct name { \
156  typedef ret T_numtype; \
157  static inline T_numtype \
158  apply(T_numtype1 a, T_numtype2 b) \
159  { return a op b; } \
160  \
161  template<typename T1, typename T2> \
162  static inline void prettyPrint(BZ_STD_SCOPE(string) &str, \
163  prettyPrintFormat& format, const T1& t1, \
164  const T2& t2) \
165  { \
166  str += "("; \
167  t1.prettyPrint(str, format); \
168  str += #op; \
169  t2.prettyPrint(str, format); \
170  str += ")"; \
171  } \
172 };
173 
182 
183 
185 
186 #endif // BZ_OPS_H
187 
188