@@ -65,6 +65,112 @@ 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, typename T_expr2, int NV, int RA>
74+ struct TypeSwitch <TinyVector<T_expr1, NV>, Array<TinyVector<T_expr2, NV>, RA> > {
75+ typedef Array<TinyVector<T_expr2, NV>, RA> Type;
76+ };
77+
78+ template <typename T_expr1, typename T_expr2, int NV, int RA>
79+ struct TypeSwitch <Array<TinyVector<T_expr1, NV>, RA>, TinyVector<T_expr2, NV> > {
80+ typedef Array<TinyVector<T_expr1, NV>, RA> Type;
81+ };
82+
83+ template <typename T_expr1, typename T_expr2, int N1, int N2>
84+ struct TypeSwitch <TinyVector<T_expr1, N1>, TinyVector<T_expr2, N2> > {
85+ typedef void Type;
86+ };
87+
88+ template <typename T_expr1, typename T_expr2, int NV>
89+ struct TypeSwitch <TinyVector<T_expr1, NV>, TinyVector<T_expr2, NV> > {
90+ typedef TinyVector<T_expr1, NV> Type;
91+ };
92+
93+ template <typename T_expr1, typename T_expr2, int NV>
94+ struct TypeSwitch <Array<T_expr1, NV>, Array<T_expr2, NV> > {
95+ typedef Array<T_expr2, NV> Type;
96+ };
97+
98+ template <typename T_expr1, typename T_expr2, int NV>
99+ struct TypeSwitch <T_expr1, TinyVector<T_expr2, NV> > {
100+ typedef TinyVector<T_expr2, NV> Type;
101+ };
102+
103+ template <typename T_expr1, typename T_expr2, int NV>
104+ struct TypeSwitch <TinyVector<T_expr1, NV>, T_expr2> {
105+ typedef TinyVector<T_expr1, NV> Type;
106+ };
107+
108+ template <typename T_expr1, typename T_expr2, int RA>
109+ struct TypeSwitch <Array<T_expr1, RA>, T_expr2> {
110+ typedef Array<T_expr1, RA> Type;
111+ };
112+
113+ template <typename T_expr1, typename T_expr2, int RA>
114+ struct TypeSwitch <T_expr1, Array<T_expr2, RA> > {
115+ typedef Array<T_expr2, RA> Type;
116+ };
117+
118+ // NOTE: These template structures define final type of an array expression
119+
120+ template <typename T_expr> struct TypeInfo { typedef T_expr Type; };
121+
122+ template <typename T_expr, int N>
123+ struct TypeInfo <FastTV2CopyIterator<T_expr, N> > {
124+ typedef typename FastTV2CopyIterator<T_expr, N>::T_vector Type;
125+ };
126+
127+ template <typename T_expr, int N>
128+ struct TypeInfo <FastTV2Iterator<T_expr, N> > {
129+ typedef typename FastTV2Iterator<T_expr, N>::T_vector Type;
130+ };
131+
132+ template <typename T_expr, int N>
133+ struct TypeInfo <FastArrayCopyIterator<T_expr, N> > {
134+ typedef typename FastArrayCopyIterator<T_expr, N>::T_array Type;
135+ };
136+
137+ template <typename T_expr, int N>
138+ struct TypeInfo <FastArrayIterator<T_expr, N> > {
139+ typedef typename FastArrayIterator<T_expr, N>::T_array Type;
140+ };
141+
142+ template <typename T_expr1, typename T_expr2, typename OP>
143+ struct TypeInfo <_bz_ArrayExprBinaryOp<T_expr1, T_expr2, OP> > {
144+ typedef typename TypeSwitch<
145+ typename TypeInfo<T_expr1>::Type,
146+ typename TypeInfo<T_expr2>::Type
147+ >::Type Type;
148+ };
149+
150+ template <typename T_expr, typename OP>
151+ struct TypeInfo <_bz_ArrayExprUnaryOp<T_expr, OP> > {
152+ typedef
153+ typename TypeInfo<T_expr>::Type
154+ Type;
155+ };
156+
157+ template <typename T_expr>
158+ struct TypeInfo <_bz_ArrayExprConstant<T_expr> > {
159+ typedef
160+ typename TypeInfo<T_expr>::Type
161+ Type;
162+ };
163+
164+ template <typename T_expr>
165+ struct TypeInfo <_bz_ArrayExpr<T_expr> > {
166+ typedef
167+ typename TypeInfo<T_expr>::Type
168+ Type;
169+ };
170+
171+ // ...
172+
173+
68174template <typename T1, typename T2>
69175class _bz_ExprPair {
70176public:
@@ -108,6 +214,7 @@ class _bz_ArrayExpr
108214{
109215
110216public:
217+ typedef typename TypeInfo<_bz_ArrayExpr<P_expr> >::Type T_type;
111218 typedef P_expr T_expr;
112219 typedef _bz_typename T_expr::T_numtype T_numtype;
113220 // select return type
@@ -500,6 +607,7 @@ class _bz_ArrayExpr
500607template <typename P_expr, typename P_op>
501608class _bz_ArrayExprUnaryOp {
502609public:
610+ typedef typename TypeInfo<_bz_ArrayExprUnaryOp<P_expr, P_op> >::Type T_type;
503611 typedef P_expr T_expr;
504612 typedef P_op T_op;
505613 typedef _bz_typename T_expr::T_numtype T_numtype1;
@@ -775,6 +883,7 @@ class _bz_ArrayExprUnaryOp {
775883template <typename P_expr1, typename P_expr2, typename P_op>
776884class _bz_ArrayExprBinaryOp {
777885public:
886+ typedef typename TypeInfo<_bz_ArrayExprBinaryOp<P_expr1, P_expr2, P_op> >::Type T_type;
778887 typedef P_expr1 T_expr1;
779888 typedef P_expr2 T_expr2;
780889 typedef P_op T_op;
@@ -1976,14 +2085,15 @@ class _bz_ArrayExprQuaternaryOp {
19762085template <typename P_numtype>
19772086class _bz_ArrayExprConstant {
19782087public:
2088+ typedef typename TypeInfo<_bz_ArrayExprConstant<P_numtype> >::Type T_type;
19792089 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;
2090+ typedef typename opType<T_numtype>::T_optype T_optype;
2091+ typedef typename asET<T_numtype>::T_wrapped T_typeprop;
2092+ typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
19832093
19842094 typedef T_numtype T_ctorArg1;
19852095 typedef int T_ctorArg2; // dummy
1986- typedef _bz_ArrayExprConstant<P_numtype> T_range_result;
2096+ typedef _bz_ArrayExprConstant<P_numtype> T_range_result;
19872097 static const int
19882098 numArrayOperands = 0 ,
19892099 numTVOperands = 0 ,
@@ -1996,7 +2106,7 @@ class _bz_ArrayExprConstant {
19962106 /* * For the purpose of vectorizing across the container (as opposed
19972107 to for operating on multicomponent types), a constant is always
19982108 a constant. */
1999- template <int N> struct tvresult {
2109+ template <int N> struct tvresult {
20002110 typedef _bz_ArrayExprConstant<T_numtype> Type;
20012111 };
20022112
0 commit comments