value.h

00001 #ifndef AFL_VALUET_H
00002 #define AFL_VALUET_H
00003 
00004 #include "exc/invalidargumentexception.h"
00005 #include "exc/outofboundsexception.h"
00006 #include "ddf/geometry.h"
00007 #include "ddf/ddf.h"
00008 #include <vector>
00009 #include <sstream>
00010 
00011 namespace afl
00012 {
00018     template <typename T>
00019     class ValueT
00020     {
00021         private:
00022             template <typename R>
00023             class ValueRow
00024             {
00025                 friend class ValueT<R>;
00026 
00027                 public:
00033                     ValueRow(ValueT<R>* parent, size_t row) 
00034                         : _parent(parent), _cparent(NULL), _r(row) 
00035                     { 
00036                         if (_r > _parent->getRows()) 
00037                             throw exc::OutOfBoundsException("value row is beyond size of value"); 
00038                     }
00039 
00045                     ValueRow(const ValueT<R>* parent, size_t row) 
00046                         : _parent(NULL), _cparent(parent), _r(row) 
00047                     { 
00048                         if (_r > _cparent->getRows()) 
00049                             throw exc::OutOfBoundsException("value row is beyond size of value"); 
00050                     }
00051                     
00057                     operator const T&() const
00058                     {
00059                         if (_parent->_c != 1)
00060                             throw exc::InvalidArgumentException("Only a Nx1 value can be dereferenced as a vector");
00061 
00062                         return _parent->_v[_r];
00063                     }
00064 
00070                     operator T&() 
00071                     {
00072                         if (_parent->_c != 1)
00073                             throw exc::InvalidArgumentException("Only a Nx1 value can be dereferenced as a vector");
00074 
00075                         return _parent->_v[_r];
00076                     }
00077 
00086                     const T& operator[](size_t c) const 
00087                     { 
00088                         if (c >= _cparent->_c) 
00089                             throw exc::OutOfBoundsException("value out of bounds"); 
00090 
00091                         return  _cparent->_v[_r * _cparent->_c + c];
00092                     }
00093 
00102                     T& operator[](size_t c) 
00103                     { 
00104                         if (c >= _parent->_c) 
00105                         {
00106                             std::ostringstream oss;
00107                             oss << "value out of bounds: There are " << _parent->_c << " columns, and you asked for column #" << c ;
00108                             throw exc::OutOfBoundsException(oss.str()); 
00109                         }
00110                         return  _parent->_v[_r * _parent->_c + c];
00111                     }
00112 
00113                 private:
00114                     ValueT<R>* _parent;
00115                     const ValueT<R>* _cparent;
00116                     size_t _r;
00117 
00118             };
00119 
00120             friend class ValueRow<T>;
00121 
00123         public:
00124 
00128             ValueT(  ) 
00129                 : _v(), _c(0) 
00130             {
00131             }
00132 
00137             ValueT( const T& d ) 
00138                 : _v(), _c(1)
00139             {
00140                 _v.push_back(d);
00141             }
00142 
00148             ValueT( const T& x, const T& y ) 
00149                 : _v(), _c(1)
00150             {
00151                 _v.push_back(x);
00152                 _v.push_back(y);
00153             }
00154 
00161             ValueT( const T& x, const T& y, const T& z ) 
00162                 : _v(), _c(1)
00163             {
00164                 _v.push_back(x);
00165                 _v.push_back(y);
00166                 _v.push_back(z);
00167             }
00168 
00176             ValueT( const T& x, const T& y, const T& z, const T& t ) 
00177                 : _v(), _c(1)
00178             {
00179                 _v.push_back(x);
00180                 _v.push_back(y);
00181                 _v.push_back(z);
00182                 _v.push_back(t);
00183             }
00184 
00189             explicit ValueT( const ddf::Geometry* geom );
00190 
00195             explicit ValueT( const ddf::Geometry& geom );
00196 
00200             ddf::Geometry getGeometry(  ) const
00201             {
00202                 return ddf::Geometry(_v.size()/_c, _c);
00203             }
00204 
00208             ~ValueT(  ) {  }
00209 
00214             ValueT( const ValueT<T>& c ) : _v(c._v), _c(c._c) { }
00215 
00221             ValueT<T>& operator=( const ValueT<T>& c) 
00222             { 
00223                 if (&c == this)
00224                     return *this;
00225 
00226                 _v = c._v; 
00227                 _c = c._c; 
00228                 return *this; 
00229             }
00230 
00234             size_t getRows(  ) const { return _v.size() / _c; }
00235 
00239             size_t getColumns(  ) const { return _c; } 
00240 
00248             const T& at( size_t r, size_t c = 0 ) const
00249             {
00250                 if ( c > _c || r*_c+c > _v.size())
00251                     throw exc::OutOfBoundsException("at() is out of bounds");
00252 
00253                 return _v[r*_c+c];
00254             }
00255 
00263             T& at( size_t r, size_t c = 0 )
00264             {
00265                 if ( c > _c || r*_c+c > _v.size())
00266                     throw exc::OutOfBoundsException("at() is out of bounds");
00267 
00268                 return _v[r*_c+c];
00269             }
00270 
00277             const ValueRow<T> operator[](size_t r) const { return ValueRow<T>(this, r); } 
00278 
00285             ValueRow<T> operator[](size_t r) { return ValueRow<T>(this, r); } 
00286 
00292             operator const T&() const
00293             {
00294                 //std::cerr << "the size of _v is " << _v.size() << std::endl;
00295 
00296                 if (_v.size() != 1)
00297                 {
00298                     std::ostringstream oss;
00299                     oss << _v.size();
00300                     //std::cerr << (char*)(10) << std::endl;
00301 
00302                     throw exc::InvalidArgumentException("Only a 1x1 value can be dereferenced as a scalar. The value has " + oss.str() + " elements");
00303                 }
00304 
00305                 return _v[0];
00306             }
00307 
00313             operator T&() 
00314             {
00315                 //std::cerr << "the size of _v is " << _v.size() << std::endl;
00316 
00317                 if (_v.size() != 1)
00318                 {
00319                     std::ostringstream oss;
00320                     oss << _v.size();
00321                     //std::cerr << (char*)(10) << std::endl;
00322 
00323                     throw exc::InvalidArgumentException("Only a 1x1 value can be dereferenced as a scalar. The value has " + oss.str() + " elements");
00324                 }
00325 
00326                 return _v[0];
00327             }
00328 
00334             std::string geomString(  ) const
00335             {
00336                 if (_c == 3)
00337                     return "tensor3D";
00338                 if (_c == 2)
00339                     return "tensor2D";
00340                 size_t rows = _v.size() / _c;
00341                 if (rows == 3)
00342                     return "vector3D";
00343                 if (rows == 2)
00344                     return "vector2D";
00345                 return "scalar";
00346             }
00347             
00354             ValueT<T>& operator+=( const ValueT<T>& v )
00355             {
00356                 if (_c != v._c || _v.size() != v._v.size())
00357                         throw exc::InvalidArgumentException("can't add values of differing geometries");
00358             
00359                 for (size_t i = 0 ; i < _v.size() ; ++i)
00360                     _v[i] += v._v[i];
00361                 
00362                 return *this;
00363             }
00364 
00371             ValueT<T>& operator/=( const data_t& div )
00372             {
00373                 for (size_t i = 0 ; i < _v.size() ; ++i)
00374                     _v[i] /= div;
00375                 
00376                 return *this;
00377             }
00378 
00385             ValueT<T>& operator*=( const data_t& multiplier )
00386             {
00387                 for (size_t i = 0 ; i < _v.size() ; ++i)
00388                     _v[i] *= multiplier;
00389                 
00390                 return *this;
00391             }
00392 
00400             bool operator==( const ValueT<T>& lhs ) const
00401             {
00402                 if (_c != lhs._c || _v.size() != lhs._v.size())
00403                     return false;
00404             
00405                 for (size_t i = 0 ; i < _v.size() ; ++i)
00406                     if (_v[i] != lhs._v[i])
00407                         return false;
00408                 
00409                 return true;
00410             }
00411 
00419             bool operator!=( const ValueT<T>& lhs ) const
00420             {
00421                 return ! (*this == lhs);
00422             }
00423 
00425         protected:
00429             std::vector<T> _v;
00430 
00436             size_t _c;
00437     };
00438 
00439 }
00440 
00441 #endif // AFL_VALUET_H
00442 

Generated on Fri Dec 22 07:17:50 2006 for afl by  doxygen 1.4.6