source: Sophya/trunk/Poubelle/DPC:FitsIOServer/Blitz/blitz/vector.cc@ 658

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

no message

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