@@ -65,6 +65,107 @@ BZ_NAMESPACE(blitz)
6565#define BZ_MAX (a,b ) (a)>(b) ? (a) : (b)
6666#define BZ_MIN (a,b ) (a)<(b) ? (a) : (b)
6767
68+ // NOTE: These template structures make to choose type of result binary operation between left and right side
69+ // TODO: It's necessary to consider the cases of expressions with ArrayIndexMapping and/or IndexPlaceholder
70+
71+ template <typename T_expr1, typename T_expr2> struct TypeSwitch { typedef void Type; };
72+
73+ template <typename T_expr1, int N1, typename T_expr2, int N2>
74+ struct TypeSwitch <TinyVector<T_expr1, N1>, TinyVector<T_expr2, N2> > {
75+ typedef TinyVector<T_expr2, N2> Type;
76+ };
77+
78+ template <typename T_expr1, int N1, typename T_expr2, int N2>
79+ struct TypeSwitch <TinyVector<T_expr1, N1>, Array<T_expr2, N2> > {
80+ typedef Array<T_expr2, N2> Type;
81+ };
82+
83+ template <typename T_expr1, int N1, typename T_expr2, int N2>
84+ struct TypeSwitch <Array<T_expr1, N1>, TinyVector<T_expr2, N2> > {
85+ typedef Array<T_expr2, N2> Type;
86+ };
87+
88+ template <typename T_expr1, int N1, typename T_expr2, int N2>
89+ struct TypeSwitch <Array<T_expr1, N1>, Array<T_expr2, N2> > {
90+ typedef Array<T_expr2, (N1 > N2)? N1: N2> Type;
91+ };
92+
93+ template <typename T_expr1, typename T_expr2, int N2>
94+ struct TypeSwitch <T_expr1, TinyVector<T_expr2, N2> > {
95+ typedef TinyVector<T_expr2, N2> Type;
96+ };
97+
98+ template <typename T_expr1, int N1, typename T_expr2>
99+ struct TypeSwitch <TinyVector<T_expr1, N1>, T_expr2> {
100+ typedef TinyVector<T_expr1, N1> Type;
101+ };
102+
103+ template <typename T_expr1, int N1, typename T_expr2>
104+ struct TypeSwitch <Array<T_expr1, N1>, T_expr2> {
105+ typedef Array<T_expr1, N1> Type;
106+ };
107+
108+ template <typename T_expr1, typename T_expr2, int N2>
109+ struct TypeSwitch <T_expr1, Array<T_expr2, N2> > {
110+ typedef Array<T_expr2, N2> Type;
111+ };
112+
113+ // NOTE: These template structures define final type of an array expression
114+
115+ template <typename T_expr> struct TypeInfo { typedef T_expr Type; };
116+
117+ template <typename T_expr, int N>
118+ struct TypeInfo <FastTV2CopyIterator<T_expr, N> > {
119+ typedef typename FastTV2CopyIterator<T_expr, N>::T_vector Type;
120+ };
121+
122+ template <typename T_expr, int N>
123+ struct TypeInfo <FastTV2Iterator<T_expr, N> > {
124+ typedef typename FastTV2Iterator<T_expr, N>::T_vector Type;
125+ };
126+
127+ template <typename T_expr, int N>
128+ struct TypeInfo <FastArrayCopyIterator<T_expr, N> > {
129+ typedef typename FastArrayCopyIterator<T_expr, N>::T_array Type;
130+ };
131+
132+ template <typename T_expr, int N>
133+ struct TypeInfo <FastArrayIterator<T_expr, N> > {
134+ typedef typename FastArrayIterator<T_expr, N>::T_array Type;
135+ };
136+
137+ template <typename T_expr1, typename T_expr2, typename OP>
138+ struct TypeInfo <_bz_ArrayExprBinaryOp<T_expr1, T_expr2, OP> > {
139+ typedef typename TypeSwitch<
140+ typename TypeInfo<T_expr1>::Type,
141+ typename TypeInfo<T_expr2>::Type
142+ >::Type Type;
143+ };
144+
145+ template <typename T_expr, typename OP>
146+ struct TypeInfo <_bz_ArrayExprUnaryOp<T_expr, OP> > {
147+ typedef
148+ typename TypeInfo<T_expr>::Type
149+ Type;
150+ };
151+
152+ template <typename T_expr>
153+ struct TypeInfo <_bz_ArrayExprConstant<T_expr> > {
154+ typedef
155+ typename TypeInfo<T_expr>::Type
156+ Type;
157+ };
158+
159+ template <typename T_expr>
160+ struct TypeInfo <_bz_ArrayExpr<T_expr> > {
161+ typedef
162+ typename TypeInfo<T_expr>::Type
163+ Type;
164+ };
165+
166+ // ...
167+
168+
68169template <typename T1, typename T2>
69170class _bz_ExprPair {
70171public:
@@ -108,6 +209,7 @@ class _bz_ArrayExpr
108209{
109210
110211public:
212+ typedef typename TypeInfo<_bz_ArrayExpr<P_expr> >::Type T_type;
111213 typedef P_expr T_expr;
112214 typedef _bz_typename T_expr::T_numtype T_numtype;
113215 // select return type
@@ -500,6 +602,7 @@ class _bz_ArrayExpr
500602template <typename P_expr, typename P_op>
501603class _bz_ArrayExprUnaryOp {
502604public:
605+ typedef typename TypeInfo<_bz_ArrayExprUnaryOp<P_expr, P_op> >::Type T_type;
503606 typedef P_expr T_expr;
504607 typedef P_op T_op;
505608 typedef _bz_typename T_expr::T_numtype T_numtype1;
@@ -775,6 +878,7 @@ class _bz_ArrayExprUnaryOp {
775878template <typename P_expr1, typename P_expr2, typename P_op>
776879class _bz_ArrayExprBinaryOp {
777880public:
881+ typedef typename TypeInfo<_bz_ArrayExprBinaryOp<P_expr1, P_expr2, P_op> >::Type T_type;
778882 typedef P_expr1 T_expr1;
779883 typedef P_expr2 T_expr2;
780884 typedef P_op T_op;
@@ -1976,14 +2080,15 @@ class _bz_ArrayExprQuaternaryOp {
19762080template <typename P_numtype>
19772081class _bz_ArrayExprConstant {
19782082public:
2083+ typedef typename TypeInfo<_bz_ArrayExprConstant<P_numtype> >::Type T_type;
19792084 typedef P_numtype T_numtype;
1980- typedef typename opType<T_numtype>::T_optype T_optype;
1981- typedef typename asET<T_numtype>::T_wrapped T_typeprop;
1982- typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
2085+ typedef typename opType<T_numtype>::T_optype T_optype;
2086+ typedef typename asET<T_numtype>::T_wrapped T_typeprop;
2087+ typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
19832088
19842089 typedef T_numtype T_ctorArg1;
19852090 typedef int T_ctorArg2; // dummy
1986- typedef _bz_ArrayExprConstant<P_numtype> T_range_result;
2091+ typedef _bz_ArrayExprConstant<P_numtype> T_range_result;
19872092 static const int
19882093 numArrayOperands = 0 ,
19892094 numTVOperands = 0 ,
@@ -1996,7 +2101,7 @@ class _bz_ArrayExprConstant {
19962101 /* * For the purpose of vectorizing across the container (as opposed
19972102 to for operating on multicomponent types), a constant is always
19982103 a constant. */
1999- template <int N> struct tvresult {
2104+ template <int N> struct tvresult {
20002105 typedef _bz_ArrayExprConstant<T_numtype> Type;
20012106 };
20022107
0 commit comments