source: projectionDesigner/trunk/projdesigner/include/gmtl/VecBase.h @ 373

Last change on this file since 373 was 4, checked in by Torben Dannhauer, 15 years ago
File size: 8.7 KB
Line 
1/************************************************************** ggt-head beg
2 *
3 * GGT: Generic Graphics Toolkit
4 *
5 * Original Authors:
6 *   Allen Bierbaum
7 *
8 * -----------------------------------------------------------------
9 * File:          VecBase.h,v
10 * Date modified: 2005/06/06 03:44:49
11 * Version:       1.20
12 * -----------------------------------------------------------------
13 *
14 *********************************************************** ggt-head end */
15/*************************************************************** ggt-cpr beg
16*
17* GGT: The Generic Graphics Toolkit
18* Copyright (C) 2001,2002 Allen Bierbaum
19*
20* This library is free software; you can redistribute it and/or
21* modify it under the terms of the GNU Lesser General Public
22* License as published by the Free Software Foundation; either
23* version 2.1 of the License, or (at your option) any later version.
24*
25* This library is distributed in the hope that it will be useful,
26* but WITHOUT ANY WARRANTY; without even the implied warranty of
27* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28* Lesser General Public License for more details.
29*
30* You should have received a copy of the GNU Lesser General Public
31* License along with this library; if not, write to the Free Software
32* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33*
34 ************************************************************ ggt-cpr end */
35#ifndef _GMTL_VECBASE_H_
36#define _GMTL_VECBASE_H_
37
38#include <gmtl/Defines.h>
39#include <gmtl/Util/Assert.h>
40#include <gmtl/Util/StaticAssert.h>
41#include <gmtl/Util/Meta.h>
42#include <gmtl/Config.h>
43#include <gmtl/Helpers.h>
44
45
46namespace gmtl
47{
48
49#ifndef GMTL_NO_METAPROG
50namespace meta
51{
52   struct DefaultVecTag
53   {};
54}
55#endif
56
57
58/**
59 * Base type for vector-like objects including Points and Vectors. It is
60 * templated on the component datatype as well as the number of components that
61 * make it up.
62 *
63 * @param DATA_TYPE  the datatype to use for the components
64 * @param SIZE       the number of components this VecB has
65 * @param REP        the representation to use for the vector.  (expression template or default)
66 */
67#ifndef GMTL_NO_METAPROG
68template<class DATA_TYPE, unsigned SIZE, typename REP=meta::DefaultVecTag>
69class VecBase
70{
71protected:
72   const REP  expRep;      // The expression rep
73
74public:
75   /// The datatype used for the components of this VecB.
76   typedef DATA_TYPE DataType;
77
78   /// The number of components this VecB has.
79   enum Params { Size = SIZE };
80
81public:
82   VecBase()
83   {;}
84
85   VecBase(const REP& rep)
86      : expRep(rep)
87   {;}
88
89   /** Conversion operator to default vecbase type. */
90   /*
91   operator VecBase<DATA_TYPE,SIZE,meta::DefaultVecTag>()
92   {
93      return VecBase<DATA_TYPE,SIZE,meta::DefaultVecTag>(*this);
94   }
95   */
96
97   /** Return the value at given location. */
98   inline DATA_TYPE operator [](const unsigned i)
99   {
100      gmtlASSERT(i < SIZE);
101      return expRep[i];
102   }
103   inline const DATA_TYPE  operator [](const unsigned i) const
104   {
105      gmtlASSERT(i < SIZE);
106      return expRep[i];
107   }
108};
109#endif
110
111
112/**
113 * Specialized version of VecBase that is actually used for all user interaction
114 * with a traditional vector.
115 *
116 * @param DATA_TYPE  the datatype to use for the components
117 * @param SIZE       the number of components this VecBase has
118 */
119template<class DATA_TYPE, unsigned SIZE>
120#ifdef GMTL_NO_METAPROG
121class VecBase
122#else
123class VecBase<DATA_TYPE,SIZE,meta::DefaultVecTag>
124#endif
125{
126public:
127   /// The datatype used for the components of this VecBase.
128   typedef DATA_TYPE DataType;
129
130#ifdef GMTL_NO_METAPROG
131   typedef VecBase<DATA_TYPE, SIZE> VecType;
132#else
133   typedef VecBase<DATA_TYPE, SIZE, meta::DefaultVecTag> VecType;
134#endif
135
136   /// The number of components this VecBase has.
137   enum Params { Size = SIZE };
138
139public:
140   /**
141    * Default constructor.
142    * Does nothing, leaves data alone.
143    * This is for performance because this constructor is called by derived class constructors
144    * Even when they just want to set the data directly
145    */
146   VecBase()
147   {
148#ifdef GMTL_COUNT_CONSTRUCT_CALLS
149      gmtl::helpers::VecCtrCounterInstance()->inc();
150#endif
151   }
152
153   /**
154    * Makes an exact copy of the given VecBase object.
155    *
156    * @param rVec    the VecBase object to copy
157    */
158   VecBase(const VecBase<DATA_TYPE, SIZE>& rVec)
159   {
160#ifdef GMTL_COUNT_CONSTRUCT_CALLS
161      gmtl::helpers::VecCtrCounterInstance()->inc();
162#endif
163#ifdef GMTL_NO_METAPROG
164      for(unsigned i=0;i<SIZE;++i)
165         mData[i] = rVec.mData[i];
166#else
167      gmtl::meta::AssignVecUnrolled<SIZE-1, VecBase<DATA_TYPE,SIZE> >::func(*this, rVec);
168#endif
169   }
170
171#ifndef GMTL_NO_METAPROG
172   template<typename REP2>
173   VecBase(const VecBase<DATA_TYPE, SIZE, REP2>& rVec)
174   {
175#ifdef GMTL_COUNT_CONSTRUCT_CALLS
176      gmtl::helpers::VecCtrCounterInstance()->inc();
177#endif
178      for(unsigned i=0;i<SIZE;++i)
179      {  mData[i] = rVec[i]; }
180   }
181#endif
182
183   //@{
184   /**
185    * Creates a new VecBase initialized to the given values.
186    */
187   VecBase(const DATA_TYPE& val0,const DATA_TYPE& val1)
188   {
189#ifdef GMTL_COUNT_CONSTRUCT_CALLS
190      gmtl::helpers::VecCtrCounterInstance()->inc();
191#endif
192      GMTL_STATIC_ASSERT( SIZE == 2, Invalid_constructor_of_size_2_used);
193      mData[0] = val0; mData[1] = val1;
194   }
195   VecBase(const DATA_TYPE& val0,const DATA_TYPE& val1,const DATA_TYPE& val2)
196   {
197#ifdef GMTL_COUNT_CONSTRUCT_CALLS
198      gmtl::helpers::VecCtrCounterInstance()->inc();
199#endif
200      GMTL_STATIC_ASSERT( SIZE == 3, Invalid_constructor_of_size_3_used );
201      mData[0] = val0;  mData[1] = val1;  mData[2] = val2;
202   }
203   VecBase(const DATA_TYPE& val0,const DATA_TYPE& val1,const DATA_TYPE& val2,const DATA_TYPE& val3)
204   {
205#ifdef GMTL_COUNT_CONSTRUCT_CALLS
206      gmtl::helpers::VecCtrCounterInstance()->inc();
207#endif
208      // @todo need compile time assert
209      GMTL_STATIC_ASSERT( SIZE == 4, Invalid_constructor_of_size_4_used);
210      mData[0] = val0;  mData[1] = val1;  mData[2] = val2;  mData[3] = val3;
211   }
212   //@}
213
214   /**
215    * Sets the components in this VecBase using the given array.
216    *
217    * @param dataPtr    the array containing the values to copy
218    * @pre dataPtr has at least SIZE elements
219    */
220   inline void set(const DATA_TYPE* dataPtr)
221   {
222#ifdef GMTL_NO_METAPROG
223      for ( unsigned int i = 0; i < SIZE; ++i )
224      {
225         mData[i] = dataPtr[i];
226      }
227#else
228      gmtl::meta::AssignArrayUnrolled<SIZE-1, DATA_TYPE>::func(&(mData[0]),
229                                                               dataPtr);
230#endif
231   }
232
233   //@{
234   /**
235    * Sets the components in this VecBase to the given values.
236    */
237   inline void set(const DATA_TYPE& val0)
238   { mData[0] = val0; }
239
240   inline void set(const DATA_TYPE& val0,const DATA_TYPE& val1)
241   {
242      GMTL_STATIC_ASSERT( SIZE >= 2, Set_out_of_valid_range);
243      mData[0] = val0; mData[1] = val1;
244   }
245   inline void set(const DATA_TYPE& val0,const DATA_TYPE& val1,const DATA_TYPE& val2)
246   {
247      GMTL_STATIC_ASSERT( SIZE >= 3, Set_out_of_valid_range);
248      mData[0] = val0;  mData[1] = val1;  mData[2] = val2;
249   }
250   inline void set(const DATA_TYPE& val0,const DATA_TYPE& val1,const DATA_TYPE& val2,const DATA_TYPE& val3)
251   {
252      GMTL_STATIC_ASSERT( SIZE >= 4, Set_out_of_valid_range);
253      mData[0] = val0;  mData[1] = val1;  mData[2] = val2;  mData[3] = val3;
254   }
255   //@}
256
257   //@{
258   /**
259    * Gets the ith component in this VecBase.
260    *
261    * @param i    the zero-based index of the component to access.
262    * @pre i < SIZE
263    *
264    * @return  a reference to the ith component
265    */
266   inline DATA_TYPE& operator [](const unsigned i)
267   {
268      gmtlASSERT(i < SIZE);
269      return mData[i];
270   }
271   inline const DATA_TYPE&  operator [](const unsigned i) const
272   {
273      gmtlASSERT(i < SIZE);
274      return mData[i];
275   }
276   //@}
277
278   /** Assign from different rep. */
279#ifdef GMTL_NO_METAPROG
280   inline VecType& operator=(const VecBase<DATA_TYPE,SIZE>& rhs)
281   {
282      for(unsigned i=0;i<SIZE;++i)
283      {
284         mData[i] = rhs[i];
285      }
286
287      return *this;
288   }
289#else
290   template<typename REP2>
291   inline VecType& operator=(const VecBase<DATA_TYPE,SIZE,REP2>& rhs)
292   {
293      for(unsigned i=0;i<SIZE;++i)
294      {
295         mData[i] = rhs[i];
296      }
297
298      //gmtl::meta::AssignVecUnrolled<SIZE-1, VecBase<DATA_TYPE,SIZE> >::func(*this, rVec);
299      return *this;
300   }
301#endif
302
303   /*
304    Assign from another of same type.
305   inline VecType& operator=(const VecType&  rhs)
306   {
307      for(unsigned i=0;i<SIZE;++i)
308      {
309         mData[i] = rhs[i];
310      }
311      return *this;
312   }
313*/
314
315   //@{
316   /**
317    * Gets the internal array of the components.
318    *
319    * @return  a pointer to the component array with length SIZE
320    */
321   DATA_TYPE* getData()
322   { return mData; }
323   const DATA_TYPE* getData() const
324   { return mData; }
325   //@}
326
327public:
328   /// The array of components.
329   DATA_TYPE mData[SIZE];
330};
331
332
333}
334
335#endif
Note: See TracBrowser for help on using the repository browser.