23 #include <type_traits>
35 #define RESULT_TYPE( ee ) typename std::decay< decltype( ee ) >::type
46 #define VECTOR_VECTOR_ASSIGNMENT_OPERATOR( op ) \
47 template< typename t_OtherType > \
48 inline Vector const& operator op ( Vector< t_OtherType, t_Size > const& other ) { \
49 for ( size_t ii = 0; ii < t_Size; ++ii ) \
50 data[ ii ] op other.data[ ii ]; \
55 #define VECTOR_SCALAR_ASSIGNMENT_OPERATOR( op ) \
56 template< typename t_OtherType > \
57 inline Vector const& operator op ( t_OtherType const& other ) { \
58 for ( size_t ii = 0; ii < t_Size; ++ii ) \
59 data[ ii ] op other; \
95 template<
typename t_Type,
size_t t_Size >
98 typedef t_Type value_type;
101 inline t_Type& operator[](
size_t const index );
102 inline t_Type
const& operator[](
size_t const index )
const;
135 inline t_Type
Sum()
const;
144 inline RESULT_TYPE( std::sqrt( *static_cast< t_Type const* >( NULL ) ) ) Norm()
const;
147 t_Type data[ t_Size ];
151 #undef VECTOR_VECTOR_ASSIGNMENT_OPERATOR
152 #undef VECTOR_SCALAR_ASSIGNMENT_OPERATOR
162 template<
typename t_Type,
size_t t_Size >
165 assert( index < t_Size );
166 return data[ index ];
170 template<
typename t_Type,
size_t t_Size >
173 assert( index < t_Size );
174 return data[ index ];
178 template<
typename t_Type,
size_t t_Size >
181 for (
size_t ii = 0; ii < t_Size; ++ii )
182 data[ ii ] = other.data[ ii ];
187 template<
typename t_Type,
size_t t_Size >
191 for (
size_t ii = 0; ii < t_Size; ++ii )
192 result += data[ ii ];
197 template<
typename t_Type,
size_t t_Size >
201 for (
size_t ii = 0; ii < t_Size; ++ii )
202 result *= data[ ii ];
207 template<
typename t_Type,
size_t t_Size >
210 static_assert( t_Size > 0,
"cannot find Maximum of an empty vector!" );
211 t_Type result = data[ 0 ];
212 for (
size_t ii = 1; ii < t_Size; ++ii )
213 if ( data[ ii ] > result )
219 template<
typename t_Type,
size_t t_Size >
222 static_assert( t_Size > 0,
"cannot find Minimum of an empty vector!" );
223 t_Type result = data[ 0 ];
224 for (
size_t ii = 1; ii < t_Size; ++ii )
225 if ( data[ ii ] < result )
231 template<
typename t_Type,
size_t t_Size >
235 for (
size_t ii = 0; ii < t_Size; ++ii )
236 result +=
Square( data[ ii ] );
241 template<
typename t_Type,
size_t t_Size >
242 RESULT_TYPE( std::sqrt( *static_cast< t_Type const* >( NULL ) ) )
Vector< t_Type, t_Size >::Norm()
const {
244 return std::sqrt( NormSquared() );
256 template<
typename t_LeftType,
typename t_RightType,
size_t t_Size >
260 for (
size_t ii = 0; ii < t_Size; ++ii ) {
262 if ( left.data[ ii ] < right.data[ ii ] ) {
267 else if ( left.data[ ii ] > right[ ii ] ) {
278 template<
typename t_LeftType,
typename t_RightType,
size_t t_Size >
281 RESULT_TYPE( left.data[ 0 ] * right.data[ 0 ] ) result = 0;
282 for (
size_t ii = 0; ii < t_Size; ++ii )
283 result += left.data[ ii ] * right.data[ ii ];
289 template<
typename t_LeftType,
typename t_RightType >
293 left.data[ 1 ] * right.data[ 2 ] - left.data[ 2 ] * right.data[ 1 ],
294 left.data[ 2 ] * right.data[ 0 ] - left.data[ 0 ] * right.data[ 2 ],
295 left.data[ 0 ] * right.data[ 1 ] - left.data[ 1 ] * right.data[ 0 ]
302 template<
typename t_Type,
size_t t_Size >
303 inline std::ostream& operator<<( std::ostream& out, Vector< t_Type, t_Size >
const& vector ) {
308 out << vector.data[ 0 ];
309 for (
size_t ii = 1; ii < t_Size; ++ii )
310 out <<
',' << vector.data[ ii ];
326 #define VECTOR_OPERATOR( op ) \
327 template< typename t_Type, size_t t_Size > \
328 inline Vector< t_Type, t_Size > operator op ( Vector< t_Type, t_Size > const& vector ) { \
329 Vector< t_Type, t_Size > result; \
330 for ( size_t ii = 0; ii < t_Size; ++ii ) \
331 result.data[ ii ] = ( op vector.data[ ii ] ); \
336 #define VECTOR_VECTOR_OPERATOR( op ) \
337 template< typename t_LeftType, typename t_RightType, size_t t_Size > \
338 inline auto operator op ( Vector< t_LeftType, t_Size > const& left, Vector< t_RightType, t_Size > const& right ) -> Vector< RESULT_TYPE( left.data[ 0 ] op right.data[ 0 ] ), t_Size > { \
339 Vector< RESULT_TYPE( left.data[ 0 ] op right.data[ 0 ] ), t_Size > result; \
340 for ( size_t ii = 0; ii < t_Size; ++ii ) \
341 result.data[ ii ] = ( left.data[ ii ] op right.data[ ii ] ); \
346 #define VECTOR_SCALAR_OPERATOR( op ) \
347 template< typename t_LeftType, typename t_RightType, size_t t_Size > \
348 inline auto operator op ( Vector< t_LeftType, t_Size > const& left, t_RightType const& right ) -> Vector< RESULT_TYPE( left.data[ 0 ] op right ), t_Size > { \
349 Vector< RESULT_TYPE( left.data[ 0 ] op right ), t_Size > result; \
350 for ( size_t ii = 0; ii < t_Size; ++ii ) \
351 result.data[ ii ] = ( left.data[ ii ] op right ); \
356 #define SCALAR_VECTOR_OPERATOR( op ) \
357 template< typename t_LeftType, typename t_RightType, size_t t_Size > \
358 inline auto operator op ( t_LeftType const& left, Vector< t_RightType, t_Size > const& right ) -> Vector< RESULT_TYPE( left op right.data[ 0 ] ), t_Size > { \
359 Vector< RESULT_TYPE( left op right.data[ 0 ] ), t_Size > result; \
360 for ( size_t ii = 0; ii < t_Size; ++ii ) \
361 result.data[ ii ] = ( left op right.data[ ii ] ); \
366 #define VECTOR_COMPARISON_OPERATOR( op ) \
367 template< typename t_LeftType, typename t_RightType, size_t t_Size > \
368 inline bool operator op ( Vector< t_LeftType, t_Size > const& left, Vector< t_RightType, t_Size > const& right ) { \
369 return( Compare( left, right ) op 0 ); \
417 #undef VECTOR_VECTOR_OPERATOR
418 #undef VECTOR_SCALAR_OPERATOR
419 #undef SCALAR_VECTOR_OPERATOR
420 #undef VECTOR_COMPARISON_OPERATOR
431 #define VECTOR_FUNCTION( fun ) \
432 template< typename t_Type, size_t t_Size > \
433 inline auto fun( Vector< t_Type, t_Size > const& vector ) -> Vector< RESULT_TYPE( fun( vector.data[ 0 ] ) ), t_Size > { \
434 Vector< RESULT_TYPE( fun( vector.data[ 0 ] ) ), t_Size > result; \
435 for ( size_t ii = 0; ii < t_Size; ++ii ) \
436 result.data[ ii ] = fun( vector.data[ ii ] ); \
441 #define VECTOR_VECTOR_FUNCTION( fun ) \
442 template< typename t_LeftType, typename t_RightType, size_t t_Size > \
443 inline auto fun( Vector< t_LeftType, t_Size > const& left, Vector< t_RightType, t_Size > const& right ) -> Vector< RESULT_TYPE( fun( left.data[ 0 ], right.data[ 0 ] ) ), t_Size > { \
444 Vector< RESULT_TYPE( fun( left.data[ 0 ], right.data[ 0 ] ) ), t_Size > result; \
445 for ( size_t ii = 0; ii < t_Size; ++ii ) \
446 result.data[ ii ] = fun( left.data[ ii ], right.data[ ii ] ); \
451 #define VECTOR_SCALAR_FUNCTION( fun ) \
452 template< typename t_LeftType, typename t_RightType, size_t t_Size > \
453 inline auto fun( Vector< t_LeftType, t_Size > const& left, t_RightType const& right ) -> Vector< RESULT_TYPE( fun( left.data[ 0 ], right ) ), t_Size > { \
454 Vector< RESULT_TYPE( fun( left.data[ 0 ], right ) ), t_Size > result; \
455 for ( size_t ii = 0; ii < t_Size; ++ii ) \
456 result.data[ ii ] = fun( left.data[ ii ], right ); \
461 #define SCALAR_VECTOR_FUNCTION( fun ) \
462 template< typename t_LeftType, typename t_RightType, size_t t_Size > \
463 inline auto fun( t_LeftType const& left, Vector< t_RightType, t_Size > const& right ) -> Vector< RESULT_TYPE( fun( left, right.data[ 0 ] ) ), t_Size > { \
464 Vector< RESULT_TYPE( fun( left, right.data[ 0 ] ) ), t_Size > result; \
465 for ( size_t ii = 0; ii < t_Size; ++ii ) \
466 result.data[ ii ] = fun( left, right.data[ ii ] ); \
518 #undef VECTOR_FUNCTION
519 #undef VECTOR_VECTOR_FUNCTION
520 #undef VECTOR_SCALAR_FUNCTION
521 #undef SCALAR_VECTOR_FUNCTION