#if !defined( INCLUDED_VECTOR_H ) #define INCLUDED_VECTOR_H #include template class BasicVector2 { Element m_elements[2]; public: BasicVector2(){ } template BasicVector2( const BasicVector2& other ){ x() = static_cast( other.x() ); y() = static_cast( other.y() ); } BasicVector2( const Element& x_, const Element& y_ ){ x() = x_; y() = y_; } Element& x(){ return m_elements[0]; } const Element& x() const { return m_elements[0]; } Element& y(){ return m_elements[1]; } const Element& y() const { return m_elements[1]; } const Element& operator[]( std::size_t i ) const { return m_elements[i]; } Element& operator[]( std::size_t i ){ return m_elements[i]; } Element* data(){ return m_elements; } const Element* data() const { return m_elements; } }; /// \brief A 3-element vector. template class BasicVector3 { Element m_elements[3]; public: BasicVector3(){ } template BasicVector3( const BasicVector3& other ){ x() = static_cast( other.x() ); y() = static_cast( other.y() ); z() = static_cast( other.z() ); } template explicit BasicVector3( const BasicVector2& vec2 ){ x() = static_cast( vec2.x() ); y() = static_cast( vec2.y() ); z() = 0; } BasicVector3( const Element& x_, const Element& y_, const Element& z_ ) : m_elements{ x_, y_, z_ }{ } explicit BasicVector3( const Element& value ) : m_elements{ value, value, value }{ } Element& x(){ return m_elements[0]; } const Element& x() const { return m_elements[0]; } Element& y(){ return m_elements[1]; } const Element& y() const { return m_elements[1]; } Element& z(){ return m_elements[2]; } const Element& z() const { return m_elements[2]; } const Element& operator[]( std::size_t i ) const { return m_elements[i]; } Element& operator[]( std::size_t i ){ return m_elements[i]; } Element* data(){ return m_elements; } const Element* data() const { return m_elements; } BasicVector2& vec2(){ return reinterpret_cast&>( x() ); } const BasicVector2& vec2() const { return reinterpret_cast&>( x() ); } void set( const Element value ){ x() = y() = z() = value; } }; /// \brief A 4-element vector. template class BasicVector4 { Element m_elements[4]; public: BasicVector4(){ } BasicVector4( Element x_, Element y_, Element z_, Element w_ ){ x() = x_; y() = y_; z() = z_; w() = w_; } BasicVector4( const BasicVector3& self, Element w_ ){ x() = self.x(); y() = self.y(); z() = self.z(); w() = w_; } Element& x(){ return m_elements[0]; } const Element& x() const { return m_elements[0]; } Element& y(){ return m_elements[1]; } const Element& y() const { return m_elements[1]; } Element& z(){ return m_elements[2]; } const Element& z() const { return m_elements[2]; } Element& w(){ return m_elements[3]; } const Element& w() const { return m_elements[3]; } Element index( std::size_t i ) const { return m_elements[i]; } Element& index( std::size_t i ){ return m_elements[i]; } Element operator[]( std::size_t i ) const { return m_elements[i]; } Element& operator[]( std::size_t i ){ return m_elements[i]; } Element* data(){ return m_elements; } const Element* data() const { return m_elements; } BasicVector3& vec3(){ return reinterpret_cast&>( x() ); } const BasicVector3& vec3() const { return reinterpret_cast&>( x() ); } void set( const Element value ){ x() = y() = z() = w() = value; } }; template inline BasicVector2 vector2_from_array( const Element* array ){ return BasicVector2( array[0], array[1] ); } template inline BasicVector3 vector3_from_array( const Element* array ){ return BasicVector3( array[0], array[1], array[2] ); } template inline Element* vector3_to_array( BasicVector3& self ){ return self.data(); } template inline const Element* vector3_to_array( const BasicVector3& self ){ return self.data(); } template inline Element* vector4_to_array( BasicVector4& self ){ return self.data(); } template inline const Element* vector4_to_array( const BasicVector4& self ){ return self.data(); } template inline BasicVector3& vector4_to_vector3( BasicVector4& self ){ return *reinterpret_cast*>( vector4_to_array( self ) ); } template inline const BasicVector3& vector4_to_vector3( const BasicVector4& self ){ return *reinterpret_cast*>( vector4_to_array( self ) ); } /// \brief A 2-element vector stored in single-precision floating-point. typedef BasicVector2 Vector2; /// \brief A 3-element vector stored in single-precision floating-point. typedef BasicVector3 Vector3; /// \brief A 3-element vector stored in double-precision floating-point. typedef BasicVector3 DoubleVector3; /// \brief A 4-element vector stored in single-precision floating-point. typedef BasicVector4 Vector4; template inline TextOutputStreamType& ostream_write( TextOutputStreamType& outputStream, const Vector3& v ){ return outputStream << '(' << v.x() << ' ' << v.y() << ' ' << v.z() << ')'; } template TextOutputStreamType& ostream_write( TextOutputStreamType& t, const Vector4& v ){ return t << "[ " << v.x() << " " << v.y() << " " << v.z() << " " << v.w() << " ]"; } #endif