Skip to content

Commit bf348ed

Browse files
committed
Fixing assignment between Array<TinyVector> and TinyVector expression
Add checking for conversion of a right side to Array::T_numtype (C++11 is used)
1 parent 49b2ec7 commit bf348ed

5 files changed

Lines changed: 142 additions & 18 deletions

File tree

blitz/array-impl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
#include <boost/serialization/base_object.hpp>
6363
#endif
6464

65+
#include <type_traits>
6566

6667
BZ_NAMESPACE(blitz)
6768

@@ -2268,6 +2269,13 @@ class Array : public MemoryBlockReference<P_numtype>
22682269
isStorageContiguous when operator, is used. \todo We should do
22692270
bounds checking, right now we will buffer overrun if the number
22702271
of initializers in the list is larger than numElements. */
2272+
template <typename T_expr, typename = typename std::enable_if<std::is_convertible<
2273+
typename T_expr::T_type, T_numtype>::value>::type>
2274+
ListInitializationSwitch<T_array> operator=(const T_expr &expr)
2275+
{
2276+
return ListInitializationSwitch<T_array>(*this, T_numtype(expr));
2277+
}
2278+
22712279
ListInitializationSwitch<T_array> operator=(T_numtype x)
22722280
{
22732281
return ListInitializationSwitch<T_array>(*this, x);

blitz/array/expr.h

Lines changed: 115 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
68174
template<typename T1, typename T2>
69175
class _bz_ExprPair {
70176
public:
@@ -108,6 +214,7 @@ class _bz_ArrayExpr
108214
{
109215

110216
public:
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
500607
template<typename P_expr, typename P_op>
501608
class _bz_ArrayExprUnaryOp {
502609
public:
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 {
775883
template<typename P_expr1, typename P_expr2, typename P_op>
776884
class _bz_ArrayExprBinaryOp {
777885
public:
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 {
19762085
template<typename P_numtype>
19772086
class _bz_ArrayExprConstant {
19782087
public:
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

blitz/array/ops.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ Array<P_numtype, N_rank>& Array<P_numtype,N_rank>::initialize(T_numtype x)
5050
// we can't use asExpr here, because if we are initializing an array
5151
// whose components are also ETBase, it would parse as an array
5252
// expression, not as an initialization with a scalar.
53-
(*this) = _bz_ArrayExpr<_bz_ArrayExprConstant<T_numtype> >(x);
53+
54+
//(*this) = _bz_ArrayExpr<_bz_ArrayExprConstant<T_numtype> >(x);
55+
iterator iter, last = end();
56+
for (iter = begin(); iter != last; ++ iter) *iter = x;
57+
5458
return *this;
5559
}
5660

blitz/tinymat2.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,13 @@ class TinyMatrix : public ETBase<TinyMatrix<P_numtype, N_rows, N_columns> >
7575
typedef P_numtype T_numtype;
7676
// typedef _bz_tinyMatrixRef<T_numtype, N_rows, N_columns, N_columns, 1>
7777
// T_reference;
78-
typedef TinyVector<int, 2> T_index;
79-
typedef TinyMatrix<T_numtype, N_rows, N_columns> T_matrix;
80-
typedef FastTM2Iterator<T_numtype,N_rows, N_columns> T_iterator;
81-
typedef T_numtype* iterator;
82-
typedef const T_numtype* const_iterator;
83-
typedef FastTM2CopyIterator<P_numtype, N_rows, N_columns> T_range_result;
78+
typedef TinyVector<int, 2> T_index;
79+
typedef TinyMatrix<T_numtype, N_rows, N_columns> T_matrix;
80+
typedef T_matrix T_type;
81+
typedef FastTM2Iterator<T_numtype,N_rows, N_columns> T_iterator;
82+
typedef T_numtype* iterator;
83+
typedef const T_numtype* const_iterator;
84+
typedef FastTM2CopyIterator<P_numtype, N_rows, N_columns> T_range_result;
8485

8586
static const int
8687
//numArrayOperands = 1,

blitz/tinyvec2.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,13 @@ class TinyVector : public ETBase<TinyVector<P_numtype, N_length> >
7777
// Public Types
7878
//////////////////////////////////////////////
7979

80-
typedef P_numtype T_numtype;
81-
typedef TinyVector<T_numtype,N_length> T_vector;
82-
typedef FastTV2Iterator<T_numtype,N_length> T_iterator;
83-
typedef T_numtype* iterator;
84-
typedef const T_numtype* const_iterator;
85-
typedef FastTV2CopyIterator<P_numtype, N_length> T_range_result;
80+
typedef P_numtype T_numtype;
81+
typedef TinyVector<T_numtype,N_length> T_vector;
82+
typedef T_vector T_type;
83+
typedef FastTV2Iterator<T_numtype,N_length> T_iterator;
84+
typedef T_numtype* iterator;
85+
typedef const T_numtype* const_iterator;
86+
typedef FastTV2CopyIterator<P_numtype, N_length> T_range_result;
8687

8788
static const int
8889
//numArrayOperands = 1,

0 commit comments

Comments
 (0)