/************************************************************** ggt-head beg * * GGT: Generic Graphics Toolkit * * Original Authors: * Allen Bierbaum * * ----------------------------------------------------------------- * File: VecBase.h,v * Date modified: 2005/06/06 03:44:49 * Version: 1.20 * ----------------------------------------------------------------- * *********************************************************** ggt-head end */ /*************************************************************** ggt-cpr beg * * GGT: The Generic Graphics Toolkit * Copyright (C) 2001,2002 Allen Bierbaum * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ************************************************************ ggt-cpr end */ #ifndef _GMTL_VECBASE_H_ #define _GMTL_VECBASE_H_ #include #include #include #include #include #include namespace gmtl { #ifndef GMTL_NO_METAPROG namespace meta { struct DefaultVecTag {}; } #endif /** * Base type for vector-like objects including Points and Vectors. It is * templated on the component datatype as well as the number of components that * make it up. * * @param DATA_TYPE the datatype to use for the components * @param SIZE the number of components this VecB has * @param REP the representation to use for the vector. (expression template or default) */ #ifndef GMTL_NO_METAPROG template class VecBase { protected: const REP expRep; // The expression rep public: /// The datatype used for the components of this VecB. typedef DATA_TYPE DataType; /// The number of components this VecB has. enum Params { Size = SIZE }; public: VecBase() {;} VecBase(const REP& rep) : expRep(rep) {;} /** Conversion operator to default vecbase type. */ /* operator VecBase() { return VecBase(*this); } */ /** Return the value at given location. */ inline DATA_TYPE operator [](const unsigned i) { gmtlASSERT(i < SIZE); return expRep[i]; } inline const DATA_TYPE operator [](const unsigned i) const { gmtlASSERT(i < SIZE); return expRep[i]; } }; #endif /** * Specialized version of VecBase that is actually used for all user interaction * with a traditional vector. * * @param DATA_TYPE the datatype to use for the components * @param SIZE the number of components this VecBase has */ template #ifdef GMTL_NO_METAPROG class VecBase #else class VecBase #endif { public: /// The datatype used for the components of this VecBase. typedef DATA_TYPE DataType; #ifdef GMTL_NO_METAPROG typedef VecBase VecType; #else typedef VecBase VecType; #endif /// The number of components this VecBase has. enum Params { Size = SIZE }; public: /** * Default constructor. * Does nothing, leaves data alone. * This is for performance because this constructor is called by derived class constructors * Even when they just want to set the data directly */ VecBase() { #ifdef GMTL_COUNT_CONSTRUCT_CALLS gmtl::helpers::VecCtrCounterInstance()->inc(); #endif } /** * Makes an exact copy of the given VecBase object. * * @param rVec the VecBase object to copy */ VecBase(const VecBase& rVec) { #ifdef GMTL_COUNT_CONSTRUCT_CALLS gmtl::helpers::VecCtrCounterInstance()->inc(); #endif #ifdef GMTL_NO_METAPROG for(unsigned i=0;i >::func(*this, rVec); #endif } #ifndef GMTL_NO_METAPROG template VecBase(const VecBase& rVec) { #ifdef GMTL_COUNT_CONSTRUCT_CALLS gmtl::helpers::VecCtrCounterInstance()->inc(); #endif for(unsigned i=0;iinc(); #endif GMTL_STATIC_ASSERT( SIZE == 2, Invalid_constructor_of_size_2_used); mData[0] = val0; mData[1] = val1; } VecBase(const DATA_TYPE& val0,const DATA_TYPE& val1,const DATA_TYPE& val2) { #ifdef GMTL_COUNT_CONSTRUCT_CALLS gmtl::helpers::VecCtrCounterInstance()->inc(); #endif GMTL_STATIC_ASSERT( SIZE == 3, Invalid_constructor_of_size_3_used ); mData[0] = val0; mData[1] = val1; mData[2] = val2; } VecBase(const DATA_TYPE& val0,const DATA_TYPE& val1,const DATA_TYPE& val2,const DATA_TYPE& val3) { #ifdef GMTL_COUNT_CONSTRUCT_CALLS gmtl::helpers::VecCtrCounterInstance()->inc(); #endif // @todo need compile time assert GMTL_STATIC_ASSERT( SIZE == 4, Invalid_constructor_of_size_4_used); mData[0] = val0; mData[1] = val1; mData[2] = val2; mData[3] = val3; } //@} /** * Sets the components in this VecBase using the given array. * * @param dataPtr the array containing the values to copy * @pre dataPtr has at least SIZE elements */ inline void set(const DATA_TYPE* dataPtr) { #ifdef GMTL_NO_METAPROG for ( unsigned int i = 0; i < SIZE; ++i ) { mData[i] = dataPtr[i]; } #else gmtl::meta::AssignArrayUnrolled::func(&(mData[0]), dataPtr); #endif } //@{ /** * Sets the components in this VecBase to the given values. */ inline void set(const DATA_TYPE& val0) { mData[0] = val0; } inline void set(const DATA_TYPE& val0,const DATA_TYPE& val1) { GMTL_STATIC_ASSERT( SIZE >= 2, Set_out_of_valid_range); mData[0] = val0; mData[1] = val1; } inline void set(const DATA_TYPE& val0,const DATA_TYPE& val1,const DATA_TYPE& val2) { GMTL_STATIC_ASSERT( SIZE >= 3, Set_out_of_valid_range); mData[0] = val0; mData[1] = val1; mData[2] = val2; } inline void set(const DATA_TYPE& val0,const DATA_TYPE& val1,const DATA_TYPE& val2,const DATA_TYPE& val3) { GMTL_STATIC_ASSERT( SIZE >= 4, Set_out_of_valid_range); mData[0] = val0; mData[1] = val1; mData[2] = val2; mData[3] = val3; } //@} //@{ /** * Gets the ith component in this VecBase. * * @param i the zero-based index of the component to access. * @pre i < SIZE * * @return a reference to the ith component */ inline DATA_TYPE& operator [](const unsigned i) { gmtlASSERT(i < SIZE); return mData[i]; } inline const DATA_TYPE& operator [](const unsigned i) const { gmtlASSERT(i < SIZE); return mData[i]; } //@} /** Assign from different rep. */ #ifdef GMTL_NO_METAPROG inline VecType& operator=(const VecBase& rhs) { for(unsigned i=0;i inline VecType& operator=(const VecBase& rhs) { for(unsigned i=0;i >::func(*this, rVec); return *this; } #endif /* Assign from another of same type. inline VecType& operator=(const VecType& rhs) { for(unsigned i=0;i