source: Sophya/trunk/SophyaExt/Blitz/blitz/vector.cc@ 3887

Last change on this file since 3887 was 221, checked in by ansari, 26 years ago

Creation module DPC/Blitz (blitz 0.4) Reza 09/04/99

File size: 27.4 KB
Line 
1/*
2 * $Id: vector.cc,v 1.1.1.1 1999-04-09 17:58:59 ansari Exp $
3 *
4 * Copyright (C) 1997 Todd Veldhuizen <tveldhui@seurat.uwaterloo.ca>
5 * All rights reserved. Please see <blitz/blitz.h> for terms and
6 * conditions of use.
7 *
8 * $Log: not supported by cvs2svn $
9 * Revision 1.6 1998/03/14 00:04:47 tveldhui
10 * 0.2-alpha-05
11 *
12 * Revision 1.5 1997/07/16 14:51:20 tveldhui
13 * Update: Alpha release 0.2 (Arrays)
14 *
15 * Revision 1.4 1997/01/24 14:42:00 tveldhui
16 * Periodic RCS update
17 *
18 */
19
20#ifndef BZ_VECTOR_CC
21#define BZ_VECTOR_CC
22
23#ifndef BZ_VECTOR_H
24 #include <blitz/vector.h>
25#endif
26
27#ifndef BZ_UPDATE_H
28 #include <blitz/update.h>
29#endif
30
31BZ_NAMESPACE(blitz)
32
33template<class P_numtype>
34Vector<P_numtype> Vector<P_numtype>::copy() const
35{
36 Vector<P_numtype> newCopy(length_);
37
38 if (stride_ == 1)
39 {
40 memcpy(newCopy.data(), data(), length_ * sizeof(P_numtype));
41 }
42 else {
43 for (int i=0; i < length_; ++i)
44 {
45 // Can assume that newCopy has unit stride, and hence use
46 // the operator(), which assumes unit stride. Since this
47 // vector doesn't have unit stride, use [].
48 newCopy(i) = (*this)[i];
49 }
50 }
51
52 return newCopy;
53}
54
55template<class P_numtype>
56void Vector<P_numtype>::makeUnique()
57{
58 if ((stride_ != 1) || (numReferences() > 1))
59 {
60 Vector<P_numtype> tmp = copy();
61 reference(tmp);
62 }
63}
64
65template<class P_numtype>
66void Vector<P_numtype>::reference(Vector<P_numtype>& x)
67{
68 MemoryBlockReference<P_numtype>::changeBlock(x, 0);
69 length_ = x.length_;
70 stride_ = x.stride_;
71}
72
73template<class P_numtype>
74void Vector<P_numtype>::resize(int length)
75{
76 if (length != length_)
77 {
78 MemoryBlockReference<P_numtype>::newBlock(length);
79 length_ = length;
80 stride_ = 1;
81 }
82}
83
84template<class P_numtype>
85void Vector<P_numtype>::resizeAndPreserve(int newLength)
86{
87 Vector<P_numtype> newVector(newLength);
88
89 if (newLength > length_)
90 newVector(Range(0,length_-1)) = (*this);
91 else
92 newVector(Range(0,newLength-1)) = (*this);
93
94 reference(newVector);
95}
96
97/*****************************************************************************
98 * Assignment operators with vector expression operand
99 */
100
101template<class P_numtype> template<class P_expr, class P_updater>
102inline
103void Vector<P_numtype>::_bz_assign(P_expr expr, P_updater)
104{
105 BZPRECONDITION(expr.length(length_) == length_);
106
107 // If all vectors in the expression, plus the vector to which the
108 // result is being assigned have unit stride, then avoid stride
109 // calculations.
110 if ((stride_ == 1) && (expr._bz_hasFastAccess()))
111 {
112#ifndef BZ_PARTIAL_LOOP_UNROLL
113 for (int i=0; i < length_; ++i)
114 P_updater::update(data_[i], expr._bz_fastAccess(i));
115#else
116 // Unwind the inner loop, four elements at a time.
117 int leftover = length_ & 0x03;
118
119 int i=0;
120 for (; i < leftover; ++i)
121 P_updater::update(data_[i], expr._bz_fastAccess(i));
122
123 for (; i < length_; i += 4)
124 {
125 // Common subexpression elimination: avoid doing i+1, i+2, i+3
126 // multiple times (compilers *won't* do this cse automatically)
127 int t1 = i+1;
128 int t2 = i+2;
129 int t3 = i+3;
130
131 _bz_typename P_expr::T_numtype tmp1, tmp2, tmp3, tmp4;
132
133 // Reading all the results first avoids aliasing
134 // ambiguities, and provides more flexibility in
135 // register allocation & instruction scheduling
136 tmp1 = expr._bz_fastAccess(i);
137 tmp2 = expr._bz_fastAccess(BZ_NO_PROPAGATE(t1));
138 tmp3 = expr._bz_fastAccess(BZ_NO_PROPAGATE(t2));
139 tmp4 = expr._bz_fastAccess(BZ_NO_PROPAGATE(t3));
140
141 P_updater::update(data_[i], BZ_NO_PROPAGATE(tmp1));
142 P_updater::update(data_[t1], tmp2);
143 P_updater::update(data_[t2], tmp3);
144 P_updater::update(data_[t3], tmp4);
145 }
146#endif
147 }
148 else {
149 // Not all unit strides -- have to access all the vector elements
150 // as data_[i*stride_], which is slower.
151 for (int i=0; i < length_; ++i)
152 P_updater::update((*this)[i], expr[i]);
153 }
154}
155
156template<class P_numtype> template<class P_expr>
157inline Vector<P_numtype>& Vector<P_numtype>::operator=(_bz_VecExpr<P_expr> expr)
158{
159 BZPRECONDITION(expr.length(length_) == length_);
160
161 // If all vectors in the expression, plus the vector to which the
162 // result is being assigned have unit stride, then avoid stride
163 // calculations.
164 if ((stride_ == 1) && (expr._bz_hasFastAccess()))
165 {
166#ifndef BZ_PARTIAL_LOOP_UNROLL
167 for (int i=0; i < length_; ++i)
168 data_[i] = (P_numtype)expr._bz_fastAccess(i);
169#else
170 // Unwind the inner loop, four elements at a time.
171 int leftover = length_ & 3;
172
173 int i=0;
174 for (; i < leftover; ++i)
175 data_[i] = (P_numtype)expr._bz_fastAccess(i);
176
177 for (; i < length_; i += 4)
178 {
179 // Common subexpression elimination: avoid doing i+1, i+2, i+3
180 // multiple times (compilers *won't* do this cse automatically)
181 int t1 = i+1;
182 int t2 = i+2;
183 int t3 = i+3;
184
185 _bz_typename P_expr::T_numtype tmp1, tmp2, tmp3, tmp4;
186
187 // Reading all the results first avoids aliasing
188 // ambiguities, and provides more flexibility in
189 // register allocation & instruction scheduling
190 tmp1 = expr._bz_fastAccess(i);
191 tmp2 = expr._bz_fastAccess(BZ_NO_PROPAGATE(t1));
192 tmp3 = expr._bz_fastAccess(BZ_NO_PROPAGATE(t2));
193 tmp4 = expr._bz_fastAccess(BZ_NO_PROPAGATE(t3));
194
195 data_[i] = (P_numtype)BZ_NO_PROPAGATE(tmp1);
196 data_[t1] = (P_numtype)tmp2;
197 data_[t2] = (P_numtype)tmp3;
198 data_[t3] = (P_numtype)tmp4;
199 }
200#endif
201 }
202 else {
203 // Not all unit strides -- have to access all the vector elements
204 // as data_[i*stride_], which is slower.
205 for (int i=0; i < length_; ++i)
206 (*this)[i] = (P_numtype)expr[i];
207 }
208 return *this;
209}
210
211#ifdef BZ_PARTIAL_LOOP_UNROLL
212
213#define BZ_VECTOR_ASSIGN(op) \
214template<class P_numtype> template<class P_expr> \
215inline Vector<P_numtype>& Vector<P_numtype>:: \
216 operator op (_bz_VecExpr<P_expr> expr) \
217{ \
218 BZPRECONDITION(expr.length(length_) == length_); \
219 if ((stride_ == 1) && (expr._bz_hasFastAccess())) \
220 { \
221 int leftover = length_ & 0x03; \
222 \
223 int i=0; \
224 for (; i < leftover; ++i) \
225 data_[i] op expr._bz_fastAccess(i); \
226 \
227 for (; i < length_; i += 4) \
228 { \
229 int t1 = i+1; \
230 int t2 = i+2; \
231 int t3 = i+3; \
232 \
233 _bz_typename P_expr::T_numtype tmp1, tmp2, tmp3, tmp4; \
234 \
235 tmp1 = expr._bz_fastAccess(i); \
236 tmp2 = expr._bz_fastAccess(t1); \
237 tmp3 = expr._bz_fastAccess(t2); \
238 tmp4 = expr._bz_fastAccess(t3); \
239 \
240 data_[i] op tmp1; \
241 data_[t1] op tmp2; \
242 data_[t2] op tmp3; \
243 data_[t3] op tmp4; \
244 } \
245 } \
246 else { \
247 for (int i=0; i < length_; ++i) \
248 (*this)[i] op expr[i]; \
249 } \
250 return *this; \
251}
252
253#else // not BZ_PARTIAL_LOOP_UNROLL
254
255#ifdef BZ_ALTERNATE_FORWARD_BACKWARD_TRAVERSALS
256
257/*
258 * NEEDS_WORK: need to incorporate BZ_NO_PROPAGATE here. This
259 * will require doing away with the macro BZ_VECTOR_ASSIGN, and
260 * adopting an approach similar to that used in arrayeval.cc.
261 */
262
263#define BZ_VECTOR_ASSIGN(op) \
264template<class P_numtype> template<class P_expr> \
265inline Vector<P_numtype>& Vector<P_numtype>:: \
266 operator op (_bz_VecExpr<P_expr> expr) \
267{ \
268 BZPRECONDITION(expr.length(length_) == length_); \
269 static int traversalOrder = 0; \
270 if ((stride_ == 1) && (expr._bz_hasFastAccess())) \
271 { \
272 if (traversalOrder & 0x01) \
273 for (int i=length_-1; i >= 0; --i) \
274 data_[i] op expr._bz_fastAccess(i); \
275 else \
276 for (int i=0; i < length_; ++i) \
277 data_[i] op expr._bz_fastAccess(i); \
278 } \
279 else { \
280 for (int i=0; i < length_; ++i) \
281 (*this)[i] op expr[i]; \
282 } \
283 traversalOrder ^= 0x01; \
284 return *this; \
285}
286
287#else // not BZ_ALTERNATE_FORWARD_BACKWARD_TRAVERSALS
288
289#define BZ_VECTOR_ASSIGN(op) \
290template<class P_numtype> template<class P_expr> \
291inline Vector<P_numtype>& Vector<P_numtype>:: \
292 operator op (_bz_VecExpr<P_expr> expr) \
293{ \
294 BZPRECONDITION(expr.length(length_) == length_); \
295 if ((stride_ == 1) && (expr._bz_hasFastAccess())) \
296 { \
297 for (int i=0; i < length_; ++i) \
298 data_[i] op expr._bz_fastAccess(i); \
299 } \
300 else { \
301 for (int i=0; i < length_; ++i) \
302 (*this)[i] op expr[i]; \
303 } \
304 return *this; \
305}
306#endif // BZ_ALTERNATE_FORWARD_BACKWARD_TRAVERSALS
307#endif // BZ_PARTIAL_LOOP_UNROLL
308
309BZ_VECTOR_ASSIGN(+=)
310BZ_VECTOR_ASSIGN(-=)
311BZ_VECTOR_ASSIGN(*=)
312BZ_VECTOR_ASSIGN(/=)
313BZ_VECTOR_ASSIGN(%=)
314BZ_VECTOR_ASSIGN(^=)
315BZ_VECTOR_ASSIGN(&=)
316BZ_VECTOR_ASSIGN(|=)
317BZ_VECTOR_ASSIGN(>>=)
318BZ_VECTOR_ASSIGN(<<=)
319
320#if NOT_DEFINED
321
322template<class P_numtype> template<class P_expr>
323inline Vector<P_numtype>& Vector<P_numtype>::operator+=(_bz_VecExpr<P_expr> expr)
324{
325 _bz_assign(expr, _bz_plus_update<P_numtype,
326 _bz_typename P_expr::T_numtype>());
327 return *this;
328}
329
330template<class P_numtype> template<class P_expr>
331inline Vector<P_numtype>& Vector<P_numtype>::operator-=(_bz_VecExpr<P_expr> expr)
332{
333 _bz_assign(expr, _bz_minus_update<P_numtype,
334 _bz_typename P_expr::T_numtype>());
335 return *this;
336}
337
338template<class P_numtype> template<class P_expr>
339inline Vector<P_numtype>& Vector<P_numtype>::operator*=(_bz_VecExpr<P_expr> expr)
340{
341 _bz_assign(expr, _bz_multiply_update<P_numtype,
342 _bz_typename P_expr::T_numtype>());
343 return *this;
344}
345
346template<class P_numtype> template<class P_expr>
347inline Vector<P_numtype>& Vector<P_numtype>::operator/=(_bz_VecExpr<P_expr> expr)
348{
349 _bz_assign(expr, _bz_divide_update<P_numtype,
350 _bz_typename P_expr::T_numtype>());
351 return *this;
352}
353
354template<class P_numtype> template<class P_expr>
355inline Vector<P_numtype>& Vector<P_numtype>::operator%=(_bz_VecExpr<P_expr> expr)
356{
357 _bz_assign(expr, _bz_mod_update<P_numtype,
358 _bz_typename P_expr::T_numtype>());
359 return *this;
360}
361
362template<class P_numtype> template<class P_expr>
363inline Vector<P_numtype>& Vector<P_numtype>::operator^=(_bz_VecExpr<P_expr> expr)
364{
365 _bz_assign(expr, _bz_xor_update<P_numtype,
366 _bz_typename P_expr::T_numtype>());
367 return *this;
368}
369
370template<class P_numtype> template<class P_expr>
371inline Vector<P_numtype>& Vector<P_numtype>::operator&=(_bz_VecExpr<P_expr> expr)
372{
373 _bz_assign(expr, _bz_bitand_update<P_numtype,
374 _bz_typename P_expr::T_numtype>());
375 return *this;
376}
377
378template<class P_numtype> template<class P_expr>
379inline Vector<P_numtype>& Vector<P_numtype>::operator|=(_bz_VecExpr<P_expr> expr)
380{
381 _bz_assign(expr, _bz_bitor_update<P_numtype,
382 _bz_typename P_expr::T_numtype>());
383 return *this;
384}
385
386template<class P_numtype> template<class P_expr>
387inline Vector<P_numtype>& Vector<P_numtype>::operator>>=(_bz_VecExpr<P_expr> expr)
388{
389 _bz_assign(expr, _bz_shiftr_update<P_numtype,
390 _bz_typename P_expr::T_numtype>());
391 return *this;
392}
393
394template<class P_numtype> template<class P_expr>
395inline Vector<P_numtype>& Vector<P_numtype>::operator<<=(_bz_VecExpr<P_expr> expr)
396{
397 _bz_assign(expr, _bz_shiftl_update<P_numtype,
398 _bz_typename P_expr::T_numtype>());
399 return *this;
400}
401#endif // NOT_DEFINED
402
403/*****************************************************************************
404 * Assignment operators with scalar operand
405 */
406
407template<class P_numtype>
408inline Vector<P_numtype>& Vector<P_numtype>::initialize(P_numtype x)
409{
410 typedef _bz_VecExprConstant<P_numtype> T_expr;
411 (*this) = _bz_VecExpr<T_expr>(T_expr(x));
412 return *this;
413}
414
415template<class P_numtype>
416inline Vector<P_numtype>& Vector<P_numtype>::operator+=(P_numtype x)
417{
418 typedef _bz_VecExprConstant<P_numtype> T_expr;
419 (*this) += _bz_VecExpr<T_expr>(T_expr(x));
420 return *this;
421}
422
423template<class P_numtype>
424inline Vector<P_numtype>& Vector<P_numtype>::operator-=(P_numtype x)
425{
426 typedef _bz_VecExprConstant<P_numtype> T_expr;
427 (*this) -= _bz_VecExpr<T_expr>(T_expr(x));
428 return *this;
429}
430
431template<class P_numtype>
432inline Vector<P_numtype>& Vector<P_numtype>::operator*=(P_numtype x)
433{
434 typedef _bz_VecExprConstant<P_numtype> T_expr;
435 (*this) *= _bz_VecExpr<T_expr>(T_expr(x));
436 return *this;
437}
438
439template<class P_numtype>
440inline Vector<P_numtype>& Vector<P_numtype>::operator/=(P_numtype x)
441{
442 typedef _bz_VecExprConstant<P_numtype> T_expr;
443 (*this) /= _bz_VecExpr<T_expr>(T_expr(x));
444 return *this;
445}
446
447template<class P_numtype>
448inline Vector<P_numtype>& Vector<P_numtype>::operator%=(P_numtype x)
449{
450 typedef _bz_VecExprConstant<P_numtype> T_expr;
451 (*this) %= _bz_VecExpr<T_expr>(T_expr(x));
452 return *this;
453}
454
455template<class P_numtype>
456inline Vector<P_numtype>& Vector<P_numtype>::operator^=(P_numtype x)
457{
458 typedef _bz_VecExprConstant<P_numtype> T_expr;
459 (*this) ^= _bz_VecExpr<T_expr>(T_expr(x));
460 return *this;
461}
462
463template<class P_numtype>
464inline Vector<P_numtype>& Vector<P_numtype>::operator&=(P_numtype x)
465{
466 typedef _bz_VecExprConstant<P_numtype> T_expr;
467 (*this) &= _bz_VecExpr<T_expr>(T_expr(x));
468 return *this;
469}
470
471template<class P_numtype>
472inline Vector<P_numtype>& Vector<P_numtype>::operator|=(P_numtype x)
473{
474 typedef _bz_VecExprConstant<P_numtype> T_expr;
475 (*this) |= _bz_VecExpr<T_expr>(T_expr(x));
476 return *this;
477}
478
479template<class P_numtype>
480inline Vector<P_numtype>& Vector<P_numtype>::operator>>=(int x)
481{
482 typedef _bz_VecExprConstant<int> T_expr;
483 (*this) >>= _bz_VecExpr<T_expr>(T_expr(x));
484 return *this;
485}
486
487template<class P_numtype>
488inline Vector<P_numtype>& Vector<P_numtype>::operator<<=(int x)
489{
490 typedef _bz_VecExprConstant<P_numtype> T_expr;
491 (*this) <<= _bz_VecExpr<T_expr>(T_expr(x));
492 return *this;
493}
494
495/*****************************************************************************
496 * Assignment operators with vector operand
497 */
498
499// This version is for two vectors with the same template parameter.
500// Does not appear to be supported by the current C++ standard; or
501// is it?
502#if 0
503template<class P_numtype> template<>
504inline Vector<P_numtype>&
505Vector<P_numtype>::operator=(const Vector<P_numtype>& x)
506{
507 // NEEDS_WORK: if unit strides, use memcpy or something similar.
508
509 typedef VectorIterConst<P_numtype> T_expr;
510 (*this) = _bz_VecExpr<T_expr>(T_expr(*this));
511 return *this;
512}
513#endif
514
515// This version is for two vectors with *different* template
516// parameters.
517template<class P_numtype> template<class P_numtype2>
518inline Vector<P_numtype>&
519Vector<P_numtype>::operator=(const Vector<P_numtype2>& x)
520{
521 (*this) = _bz_VecExpr<VectorIterConst<P_numtype2> >(x.begin());
522 return *this;
523}
524
525template<class P_numtype> template<class P_numtype2>
526inline Vector<P_numtype>&
527Vector<P_numtype>::operator+=(const Vector<P_numtype2>& x)
528{
529 (*this) += _bz_VecExpr<VectorIterConst<P_numtype2> >(x.begin());
530 return *this;
531}
532
533template<class P_numtype> template<class P_numtype2>
534inline Vector<P_numtype>&
535Vector<P_numtype>::operator-=(const Vector<P_numtype2>& x)
536{
537 (*this) -= _bz_VecExpr<VectorIterConst<P_numtype2> >(x.begin());
538 return *this;
539}
540
541template<class P_numtype> template<class P_numtype2>
542inline Vector<P_numtype>&
543Vector<P_numtype>::operator*=(const Vector<P_numtype2>& x)
544{
545 (*this) *= _bz_VecExpr<VectorIterConst<P_numtype2> >(x.begin());
546 return *this;
547}
548
549template<class P_numtype> template<class P_numtype2>
550inline Vector<P_numtype>&
551Vector<P_numtype>::operator/=(const Vector<P_numtype2>& x)
552{
553 (*this) /= _bz_VecExpr<VectorIterConst<P_numtype2> >(x.begin());
554 return *this;
555}
556
557template<class P_numtype> template<class P_numtype2>
558inline Vector<P_numtype>&
559Vector<P_numtype>::operator%=(const Vector<P_numtype2>& x)
560{
561 (*this) %= _bz_VecExpr<VectorIterConst<P_numtype2> >(x.begin());
562 return *this;
563}
564
565template<class P_numtype> template<class P_numtype2>
566inline Vector<P_numtype>&
567Vector<P_numtype>::operator^=(const Vector<P_numtype2>& x)
568{
569 (*this) ^= _bz_VecExpr<VectorIterConst<P_numtype2> >(x.begin());
570 return *this;
571}
572
573template<class P_numtype> template<class P_numtype2>
574inline Vector<P_numtype>&
575Vector<P_numtype>::operator&=(const Vector<P_numtype2>& x)
576{
577 (*this) &= _bz_VecExpr<VectorIterConst<P_numtype2> >(x.begin());
578 return *this;
579}
580
581template<class P_numtype> template<class P_numtype2>
582inline Vector<P_numtype>&
583Vector<P_numtype>::operator|=(const Vector<P_numtype2>& x)
584{
585 (*this) |= _bz_VecExpr<VectorIterConst<P_numtype2> >(x.begin());
586 return *this;
587}
588
589template<class P_numtype> template<class P_numtype2>
590inline Vector<P_numtype>&
591Vector<P_numtype>::operator<<=(const Vector<P_numtype2>& x)
592{
593 (*this) <<= _bz_VecExpr<VectorIterConst<P_numtype2> >(x.begin());
594 return *this;
595}
596
597template<class P_numtype> template<class P_numtype2>
598inline Vector<P_numtype>&
599Vector<P_numtype>::operator>>=(const Vector<P_numtype2>& x)
600{
601 (*this) >>= _bz_VecExpr<VectorIterConst<P_numtype2> >(x.begin());
602 return *this;
603}
604
605/*****************************************************************************
606 * Assignment operators with Range operand
607 */
608
609template<class P_numtype>
610inline Vector<P_numtype>& Vector<P_numtype>::operator=(Range r)
611{
612 (*this) = _bz_VecExpr<Range>(r);
613 return *this;
614}
615
616template<class P_numtype>
617inline Vector<P_numtype>& Vector<P_numtype>::operator+=(Range r)
618{
619 (*this) += _bz_VecExpr<Range>(r);
620 return *this;
621}
622
623template<class P_numtype>
624inline Vector<P_numtype>& Vector<P_numtype>::operator-=(Range r)
625{
626 (*this) -= _bz_VecExpr<Range>(r);
627 return *this;
628}
629
630template<class P_numtype>
631inline Vector<P_numtype>& Vector<P_numtype>::operator*=(Range r)
632{
633 (*this) *= _bz_VecExpr<Range>(r);
634 return *this;
635}
636
637template<class P_numtype>
638inline Vector<P_numtype>& Vector<P_numtype>::operator/=(Range r)
639{
640 (*this) /= _bz_VecExpr<Range>(r);
641 return *this;
642}
643
644template<class P_numtype>
645inline Vector<P_numtype>& Vector<P_numtype>::operator%=(Range r)
646{
647 (*this) %= _bz_VecExpr<Range>(r);
648 return *this;
649}
650
651template<class P_numtype>
652inline Vector<P_numtype>& Vector<P_numtype>::operator^=(Range r)
653{
654 (*this) ^= _bz_VecExpr<Range>(r);
655 return *this;
656}
657
658template<class P_numtype>
659inline Vector<P_numtype>& Vector<P_numtype>::operator&=(Range r)
660{
661 (*this) &= _bz_VecExpr<Range>(r);
662 return *this;
663}
664
665template<class P_numtype>
666inline Vector<P_numtype>& Vector<P_numtype>::operator|=(Range r)
667{
668 (*this) |= _bz_VecExpr<Range>(r);
669 return *this;
670}
671
672template<class P_numtype>
673inline Vector<P_numtype>& Vector<P_numtype>::operator>>=(Range r)
674{
675 (*this) >>= _bz_VecExpr<Range>(r);
676 return *this;
677}
678
679template<class P_numtype>
680inline Vector<P_numtype>& Vector<P_numtype>::operator<<=(Range r)
681{
682 (*this) <<= _bz_VecExpr<Range>(r);
683 return *this;
684}
685
686/*****************************************************************************
687 * Assignment operators with VectorPick operand
688 */
689
690template<class P_numtype> template<class P_numtype2>
691inline Vector<P_numtype>& Vector<P_numtype>::operator=(const
692 VectorPick<P_numtype2>& x)
693{
694 typedef VectorPickIterConst<P_numtype2> T_expr;
695 (*this) = _bz_VecExpr<T_expr>(x.begin());
696 return *this;
697}
698
699template<class P_numtype> template<class P_numtype2>
700inline Vector<P_numtype>& Vector<P_numtype>::operator+=(const
701 VectorPick<P_numtype2>& x)
702{
703 typedef VectorPickIterConst<P_numtype2> T_expr;
704 (*this) += _bz_VecExpr<T_expr>(x.begin());
705 return *this;
706}
707
708
709template<class P_numtype> template<class P_numtype2>
710inline Vector<P_numtype>& Vector<P_numtype>::operator-=(const
711 VectorPick<P_numtype2>& x)
712{
713 typedef VectorPickIterConst<P_numtype2> T_expr;
714 (*this) -= _bz_VecExpr<T_expr>(x.begin());
715 return *this;
716}
717
718template<class P_numtype> template<class P_numtype2>
719inline Vector<P_numtype>& Vector<P_numtype>::operator*=(const
720 VectorPick<P_numtype2>& x)
721{
722 typedef VectorPickIterConst<P_numtype2> T_expr;
723 (*this) *= _bz_VecExpr<T_expr>(x.begin());
724 return *this;
725}
726
727template<class P_numtype> template<class P_numtype2>
728inline Vector<P_numtype>& Vector<P_numtype>::operator/=(const
729 VectorPick<P_numtype2>& x)
730{
731 typedef VectorPickIterConst<P_numtype2> T_expr;
732 (*this) /= _bz_VecExpr<T_expr>(x.begin());
733 return *this;
734}
735
736template<class P_numtype> template<class P_numtype2>
737inline Vector<P_numtype>& Vector<P_numtype>::operator%=(const
738 VectorPick<P_numtype2>& x)
739{
740 typedef VectorPickIterConst<P_numtype2> T_expr;
741 (*this) %= _bz_VecExpr<T_expr>(x.begin());
742 return *this;
743}
744
745template<class P_numtype> template<class P_numtype2>
746inline Vector<P_numtype>& Vector<P_numtype>::operator^=(const
747 VectorPick<P_numtype2>& x)
748{
749 typedef VectorPickIterConst<P_numtype2> T_expr;
750 (*this) ^= _bz_VecExpr<T_expr>(x.begin());
751 return *this;
752}
753
754template<class P_numtype> template<class P_numtype2>
755inline Vector<P_numtype>& Vector<P_numtype>::operator&=(const
756 VectorPick<P_numtype2>& x)
757{
758 typedef VectorPickIterConst<P_numtype2> T_expr;
759 (*this) &= _bz_VecExpr<T_expr>(x.begin());
760 return *this;
761}
762
763template<class P_numtype> template<class P_numtype2>
764inline Vector<P_numtype>& Vector<P_numtype>::operator|=(const
765 VectorPick<P_numtype2>& x)
766{
767 typedef VectorPickIterConst<P_numtype2> T_expr;
768 (*this) |= _bz_VecExpr<T_expr>(x.begin());
769 return *this;
770}
771
772/*****************************************************************************
773 * Assignment operators with Random operand
774 */
775
776template<class P_numtype> template<class P_distribution>
777Vector<P_numtype>& Vector<P_numtype>::operator=(Random<P_distribution>& rand)
778{
779 for (int i=0; i < length_; ++i)
780 (*this)[i] = rand.random();
781 return *this;
782}
783
784#ifdef BZ_PECULIAR_RANDOM_VECTOR_ASSIGN_BUG
785
786template<class P_numtype> template<class P_distribution>
787Vector<P_numtype>& Vector<P_numtype>::operator=(Random<P_distribution>& rand)
788{
789 (*this) = _bz_VecExpr<_bz_VecExprRandom<P_distribution> >
790 (_bz_VecExprRandom<P_distribution>(rand));
791 return *this;
792}
793
794template<class P_numtype> template<class P_distribution>
795Vector<P_numtype>& Vector<P_numtype>::operator+=(Random<P_distribution>& rand)
796{
797 (*this) += _bz_VecExpr<_bz_VecExprRandom<P_distribution> >
798 (_bz_VecExprRandom<P_distribution>(rand));
799 return *this;
800}
801
802template<class P_numtype> template<class P_distribution>
803Vector<P_numtype>& Vector<P_numtype>::operator-=(Random<P_distribution>& rand)
804{
805 (*this) -= _bz_VecExpr<_bz_VecExprRandom<P_distribution> >
806 (_bz_VecExprRandom<P_distribution>(rand));
807 return *this;
808}
809
810template<class P_numtype> template<class P_distribution>
811Vector<P_numtype>& Vector<P_numtype>::operator*=(Random<P_distribution>& rand)
812{
813 (*this) *= _bz_VecExpr<_bz_VecExprRandom<P_distribution> >
814 (_bz_VecExprRandom<P_distribution>(rand));
815 return *this;
816}
817
818template<class P_numtype> template<class P_distribution>
819Vector<P_numtype>& Vector<P_numtype>::operator/=(Random<P_distribution>& rand)
820{
821 (*this) /= _bz_VecExpr<_bz_VecExprRandom<P_distribution> >
822 (_bz_VecExprRandom<P_distribution>(rand));
823 return *this;
824}
825
826template<class P_numtype> template<class P_distribution>
827Vector<P_numtype>& Vector<P_numtype>::operator%=(Random<P_distribution>& rand)
828{
829 (*this) %= _bz_VecExpr<_bz_VecExprRandom<P_distribution> >
830 (_bz_VecExprRandom<P_distribution>(rand));
831 return *this;
832}
833
834template<class P_numtype> template<class P_distribution>
835Vector<P_numtype>& Vector<P_numtype>::operator^=(Random<P_distribution>& rand)
836{
837 (*this) ^= _bz_VecExpr<_bz_VecExprRandom<P_distribution> >
838 (_bz_VecExprRandom<P_distribution>(rand));
839 return *this;
840}
841
842template<class P_numtype> template<class P_distribution>
843Vector<P_numtype>& Vector<P_numtype>::operator&=(Random<P_distribution>& rand)
844{
845 (*this) &= _bz_VecExpr<_bz_VecExprRandom<P_distribution> >
846 (_bz_VecExprRandom<P_distribution>(rand));
847 return *this;
848}
849
850template<class P_numtype> template<class P_distribution>
851Vector<P_numtype>& Vector<P_numtype>::operator|=(Random<P_distribution>& rand)
852{
853 (*this) |= _bz_VecExpr<_bz_VecExprRandom<P_distribution> >
854 (_bz_VecExprRandom<P_distribution>(rand));
855 return *this;
856}
857
858#endif // BZ_PECULIAR_RANDOM_VECTOR_ASSIGN_BUG
859
860BZ_NAMESPACE_END
861
862#endif // BZ_VECTOR_CC
Note: See TracBrowser for help on using the repository browser.