37 #ifndef VIGRA_TINYVECTOR_HXX
38 #define VIGRA_TINYVECTOR_HXX
46 #include "metaprogramming.hxx"
47 #include "numerictraits.hxx"
49 #include "mathutil.hxx"
52 #ifdef VIGRA_CHECK_BOUNDS
53 #define VIGRA_ASSERT_INSIDE(diff) \
54 vigra_precondition(diff >= 0, "Index out of bounds");\
55 vigra_precondition(diff < SIZE, "Index out of bounds");
57 #define VIGRA_ASSERT_INSIDE(diff)
64 #pragma warning( push )
65 #pragma warning( disable : 4503 )
74 template <
class V1,
int SIZE,
class D1,
class D2>
77 template <
class V1,
int SIZE,
class D1,
class D2>
85 #define VIGRA_EXEC_LOOP(NAME, OPER) \
86 template <class T1, class T2> \
87 static void NAME(T1 * left, T2 const * right) \
89 for(int i=0; i<LEVEL; ++i) \
90 (left[i]) OPER (right[i]); \
93 #define VIGRA_EXEC_LOOP_MINMAX(NAME, OPER) \
94 template <class T1, class T2> \
95 static void NAME(T1 * left, T2 const * right) \
97 for(int i=0; i<LEVEL; ++i) \
98 if(left[i] OPER right[i]) \
102 #define VIGRA_EXEC_LOOP_SCALAR(NAME, OPER) \
103 template <class T1, class T2> \
104 static void NAME(T1 * left, T2 right) \
106 for(int i=0; i<LEVEL; ++i) \
107 (left[i]) = detail::RequiresExplicitCast<T1>::cast((left[i]) OPER (right)); \
113 template <
class T1,
class T2>
114 static void assignCast(T1 * left, T2
const * right)
116 for(
int i=0; i<LEVEL; ++i)
117 left[i] = detail::RequiresExplicitCast<T1>::cast(right[i]);
120 template <
class T1,
class T2>
121 static void reverseAssign(T1 * left, T2
const * right)
123 for(
int i=0; i<LEVEL; ++i)
127 template <
class T1,
class T2>
128 static void assignScalar(T1 * left, T2 right)
130 for(
int i=0; i<LEVEL; ++i)
131 left[i] = detail::RequiresExplicitCast<T1>::cast(right);
134 template <
class T1,
class T2>
135 static void power(T1 * left, T2 right)
137 for(
int i=0; i<LEVEL; ++i)
138 left[i] = detail::RequiresExplicitCast<T1>::cast(pow(left, right));
141 VIGRA_EXEC_LOOP(assign, =)
142 VIGRA_EXEC_LOOP(
add, +=)
143 VIGRA_EXEC_LOOP(
sub, -=)
144 VIGRA_EXEC_LOOP(
mul, *=)
145 VIGRA_EXEC_LOOP(
div, /=)
146 VIGRA_EXEC_LOOP(neg, = -)
147 VIGRA_EXEC_LOOP(
abs, = vigra::abs)
148 VIGRA_EXEC_LOOP(
floor, = vigra::floor)
149 VIGRA_EXEC_LOOP(
ceil, = vigra::ceil)
150 VIGRA_EXEC_LOOP(
sqrt, = vigra::sqrt)
151 VIGRA_EXEC_LOOP(fromPromote, = NumericTraits<T1>::fromPromote)
152 VIGRA_EXEC_LOOP(fromRealPromote, = NumericTraits<T1>::fromRealPromote)
153 VIGRA_EXEC_LOOP_SCALAR(mulScalar, *)
154 VIGRA_EXEC_LOOP_SCALAR(divScalar, /)
156 VIGRA_EXEC_LOOP_MINMAX(min, >)
157 VIGRA_EXEC_LOOP_MINMAX(max, <)
160 static T const & minimum(T const * p)
162 return *std::min_element(p, p+LEVEL);
166 static T
const & maximum(T
const * p)
168 return *std::max_element(p, p+LEVEL);
171 template <
class T1,
class T2>
172 static bool notEqual(T1
const * left, T2
const * right)
174 for(
int i=0; i<LEVEL; ++i)
175 if(left[i] != right[i])
180 template <
class T1,
class T2>
181 static bool less(T1
const * left, T2
const * right)
183 for(
int i=0; i<LEVEL; ++i)
185 if(left[i] < right[i])
187 if(right[i] < left[i])
193 static typename NumericTraits<T>::Promote
196 typename NumericTraits<T>::Promote res(*d * *d);
197 for(
int i=1; i<LEVEL; ++i)
202 template <
class T1,
class T2>
203 static typename PromoteTraits<T1, T2>::Promote
204 dot(T1
const * left, T2
const * right)
206 typename PromoteTraits<T1, T2>::Promote res(*left * *right);
207 for(
int i=1; i<LEVEL; ++i)
208 res += left[i] * right[i];
213 static typename NormTraits<T>::SquaredNormType
217 for(
int i=1; i<LEVEL; ++i)
224 struct UnrollScalarResult
227 static typename NumericTraits<T>::Promote
233 template <
class T1,
class T2>
234 static typename PromoteTraits<T1, T2>::Promote
235 dot(T1
const * left, T2
const * right)
241 static typename NormTraits<T>::SquaredNormType
247 static std::ptrdiff_t
254 static T
const & minimum(T
const * p)
256 T
const & m = UnrollScalarResult<LEVEL - 1>::minimum(p+1);
263 static T
const & maximum(T
const * p)
265 T
const & m = UnrollScalarResult<LEVEL - 1>::maximum(p+1);
273 struct UnrollScalarResult<1>
276 static typename NumericTraits<T>::Promote
282 template <
class T1,
class T2>
283 static typename PromoteTraits<T1, T2>::Promote
284 dot(T1
const * left, T2
const * right)
286 return *left * *right;
290 static typename NormTraits<T>::SquaredNormType
296 static std::ptrdiff_t
303 static T
const & minimum(T
const * p)
309 static T
const & maximum(T
const * p)
315 #undef VIGRA_EXEC_LOOP
316 #undef VIGRA_EXEC_LOOP_MINMAX
317 #undef VIGRA_EXEC_LOOP_SCALAR
319 #define VIGRA_UNROLL_LOOP(NAME, OPER) \
320 template <class T1, class T2> \
321 static void NAME(T1 * left, T2 const * right) \
323 (*left) OPER (*right); \
324 UnrollLoop<LEVEL-1>::NAME(left+1, right+1); \
327 #define VIGRA_UNROLL_LOOP_MINMAX(NAME, OPER) \
328 template <class T1, class T2> \
329 static void NAME(T1 * left, T2 const * right) \
331 if(*left OPER *right) \
333 UnrollLoop<LEVEL-1>::NAME(left+1, right+1); \
336 #define VIGRA_UNROLL_LOOP_SCALAR(NAME, OPER) \
337 template <class T1, class T2> \
338 static void NAME(T1 * left, T2 right) \
340 (*left) = detail::RequiresExplicitCast<T1>::cast((*left) OPER (right)); \
341 UnrollLoop<LEVEL-1>::NAME(left+1, right); \
348 template <
class T1,
class T2>
349 static void reverseAssign(T1 * left, T2
const * right)
352 UnrollLoop<LEVEL-1>::reverseAssign(left+1, right-1);
355 template <
class T1,
class T2>
356 static void assignCast(T1 * left, T2
const * right)
358 *left = detail::RequiresExplicitCast<T1>::cast(*right);
359 UnrollLoop<LEVEL-1>::assignCast(left+1, right+1);
362 template <
class T1,
class T2>
363 static void assignScalar(T1 * left, T2 right)
365 *left = detail::RequiresExplicitCast<T1>::cast(right);
366 UnrollLoop<LEVEL-1>::assignScalar(left+1, right);
369 template <
class T1,
class T2>
370 static void power(T1 * left, T2 right)
372 *left = detail::RequiresExplicitCast<T1>::cast(pow(*left, right));
376 VIGRA_UNROLL_LOOP(assign, =)
377 VIGRA_UNROLL_LOOP(
add, +=)
378 VIGRA_UNROLL_LOOP(
sub, -=)
379 VIGRA_UNROLL_LOOP(
mul, *=)
380 VIGRA_UNROLL_LOOP(
div, /=)
381 VIGRA_UNROLL_LOOP(neg, = -)
382 VIGRA_UNROLL_LOOP(
abs, = vigra::abs)
383 VIGRA_UNROLL_LOOP(
floor, = vigra::floor)
384 VIGRA_UNROLL_LOOP(
ceil, = vigra::ceil)
385 VIGRA_UNROLL_LOOP(
sqrt, = vigra::sqrt)
386 VIGRA_UNROLL_LOOP(fromPromote, = NumericTraits<T1>::fromPromote)
387 VIGRA_UNROLL_LOOP(fromRealPromote, = NumericTraits<T1>::fromRealPromote)
388 VIGRA_UNROLL_LOOP_SCALAR(mulScalar, *)
389 VIGRA_UNROLL_LOOP_SCALAR(divScalar, /)
391 VIGRA_UNROLL_LOOP_MINMAX(min, >)
392 VIGRA_UNROLL_LOOP_MINMAX(max, <)
395 static T const & minimum(T const * p)
397 return UnrollScalarResult<LEVEL>::minimum(p);
401 static T
const & maximum(T
const * p)
403 return UnrollScalarResult<LEVEL>::maximum(p);
406 template <
class T1,
class T2>
407 static bool notEqual(T1
const * left, T2
const * right)
409 return (*left != *right) || UnrollLoop<LEVEL - 1>::notEqual(left+1, right+1);
412 template <
class T1,
class T2>
413 static bool less(T1
const * left, T2
const * right)
419 return UnrollLoop<LEVEL - 1>::less(left+1, right+1);
423 static typename NumericTraits<T>::Promote
429 template <
class T1,
class T2>
430 static typename PromoteTraits<T1, T2>::Promote
431 dot(T1
const * left, T2
const * right)
437 static typename NormTraits<T>::SquaredNormType
444 #undef VIGRA_UNROLL_LOOP
445 #undef VIGRA_UNROLL_LOOP_MINMAX
446 #undef VIGRA_UNROLL_LOOP_SCALAR
451 template <
class T1,
class T2>
452 static void reverseAssign(T1, T2) {}
453 template <
class T1,
class T2>
454 static void assignCast(T1, T2) {}
455 template <
class T1,
class T2>
456 static void assign(T1, T2) {}
457 template <
class T1,
class T2>
458 static void assignScalar(T1, T2) {}
459 template <
class T1,
class T2>
460 static void power(T1, T2) {}
461 template <
class T1,
class T2>
462 static void add(T1, T2) {}
463 template <
class T1,
class T2>
464 static void sub(T1, T2) {}
465 template <
class T1,
class T2>
466 static void mul(T1, T2) {}
467 template <
class T1,
class T2>
468 static void mulScalar(T1, T2) {}
469 template <
class T1,
class T2>
470 static void div(T1, T2) {}
471 template <
class T1,
class T2>
472 static void divScalar(T1, T2) {}
473 template <
class T1,
class T2>
474 static void fromPromote(T1, T2) {}
475 template <
class T1,
class T2>
476 static void fromRealPromote(T1, T2) {}
477 template <
class T1,
class T2>
478 static void neg(T1, T2) {}
479 template <
class T1,
class T2>
480 static void abs(T1, T2) {}
481 template <
class T1,
class T2>
482 static void floor(T1, T2) {}
483 template <
class T1,
class T2>
484 static void ceil(T1, T2) {}
485 template <
class T1,
class T2>
486 static void sqrt(T1, T2) {}
487 template <
class T1,
class T2>
488 static bool notEqual(T1, T2) {
return false; }
489 template <
class T1,
class T2>
490 static bool less(T1, T2) {
return false; }
491 template <
class T1,
class T2>
492 static void min(T1, T2) {}
493 template <
class T1,
class T2>
494 static void max(T1, T2) {}
496 static T minimum(T
const * p)
498 return NumericTraits<T>::max();
501 static T maximum(T
const * p)
503 return NumericTraits<T>::min();
510 typedef typename IfBool<(SIZE <= 5), UnrollLoop<SIZE>, ExecLoop<SIZE> >::type type;
516 inline DontInit dontInit() {
return DontInit(); }
520 template <
class T,
int SIZE>
523 template <
class T,
int SIZE>
541 template <
class VALUETYPE,
int SIZE,
class DATA,
class DERIVED>
550 typedef typename detail::LoopType<SIZE>::type Loop;
602 typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult
NormType;
606 enum { static_size = SIZE };
610 template <
class Iterator>
613 vigra_precondition(end-i == SIZE,
614 "TinyVector::init(): Sequence has wrong size.");
615 Loop::assignCast(data_, i);
622 Loop::assignScalar(data_, initial);
627 template <
class T1,
class D1,
class D2>
631 return static_cast<DERIVED &
>(*this);
636 template <
class T1,
class D1,
class D2>
640 return static_cast<DERIVED &
>(*this);
645 template <
class T1,
class D1,
class D2>
649 return static_cast<DERIVED &
>(*this);
654 template <
class T1,
class D1,
class D2>
658 return static_cast<DERIVED &
>(*this);
665 Loop::mulScalar(data_, r);
666 return static_cast<DERIVED &
>(*this);
673 Loop::divScalar(data_, r);
674 return static_cast<DERIVED &
>(*this);
681 return sqrt(
static_cast<typename
682 SquareRootTraits<SquaredNormType>::SquareRootArgument
>(
squaredMagnitude()));
696 return Loop::minimum(data_);
703 return Loop::maximum(data_);
710 VIGRA_ASSERT_INSIDE(i);
718 VIGRA_ASSERT_INSIDE(i);
741 pointer data() {
return data_; }
778 template <
class T,
int SIZE>
780 :
public TinyVectorBase<T, SIZE, T[SIZE], TinyVector<T, SIZE> >
782 typedef TinyVectorBase<T, SIZE, T[SIZE], TinyVector<T, SIZE> > BaseType;
783 typedef typename BaseType::Loop Loop;
800 enum ReverseCopyTag { ReverseCopy };
819 BaseType::data_[0] = detail::RequiresExplicitCast<T>::cast(initial.
x);
820 BaseType::data_[1] = detail::RequiresExplicitCast<T>::cast(initial.
y);
829 BaseType::data_[0] = i1;
830 BaseType::data_[1] = i2;
836 TinyVector(value_type
const & i1, value_type
const & i2, value_type
const & i3)
839 BaseType::data_[0] = i1;
840 BaseType::data_[1] = i2;
841 BaseType::data_[2] = i3;
848 value_type
const & i3, value_type
const & i4)
851 BaseType::data_[0] = i1;
852 BaseType::data_[1] = i2;
853 BaseType::data_[2] = i3;
854 BaseType::data_[3] = i4;
861 value_type
const & i3, value_type
const & i4,
862 value_type
const & i5)
865 BaseType::data_[0] = i1;
866 BaseType::data_[1] = i2;
867 BaseType::data_[2] = i3;
868 BaseType::data_[3] = i4;
869 BaseType::data_[4] = i5;
877 Loop::assignScalar(BaseType::data_, NumericTraits<value_type>::zero());
895 Loop::assign(BaseType::data_, r.data_);
903 Loop::assign(BaseType::data_, data);
917 Loop::reverseAssign(BaseType::data_, data+SIZE-1);
922 template <
class U,
class DATA,
class DERIVED>
926 Loop::assignCast(BaseType::data_, r.
begin());
933 Loop::assign(BaseType::data_, r.data_);
939 template <
class U,
class DATA,
class DERIVED>
942 Loop::assignCast(BaseType::data_, r.
begin());
952 BaseType::data_[0] = detail::RequiresExplicitCast<T>::cast(r.
x);
953 BaseType::data_[1] = detail::RequiresExplicitCast<T>::cast(r.
y);
969 template <
class U,
int USIZE,
class DATA,
class DERIVED>
972 static const int minSize = USIZE < SIZE
976 typedef typename detail::LoopType<minSize>::type MinLoop;
977 MinLoop::assignCast(BaseType::data_, r.
begin());
1011 template <
class T,
int SIZE>
1012 class TinyVectorView
1013 :
public TinyVectorBase<T, SIZE, T *, TinyVectorView<T, SIZE> >
1015 typedef TinyVectorBase<T, SIZE, T *, TinyVectorView<T, SIZE> > BaseType;
1016 typedef typename BaseType::Loop Loop;
1039 BaseType::data_ = 0;
1047 BaseType::data_ =
const_cast<pointer
>(data);
1055 BaseType::data_ =
const_cast<pointer
>(other.data_);
1060 template <
class DATA,
class DERIVED>
1064 BaseType::data_ =
const_cast<pointer
>(other.data());
1071 Loop::assign(BaseType::data_, r.begin());
1077 template <
class U,
class DATA,
class DERIVED>
1080 Loop::assignCast(BaseType::data_, r.
begin());
1103 template <
class V1,
int SIZE,
class D1,
class D2,
class V2,
class D3,
class D4>
1112 template <
class V1,
int SIZE,
class D1,
class D2,
class V2,
class D3,
class D4>
1117 typedef typename detail::LoopType<SIZE>::type ltype;
1118 return ltype::notEqual(l.
begin(), r.
begin());
1122 template <
class V1,
int SIZE,
class D1,
class D2,
class V2,
class D3,
class D4>
1124 operator<(TinyVectorBase<V1, SIZE, D1, D2>
const & l,
1127 typedef typename detail::LoopType<SIZE>::type ltype;
1128 return ltype::less(l.begin(), r.begin());
1138 template <
class V1,
int SIZE,
class DATA,
class DERIVED>
1140 operator<<(std::ostream & out, TinyVectorBase<V1, SIZE, DATA, DERIVED>
const & l)
1144 for(i=0; i<SIZE-1; ++i)
1145 out << l[i] <<
", ";
1203 #if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION)
1205 template <
class T,
int SIZE>
1206 struct NumericTraits<TinyVector<T, SIZE> >
1208 typedef TinyVector<T, SIZE> Type;
1209 typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote;
1210 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote;
1211 typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;
1212 typedef T ValueType;
1214 typedef typename NumericTraits<T>::isIntegral isIntegral;
1215 typedef VigraFalseType isScalar;
1216 typedef typename NumericTraits<T>::isSigned isSigned;
1217 typedef VigraTrueType isOrdered;
1218 typedef VigraFalseType isComplex;
1220 static TinyVector<T, SIZE> zero()
1222 return TinyVector<T, SIZE>(NumericTraits<T>::zero());
1224 static TinyVector<T, SIZE> one()
1226 return TinyVector<T, SIZE>(NumericTraits<T>::one());
1228 static TinyVector<T, SIZE> nonZero()
1230 return TinyVector<T, SIZE>(NumericTraits<T>::nonZero());
1233 static TinyVector<T, SIZE> min()
1235 return TinyVector<T, SIZE>(NumericTraits<T>::min());
1237 static TinyVector<T, SIZE> max()
1239 return TinyVector<T, SIZE>(NumericTraits<T>::max());
1242 template <
class D1,
class D2>
1243 static Promote toPromote(TinyVectorBase<T, SIZE, D1, D2>
const & v)
1248 template <
class D1,
class D2>
1249 static RealPromote toRealPromote(TinyVectorBase<T, SIZE, D1, D2>
const & v)
1251 return RealPromote(v);
1254 template <
class D1,
class D2>
1255 static TinyVector<T, SIZE>
1256 fromPromote(TinyVectorBase<
typename NumericTraits<T>::Promote, SIZE, D1, D2>
const & v)
1258 TinyVector<T, SIZE> res(detail::dontInit());
1259 typedef typename detail::LoopType<SIZE>::type ltype;
1260 ltype::fromPromote(res.begin(), v.begin());
1264 template <
class D1,
class D2>
1265 static TinyVector<T, SIZE>
1266 fromRealPromote(TinyVectorBase<
typename NumericTraits<T>::RealPromote, SIZE, D1, D2>
const & v)
1268 TinyVector<T, SIZE> res(detail::dontInit());
1269 typedef typename detail::LoopType<SIZE>::type ltype;
1270 ltype::fromRealPromote(res.begin(), v.begin());
1275 template <
class T,
int SIZE>
1276 struct NumericTraits<TinyVectorView<T, SIZE> >
1277 :
public NumericTraits<TinyVector<T, SIZE> >
1279 typedef TinyVector<T, SIZE> Type;
1280 typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote;
1281 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote;
1282 typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;
1283 typedef T ValueType;
1285 typedef typename NumericTraits<T>::isIntegral isIntegral;
1286 typedef VigraFalseType isScalar;
1287 typedef typename NumericTraits<T>::isSigned isSigned;
1288 typedef VigraFalseType isOrdered;
1289 typedef VigraFalseType isComplex;
1292 template <
class T,
int SIZE>
1293 struct NormTraits<TinyVector<T, SIZE> >
1295 typedef TinyVector<T, SIZE> Type;
1296 typedef typename Type::SquaredNormType SquaredNormType;
1297 typedef typename Type::NormType NormType;
1300 template <
class T,
int SIZE>
1301 struct NormTraits<TinyVectorView<T, SIZE> >
1303 typedef TinyVector<T, SIZE> Type;
1304 typedef typename Type::SquaredNormType SquaredNormType;
1305 typedef typename Type::NormType NormType;
1308 template <
class T1,
class T2,
int SIZE>
1309 struct PromoteTraits<TinyVector<T1, SIZE>, TinyVector<T2, SIZE> >
1311 typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
1314 template <
class T1,
class T2,
int SIZE>
1315 struct PromoteTraits<TinyVectorView<T1, SIZE>, TinyVectorView<T2, SIZE> >
1317 typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
1320 template <
class T1,
class T2,
int SIZE>
1321 struct PromoteTraits<TinyVectorView<T1, SIZE>, TinyVector<T2, SIZE> >
1323 typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
1326 template <
class T1,
class T2,
int SIZE>
1327 struct PromoteTraits<TinyVector<T1, SIZE>, TinyVectorView<T2, SIZE> >
1329 typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
1332 template <
class T,
int SIZE>
1333 struct PromoteTraits<TinyVector<T, SIZE>, double >
1335 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
1338 template <
class T,
int SIZE>
1339 struct PromoteTraits<double, TinyVector<T, SIZE> >
1341 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
1344 template <
class T,
int SIZE>
1345 struct PromoteTraits<TinyVectorView<T, SIZE>, double >
1347 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
1350 template <
class T,
int SIZE>
1351 struct PromoteTraits<double, TinyVectorView<T, SIZE> >
1353 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
1356 template<
class T,
int SIZE>
1357 struct CanSkipInitialization<TinyVectorView<T, SIZE> >
1359 typedef typename CanSkipInitialization<T>::type type;
1360 static const bool value = type::asBool;
1363 template<
class T,
int SIZE>
1364 struct CanSkipInitialization<TinyVector<T, SIZE> >
1366 typedef typename CanSkipInitialization<T>::type type;
1367 static const bool value = type::asBool;
1372 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1375 #define TINYVECTOR_NUMTRAITS(T, SIZE) \
1377 struct NumericTraits<TinyVector<T, SIZE> >\
1379 typedef TinyVector<T, SIZE> Type;\
1380 typedef TinyVector<NumericTraits<T>::Promote, SIZE> Promote;\
1381 typedef TinyVector<NumericTraits<T>::RealPromote, SIZE> RealPromote;\
1382 typedef TinyVector<NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;\
1383 typedef T ValueType; \
1384 typedef NumericTraits<T>::isIntegral isIntegral;\
1385 typedef VigraFalseType isScalar;\
1386 typedef NumericTraits<T>::isSigned isSigned; \
1387 typedef VigraFalseType isOrdered;\
1388 typedef VigraFalseType isComplex;\
1390 static TinyVector<T, SIZE> zero() { \
1391 return TinyVector<T, SIZE>(NumericTraits<T>::zero()); \
1393 static TinyVector<T, SIZE> one() { \
1394 return TinyVector<T, SIZE>(NumericTraits<T>::one()); \
1396 static TinyVector<T, SIZE> nonZero() { \
1397 return TinyVector<T, SIZE>(NumericTraits<T>::nonZero()); \
1400 static Promote toPromote(TinyVector<T, SIZE> const & v) { \
1401 return Promote(v); \
1403 static RealPromote toRealPromote(TinyVector<T, SIZE> const & v) { \
1404 return RealPromote(v); \
1406 static TinyVector<T, SIZE> fromPromote(Promote const & v) { \
1407 TinyVector<T, SIZE> res;\
1408 TinyVector<T, SIZE>::iterator d = res.begin(), dend = res.end();\
1409 Promote::const_iterator s = v.begin();\
1410 for(; d != dend; ++d, ++s)\
1411 *d = NumericTraits<T>::fromPromote(*s);\
1414 static TinyVector<T, SIZE> fromRealPromote(RealPromote const & v) {\
1415 TinyVector<T, SIZE> res;\
1416 TinyVector<T, SIZE>::iterator d = res.begin(), dend = res.end();\
1417 RealPromote::const_iterator s = v.begin();\
1418 for(; d != dend; ++d, ++s)\
1419 *d = NumericTraits<T>::fromRealPromote(*s);\
1424 struct NormTraits<TinyVector<T, SIZE> >\
1426 typedef TinyVector<T, SIZE> Type;\
1427 typedef Type::SquaredNormType SquaredNormType; \
1428 typedef Type::NormType NormType; \
1431 #define TINYVECTOR_PROMTRAITS1(type1, SIZE) \
1433 struct PromoteTraits<TinyVector<type1, SIZE>, TinyVector<type1, SIZE> > \
1435 typedef TinyVector<PromoteTraits<type1, type1>::Promote, SIZE> Promote; \
1436 static Promote toPromote(TinyVector<type1, SIZE> const & v) { \
1437 return static_cast<Promote>(v); } \
1440 #define TINYVECTOR_PROMTRAITS2(type1, type2, SIZE) \
1442 struct PromoteTraits<TinyVector<type1, SIZE>, TinyVector<type2, SIZE> > \
1444 typedef TinyVector<PromoteTraits<type1, type2>::Promote, SIZE> Promote; \
1445 static Promote toPromote(TinyVector<type1, SIZE> const & v) { \
1446 return static_cast<Promote>(v); } \
1447 static Promote toPromote(TinyVector<type2, SIZE> const & v) { \
1448 return static_cast<Promote>(v); } \
1451 #define TINYVECTOR_TRAITS(SIZE) \
1452 TINYVECTOR_NUMTRAITS(unsigned char, SIZE)\
1453 TINYVECTOR_NUMTRAITS(int, SIZE)\
1454 TINYVECTOR_NUMTRAITS(float, SIZE)\
1455 TINYVECTOR_NUMTRAITS(double, SIZE)\
1456 TINYVECTOR_PROMTRAITS1(unsigned char, SIZE)\
1457 TINYVECTOR_PROMTRAITS1(int, SIZE)\
1458 TINYVECTOR_PROMTRAITS1(float, SIZE)\
1459 TINYVECTOR_PROMTRAITS1(double, SIZE)\
1460 TINYVECTOR_PROMTRAITS2(float, unsigned char, SIZE)\
1461 TINYVECTOR_PROMTRAITS2(unsigned char, float, SIZE)\
1462 TINYVECTOR_PROMTRAITS2(int, unsigned char, SIZE)\
1463 TINYVECTOR_PROMTRAITS2(unsigned char, int, SIZE)\
1464 TINYVECTOR_PROMTRAITS2(int, float, SIZE)\
1465 TINYVECTOR_PROMTRAITS2(float, int, SIZE)\
1466 TINYVECTOR_PROMTRAITS2(double, unsigned char, SIZE)\
1467 TINYVECTOR_PROMTRAITS2(unsigned char, double, SIZE)\
1468 TINYVECTOR_PROMTRAITS2(int, double, SIZE)\
1469 TINYVECTOR_PROMTRAITS2(double, int, SIZE)\
1470 TINYVECTOR_PROMTRAITS2(double, float, SIZE)\
1471 TINYVECTOR_PROMTRAITS2(float, double, SIZE)
1473 TINYVECTOR_TRAITS(2)
1474 TINYVECTOR_TRAITS(3)
1475 TINYVECTOR_TRAITS(4)
1477 #undef TINYVECTOR_NUMTRAITS
1478 #undef TINYVECTOR_PROMTRAITS1
1479 #undef TINYVECTOR_PROMTRAITS2
1480 #undef TINYVECTOR_TRAITS
1482 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1496 template <
class V1,
int SIZE,
class D1,
class D2,
class V2,
class D3,
class D4>
1498 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
1506 template <
class V1,
int SIZE,
class D1,
class D2,
class V2,
class D3,
class D4>
1508 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
1516 template <
class V1,
int SIZE,
class D1,
class D2,
class V2,
class D3,
class D4>
1518 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
1526 template <
class V1,
int SIZE,
class D1,
class D2,
class V2,
class D3,
class D4>
1528 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
1536 template <
class V,
int SIZE,
class D1,
class D2>
1538 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
1541 return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(r) *= v;
1545 template <
class V,
int SIZE,
class D1,
class D2>
1547 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
1550 return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(l) *= v;
1554 template <
class V,
int SIZE,
class D1,
class D2>
1556 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
1559 return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(l) /= v;
1563 template <
class V,
int SIZE,
class D1,
class D2>
1569 typedef typename detail::LoopType<SIZE>::type Loop;
1570 Loop::divScalar(result.data(), v);
1577 template <
class V,
int SIZE,
class D1,
class D2>
1583 typedef typename detail::LoopType<SIZE>::type ltype;
1584 ltype::neg(res.begin(), v.
begin());
1589 template <
class V,
int SIZE,
class D1,
class D2>
1595 typedef typename detail::LoopType<SIZE>::type ltype;
1602 template <
class V,
int SIZE,
class D1,
class D2>
1608 typedef typename detail::LoopType<SIZE>::type ltype;
1615 template <
class V,
int SIZE,
class D1,
class D2>
1621 typedef typename detail::LoopType<SIZE>::type ltype;
1628 template <
class V,
int SIZE,
class D1,
class D2>
1634 typedef typename detail::LoopType<SIZE>::type ltype;
1643 template <
class V,
int SIZE,
class D1,
class D2,
class E>
1649 typedef typename detail::LoopType<SIZE>::type ltype;
1655 template <
class V1,
class D1,
class D2,
class V2,
class D3,
class D4>
1657 TinyVector<typename PromoteTraits<V1, V2>::Promote, 3>
1663 return Res(r1[1]*r2[2] - r1[2]*r2[1],
1664 r1[2]*r2[0] - r1[0]*r2[2],
1665 r1[0]*r2[1] - r1[1]*r2[0]);
1669 template <
class V1,
int SIZE,
class D1,
class D2,
class V2,
class D3,
class D4>
1671 typename PromoteTraits<V1, V2>::Promote
1675 typedef typename detail::LoopType<SIZE>::type ltype;
1680 template <
class V,
int SIZE,
class D1,
class D2>
1682 typename NumericTraits<V>::Promote
1685 typename NumericTraits<V>::Promote res = l[0];
1686 for(
int k=1; k<SIZE; ++k)
1692 template <
class V,
int SIZE,
class D1,
class D2>
1694 TinyVector<typename NumericTraits<V>::Promote, SIZE>
1698 for(
int k=1; k<SIZE; ++k)
1704 template <
class V,
int SIZE,
class D1,
class D2>
1706 typename NumericTraits<V>::Promote
1709 typename NumericTraits<V>::Promote res = l[0];
1710 for(
int k=1; k<SIZE; ++k)
1716 template <
class V,
int SIZE,
class D1,
class D2>
1718 TinyVector<typename NumericTraits<V>::Promote, SIZE>
1722 for(
int k=1; k<SIZE; ++k)
1730 template <
class V1,
int SIZE,
class D1,
class D2,
class V2,
class D3,
class D4>
1732 TinyVector<typename PromoteTraits<V1, V2>::Promote, SIZE>
1736 typedef typename detail::LoopType<SIZE>::type ltype;
1738 ltype::min(res.begin(), r.
begin());
1743 template <
class V1,
int SIZE,
class D1,
class D2>
1745 TinyVector<V1, SIZE>
1746 min(TinyVectorBase<V1, SIZE, D1, D2>
const & l,
1747 TinyVectorBase<V1, SIZE, D1, D2>
const & r)
1749 typedef typename detail::LoopType<SIZE>::type ltype;
1750 TinyVector<V1, SIZE> res(l);
1751 ltype::min(res.begin(), r.begin());
1755 template <
class V1,
int SIZE>
1757 TinyVector<V1, SIZE>
1758 min(TinyVector<V1, SIZE>
const & l,
1759 TinyVector<V1, SIZE>
const & r)
1761 typedef typename detail::LoopType<SIZE>::type ltype;
1762 TinyVector<V1, SIZE> res(l);
1763 ltype::min(res.begin(), r.begin());
1768 template <
class V,
int SIZE,
class D1,
class D2>
1779 template <
class V1,
int SIZE,
class D1,
class D2,
class V2,
class D3,
class D4>
1781 TinyVector<typename PromoteTraits<V1, V2>::Promote, SIZE>
1785 typedef typename detail::LoopType<SIZE>::type ltype;
1787 ltype::max(res.begin(), r.
begin());
1792 template <
class V1,
int SIZE,
class D1,
class D2>
1794 TinyVector<V1, SIZE>
1795 max(TinyVectorBase<V1, SIZE, D1, D2>
const & l,
1796 TinyVectorBase<V1, SIZE, D1, D2>
const & r)
1798 typedef typename detail::LoopType<SIZE>::type ltype;
1799 TinyVector<V1, SIZE> res(l);
1800 ltype::max(res.begin(), r.begin());
1804 template <
class V1,
int SIZE>
1806 TinyVector<V1, SIZE>
1807 max(TinyVector<V1, SIZE>
const & l,
1808 TinyVector<V1, SIZE>
const & r)
1810 typedef typename detail::LoopType<SIZE>::type ltype;
1811 TinyVector<V1, SIZE> res(l);
1812 ltype::max(res.begin(), r.begin());
1817 template <
class V,
int SIZE,
class D1,
class D2>
1826 template <
class V1,
int SIZE,
class D1,
class D2>
1828 typename TinyVectorBase<V1, SIZE, D1, D2>::SquaredNormType
1835 template <
class V,
int SIZE>
1837 typename TinyVector<V, SIZE>::SquaredNormType
1840 return t.squaredMagnitude();
1845 #if defined(_MSC_VER)
1846 #pragma warning( pop )
1850 #undef VIGRA_ASSERT_INSIDE
1851 #endif // VIGRA_TINYVECTOR_HXX