source: XIOS/dev/dev_olga/src/extern/blitz/include/blitz/ops.h @ 1022

Last change on this file since 1022 was 1022, checked in by mhnguyen, 7 years ago
File size: 8.7 KB
Line 
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
39BZ_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)                            \
76template<typename T_numtype1>                                  \
77struct 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(BZ_STD_SCOPE(string) &str,  \
86        prettyPrintFormat& format, const T1& t1)               \
87    {                                                          \
88        str += #op;                                            \
89        t1.prettyPrint(str, format);                           \
90    }                                                          \
91};
92
93BZ_DEFINE_UNARY_OP(BitwiseNot,~)
94BZ_DEFINE_UNARY_OP(UnaryPlus,+)
95BZ_DEFINE_UNARY_OP(UnaryMinus,-) 
96
97   
98/* Unary operators that return a specified type */
99   
100#define BZ_DEFINE_UNARY_OP_RET(name,op,ret)                    \
101template<typename T_numtype1>                                  \
102struct 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(BZ_STD_SCOPE(string) &str,  \
110        prettyPrintFormat& format, const T1& t1)               \
111    {                                                          \
112        str += #op;                                            \
113        t1.prettyPrint(str, format);                           \
114    }                                                          \
115};
116
117BZ_DEFINE_UNARY_OP_RET(LogicalNot,!,bool)
118   
119   
120/* Binary operators that return type based on type promotion */
121   
122#define BZ_DEFINE_BINARY_OP(name,op)                              \
123template<typename T_numtype1, typename T_numtype2>                \
124struct 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(BZ_STD_SCOPE(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
144BZ_DEFINE_BINARY_OP(Add,+)
145BZ_DEFINE_BINARY_OP(Subtract,-)
146BZ_DEFINE_BINARY_OP(Multiply,*)
147BZ_DEFINE_BINARY_OP(Divide,/)
148BZ_DEFINE_BINARY_OP(Modulo,%)
149BZ_DEFINE_BINARY_OP(BitwiseXor,^)
150BZ_DEFINE_BINARY_OP(BitwiseAnd,&)
151BZ_DEFINE_BINARY_OP(BitwiseOr,|)
152BZ_DEFINE_BINARY_OP(ShiftRight,>>)
153BZ_DEFINE_BINARY_OP(ShiftLeft,<<)
154   
155   
156/* Binary operators that return a specified type */
157   
158#define BZ_DEFINE_BINARY_OP_RET(name,op,ret)                      \
159template<typename T_numtype1, typename T_numtype2>                \
160struct 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(BZ_STD_SCOPE(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
179BZ_DEFINE_BINARY_OP_RET(Greater,>,bool)
180BZ_DEFINE_BINARY_OP_RET(Less,<,bool)
181BZ_DEFINE_BINARY_OP_RET(GreaterOrEqual,>=,bool)
182BZ_DEFINE_BINARY_OP_RET(LessOrEqual,<=,bool)
183BZ_DEFINE_BINARY_OP_RET(Equal,==,bool)
184BZ_DEFINE_BINARY_OP_RET(NotEqual,!=,bool)
185BZ_DEFINE_BINARY_OP_RET(LogicalAnd,&&,bool)
186BZ_DEFINE_BINARY_OP_RET(LogicalOr,||,bool)
187   
188/* already defined in funcs
189// We define these explicitly since they don't fit a pattern
190template<typename P_numtype1, typename P_numtype2>
191struct Min {
192public:
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
201template<typename P_numtype1, typename P_numtype2>
202class Max {
203public:
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
214BZ_NAMESPACE_END
215
216#endif // BZ_OPS_H
217
218
Note: See TracBrowser for help on using the repository browser.