]> Dogcows Code - chaz/yoink/blob - src/Moof/cml/et/scalar_ops.h
bugfix: win32 packaging script temp directories
[chaz/yoink] / src / Moof / cml / et / scalar_ops.h
1 /* -*- C++ -*- ------------------------------------------------------------
2
3 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
4
5 The Configurable Math Library (CML) is distributed under the terms of the
6 Boost Software License, v1.0 (see cml/LICENSE for details).
7
8 *-----------------------------------------------------------------------*/
9 /** @file
10 * @brief
11 */
12
13 #ifndef ops_h
14 #define ops_h
15
16 #include <cml/et/traits.h>
17 #include <cml/et/scalar_promotions.h>
18
19 /** Declare a unary scalar operator, like negation. */
20 #define CML_UNARY_SCALAR_OP(_op_, _op_name_) \
21 template<typename ArgT> struct _op_name_ { \
22 typedef ExprTraits<ArgT> arg_traits; \
23 typedef typename arg_traits::const_reference arg_reference; \
24 typedef typename arg_traits::value_type value_type; \
25 typedef scalar_result_tag result_tag; \
26 value_type apply(arg_reference arg) const { return _op_ arg; } \
27 };
28
29 /** Declare a binary scalar operator, like addition, s1+s2. */
30 #define CML_BINARY_SCALAR_OP(_op_, _op_name_) \
31 template<typename LeftT, typename RightT> struct _op_name_ { \
32 typedef ExprTraits<LeftT> left_traits; \
33 typedef ExprTraits<RightT> right_traits; \
34 typedef typename left_traits::const_reference left_reference; \
35 typedef typename right_traits::const_reference right_reference; \
36 typedef typename left_traits::value_type left_value; \
37 typedef typename right_traits::value_type right_value; \
38 typedef typename ScalarPromote<left_value,right_value>::type value_type; \
39 typedef scalar_result_tag result_tag; \
40 value_type apply(left_reference left, right_reference right) const { \
41 return left _op_ right; } \
42 };
43
44 /** Declare an op-assignment operator.
45 *
46 * @note The ExprTraits for both argument types must be defined, LeftT must
47 * have an assignment operator, and ExprTraits<LeftT>::reference must specify
48 * a type that allows assignment.
49 */
50 #define CML_BINARY_SCALAR_OP_ASSIGN(_op_, _op_name_) \
51 template<typename LeftT, typename RightT> struct _op_name_ { \
52 typedef ExprTraits<LeftT> left_traits; \
53 typedef ExprTraits<RightT> right_traits; \
54 typedef typename left_traits::reference left_reference; \
55 typedef typename right_traits::const_reference right_reference; \
56 typedef typename left_traits::value_type left_value; \
57 typedef typename right_traits::value_type right_value; \
58 typedef typename ScalarPromote<left_value,right_value>::type value_type; \
59 typedef scalar_result_tag result_tag; \
60 value_type apply(left_reference left, right_reference right) const { \
61 return left _op_ (LeftT) right; } \
62 };
63
64 /** Declare a binary boolean operator, like less-than, s1 < s2.
65 *
66 * The operator should return the appropriate truth value for the operator.
67 *
68 * @note Both scalar types must have operator<() defined.
69 */
70 #define CML_BOOLEAN_SCALAR_OP(_op_, _op_name_) \
71 template<typename LeftT, typename RightT> struct _op_name_ { \
72 typedef ExprTraits<LeftT> left_traits; \
73 typedef ExprTraits<RightT> right_traits; \
74 typedef typename left_traits::const_reference left_reference; \
75 typedef typename right_traits::const_reference right_reference; \
76 typedef scalar_result_tag result_tag; \
77 bool apply(left_reference left, right_reference right) const { \
78 return left _op_ right; } \
79 };
80
81 namespace cml {
82 namespace et {
83
84 /* Define the operators: */
85
86 /* Unary scalar ops: */
87 CML_UNARY_SCALAR_OP(-, OpNeg)
88 CML_UNARY_SCALAR_OP(+, OpPos)
89
90 /* Binary scalar ops: */
91 CML_BINARY_SCALAR_OP(+, OpAdd)
92 CML_BINARY_SCALAR_OP(-, OpSub)
93 CML_BINARY_SCALAR_OP(*, OpMul)
94
95 #if defined(CML_RECIPROCAL_OPTIMIZATION)
96 /* XXX Yikes... this should really be written out in full. *= 1./ is the
97 * "_op_" parameter to the macro (see above):
98 */
99 CML_BINARY_SCALAR_OP(* value_type(1)/, OpDiv)
100 #else
101 CML_BINARY_SCALAR_OP(/, OpDiv)
102 #endif
103
104 /* Binary scalar op-assigns: */
105 CML_BINARY_SCALAR_OP_ASSIGN( =, OpAssign)
106 CML_BINARY_SCALAR_OP_ASSIGN(+=, OpAddAssign)
107 CML_BINARY_SCALAR_OP_ASSIGN(-=, OpSubAssign)
108 CML_BINARY_SCALAR_OP_ASSIGN(*=, OpMulAssign)
109
110 #if defined(CML_RECIPROCAL_OPTIMIZATION)
111 /* XXX Yikes... this should really be written out in full. *= 1./ is the
112 * "_op_" parameter to the macro (see above):
113 */
114 CML_BINARY_SCALAR_OP_ASSIGN(*= value_type(1)/, OpDivAssign)
115 #else
116 CML_BINARY_SCALAR_OP_ASSIGN(/=, OpDivAssign)
117 #endif
118
119 /* Boolean operators for scalars: */
120 CML_BOOLEAN_SCALAR_OP(==, OpEqual)
121 CML_BOOLEAN_SCALAR_OP(!=, OpNotEqual)
122 CML_BOOLEAN_SCALAR_OP( <, OpLess)
123 CML_BOOLEAN_SCALAR_OP( >, OpGreater)
124 CML_BOOLEAN_SCALAR_OP(<=, OpLessEqual)
125 CML_BOOLEAN_SCALAR_OP(>=, OpGreaterEqual)
126
127 #undef CML_UNARY_SCALAR_OP
128 #undef CML_BINARY_SCALAR_OP
129 #undef CML_BINARY_SCALAR_OP_ASSIGN
130 #undef CML_BOOLEAN_SCALAR_OP
131
132 } // namespace et
133 } // namespace cml
134
135 #endif
136
137 // -------------------------------------------------------------------------
138 // vim:ft=cpp
This page took 0.042121 seconds and 4 git commands to generate.