PLearn 0.1
TinyVector.h
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // TinyVector.h: Definition of a tiny vector
00004 // Copyright (c) 2002 by Nicolas Chapados
00005 
00006 // Redistribution and use in source and binary forms, with or without
00007 // modification, are permitted provided that the following conditions are met:
00008 // 
00009 //  1. Redistributions of source code must retain the above copyright
00010 //     notice, this list of conditions and the following disclaimer.
00011 // 
00012 //  2. Redistributions in binary form must reproduce the above copyright
00013 //     notice, this list of conditions and the following disclaimer in the
00014 //     documentation and/or other materials provided with the distribution.
00015 // 
00016 //  3. The name of the authors may not be used to endorse or promote
00017 //     products derived from this software without specific prior written
00018 //     permission.
00019 // 
00020 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00021 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00022 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00023 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00024 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00025 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00026 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00027 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00028 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 // 
00031 // This file is part of the PLearn library. For more information on the PLearn
00032 // library, go to the PLearn Web site at www.plearn.org
00033 
00034 #ifndef TINYVECTOR_H_INC
00035 #define TINYVECTOR_H_INC
00036 
00037 //#include <utility>
00038 //#include <stdexcept>                       // for out_of_range
00039 #include <algorithm>                         // for lexicographical_compare
00040 #include <typeinfo>
00041 
00042 #include "plerror.h"
00043 
00046 namespace PLearn {
00047 using namespace std;
00048 
00050 template <class T> class TinyVectorTrait;
00051 
00052 
00053 //############################  CLASS  TINYVECTOR  ########################
00054 
00072 template < class T, unsigned N, class TTrait = TinyVectorTrait<T> >
00073 class TinyVector
00074 {
00075 public:
00077     typedef T value_type;
00078     typedef size_t size_type;
00079     typedef ptrdiff_t difference_type;
00080 
00081     typedef T* iterator;
00082     typedef const T* const_iterator;
00083         
00084     typedef T* pointer;
00085     typedef const T* const_pointer;
00086     typedef T& reference;
00087     typedef const T& const_reference;
00088 
00089 public:
00091     inline iterator begin();
00092     inline const_iterator begin() const;
00093     inline iterator end();
00094     inline const_iterator end() const;
00095 
00096 public:
00098     inline reference operator[](size_type n);
00099     inline const_reference operator[](size_type n) const;
00100 
00102     reference at(size_type n);
00103     const_reference at(size_type n) const;
00104 
00105     inline reference front();        
00106     inline const_reference front() const;
00107     inline reference back();         
00108     inline const_reference back() const;
00109 
00110 public:
00112     inline TinyVector();
00113     inline explicit TinyVector(size_type n, const T& val=T());
00115 
00116     // (Disabled for now; too many ambiguities)
00117     // //!  Construct/Copy from Input iterator
00118     // template <class In>
00119     // TinyVector(In first, In last)  { assign(first, last); }
00120         
00121     template <class In>
00122     void assign(In first, In last) {
00124         resize(last-first);
00125         for (size_type i=0; first != last && i < N; ++i, ++first)
00126             arr[i] = *first;
00127     }
00128         
00129     inline void assign(size_type n, const T& val);      
00130 
00131 public:
00133     void push_back(const T& x);      
00134     void pop_back();                 
00135 
00136 public:
00138 
00139 public:
00141     size_type size() const;                  
00142     bool empty() const {
00143         return size() == 0;
00144     }
00145     size_type max_size() {
00146         return N;
00147     }
00148     void resize(size_type sz, const T& val=T()); 
00149     void reserve(size_type n);       
00150 
00151 public:
00152     //  Other functions
00153 
00155     void swap(TinyVector&);
00156 
00158     void fill(const T&);
00159 
00161     TinyVector copy() const { return *this; }
00162         
00163 private:
00164     T arr[N];
00165 };
00166 
00167 
00169 template <class T, unsigned N, class TTrait>
00170 bool operator==(const TinyVector<T,N,TTrait>&,
00171                 const TinyVector<T,N,TTrait>&);
00172 
00174 template <class T, unsigned N, class TTrait>
00175 bool operator<(const TinyVector<T,N,TTrait>&,
00176                const TinyVector<T,N,TTrait>&);
00177 
00180 template <class T, unsigned N, class TTrait>
00181 inline bool operator!=(const TinyVector<T,N,TTrait>& x,
00182                        const TinyVector<T,N,TTrait>& y)
00183 {
00184     return !(x == y);
00185 }
00186 
00187 template <class T, unsigned N, class TTrait>
00188 inline bool operator> (const TinyVector<T,N,TTrait>& x,
00189                        const TinyVector<T,N,TTrait>& y)
00190 {
00191     return y < x;
00192 }
00193 
00194 template <class T, unsigned N, class TTrait>
00195 inline bool operator<=(const TinyVector<T,N,TTrait>& x,
00196                        const TinyVector<T,N,TTrait>& y)
00197 {
00198     return !(y < x);
00199 }
00200 
00201 template <class T, unsigned N, class TTrait>
00202 inline bool operator>=(const TinyVector<T,N,TTrait>& x,
00203                        const TinyVector<T,N,TTrait>& y)
00204 {
00205     return !(x < y);
00206 }
00207 
00209 template <class T, unsigned N, class TTrait>
00210 inline void operator<<(TinyVector<T,N,TTrait>& x,
00211                        const TinyVector<T,N,TTrait>& y)
00212 {
00213     x = y;
00214 }
00215 
00216 
00217 //#########################  CLASS  TINYVECTORTRAIT  ######################
00218 
00234 template <typename T> class TinyVectorTrait {};
00235 
00236 template <> class TinyVectorTrait<unsigned char> {
00237 public:
00238     static const unsigned char Missing = UCHAR_MAX;
00239     typedef unsigned IOType;
00240 };
00241 
00242 template <> class TinyVectorTrait<signed char> {
00243 public:
00244     static const signed char Missing = CHAR_MAX;
00245     typedef int IOType;
00246 };
00247 
00248 template <> class TinyVectorTrait<char> {
00249 public:
00250     static const char Missing = CHAR_MAX;
00251     typedef int IOType;
00252 };
00253 
00254 template <> class TinyVectorTrait<unsigned short> {
00255 public:
00256     static const unsigned short Missing = USHRT_MAX;
00257     typedef unsigned short IOType;
00258 };
00259 
00260 template <> class TinyVectorTrait<short> {
00261 public:
00262     static const short Missing = SHRT_MAX;
00263     typedef short IOType;
00264 };
00265 
00266 template <> class TinyVectorTrait<unsigned int> {
00267 public:
00268     static const unsigned int Missing = UINT_MAX;
00269     typedef unsigned IOType;
00270 };
00271 
00272 template <> class TinyVectorTrait<int> {
00273 public:
00274     static const int Missing = INT_MAX;
00275     typedef int IOType;
00276 };
00277 
00278   
00279 //#####  Implementation of Iterators  #####################################
00280 
00281 template <class T, unsigned N, class TTrait>
00282 typename TinyVector<T,N,TTrait>::iterator
00283 TinyVector<T,N,TTrait>::begin()
00284 {
00286     return &arr[0];
00287 }
00288 
00289 template <class T, unsigned N, class TTrait>
00290 typename TinyVector<T,N,TTrait>::const_iterator
00291 TinyVector<T,N,TTrait>::begin() const
00292 {
00294     return &arr[0];
00295 }
00296 
00297 template <class T, unsigned N, class TTrait>
00298 typename TinyVector<T,N,TTrait>::iterator
00299 TinyVector<T,N,TTrait>::end()
00300 {
00301     return &arr[0] + size();
00302 }
00303 
00304 template <class T, unsigned N, class TTrait>
00305 typename TinyVector<T,N,TTrait>::const_iterator
00306 TinyVector<T,N,TTrait>::end() const
00307 {
00308     return &arr[0] + size();
00309 }
00310 
00311 
00312 //#####  Implementation of Element Access  ################################
00313 
00314 template <class T, unsigned N, class TTrait>
00315 typename TinyVector<T,N,TTrait>::reference
00316 TinyVector<T,N,TTrait>::operator[](size_type n)
00317 {
00318 #ifdef BOUNDCHECK
00319     if (n >= size())
00320         PLERROR("%s: out-of-range.",typeid(*this).name());
00321 #endif
00322     return arr[n];
00323 }
00324     
00325 template <class T, unsigned N, class TTrait>
00326 typename TinyVector<T,N,TTrait>::const_reference
00327 TinyVector<T,N,TTrait>::operator[](size_type n) const
00328 {
00329 #ifdef BOUNDCHECK
00330     if (n >= size())
00331         PLERROR("%s: out-of-range.",typeid(*this).name());
00332 #endif
00333     return arr[n];
00334 }
00335     
00336 template <class T, unsigned N, class TTrait>
00337 typename TinyVector<T,N,TTrait>::reference
00338 TinyVector<T,N,TTrait>::at(size_type n)
00339 {
00341     if (n >= size())
00342         PLERROR("%s: out-of-range.",typeid(*this).name());
00343         
00344     return arr[n];
00345 }
00346     
00347 template <class T, unsigned N, class TTrait>
00348 typename TinyVector<T,N,TTrait>::const_reference
00349 TinyVector<T,N,TTrait>::at(size_type n) const
00350 {
00352     if (n >= size())
00353         PLERROR("%s: out-of-range.",typeid(*this).name());
00354         
00355     return arr[n];
00356 }
00357     
00358 template <class T, unsigned N, class TTrait>
00359 typename TinyVector<T,N,TTrait>::reference
00360 TinyVector<T,N,TTrait>::front()
00361 {
00362     if (empty())
00363         PLERROR("%s: out-of-range.",typeid(*this).name());
00364         
00365     return arr[0];
00366 }
00367     
00368 template <class T, unsigned N, class TTrait>
00369 typename TinyVector<T,N,TTrait>::const_reference
00370 TinyVector<T,N,TTrait>::front() const
00371 {
00372     if (empty())
00373         PLERROR("%s: out-of-range.",typeid(*this).name());
00374         
00375     return arr[0];
00376 }
00377     
00378 template <class T, unsigned N, class TTrait>
00379 typename TinyVector<T,N,TTrait>::reference
00380 TinyVector<T,N,TTrait>::back()
00381 {
00382     if (empty())
00383         PLERROR("%s: out-of-range.",typeid(*this).name());
00384         
00385     return *(end()-1);
00386 }
00387     
00388 template <class T, unsigned N, class TTrait>
00389 typename TinyVector<T,N,TTrait>::const_reference
00390 TinyVector<T,N,TTrait>::back() const
00391 {
00392     if (empty())
00393         PLERROR("%s: out-of-range.",typeid(*this).name());
00394         
00395     return *(end()-1);
00396 }
00397     
00398     
00399 //#####  Implementation of Constructors, etc.  ############################
00400 
00401 template <class T, unsigned N, class TTrait>
00402 void TinyVector<T,N,TTrait>::assign(size_type n, const T& val)
00403 {
00404     if (n > N)
00405         PLERROR("%s: out-of-range.",typeid(*this).name());
00406 
00407     resize(n);
00408     for (size_type i=0; i<n; ++i)
00409         arr[i] = val;
00410 }
00411 
00412 template <class T, unsigned N, class TTrait>
00413 TinyVector<T,N,TTrait>::TinyVector()
00414 {
00415     assign(static_cast<size_type>(N), 
00416            static_cast<const T&>(TTrait::Missing));
00417 }
00418 
00419 template <class T, unsigned N, class TTrait>
00420 TinyVector<T,N,TTrait>::TinyVector(size_type n, const T& val)
00421 {
00422     assign(n, val);
00423     if (n<N)
00424         for (size_type i=n; i<N; ++i)
00425             arr[i] = TTrait::Missing;
00426 }
00427 
00428 
00429 //#####  Implementation of Stack Operations  ##############################
00430 
00431 template <class T, unsigned N, class TTrait>
00432 void TinyVector<T,N,TTrait>::push_back(const T& x)
00433 {
00434     size_type s = size();
00435     if (s >= N)
00436         PLERROR("%s: out-of-range.",typeid(*this).name());
00437         
00438     arr[s] = x;
00439 }
00440 
00441 template <class T, unsigned N, class TTrait>
00442 void TinyVector<T,N,TTrait>::pop_back()
00443 {
00444     size_type s = size();
00445     if (s == 0)
00446         PLERROR("%s: out-of-range.",typeid(*this).name());
00447         
00448     arr[s-1] = TTrait::Missing;
00449 }
00450 
00451     
00452 //#####  Implementation of Size/Capacity Operations  ######################
00453 
00454 template <class T, unsigned N, class TTrait>
00455 typename TinyVector<T,N,TTrait>::size_type
00456 TinyVector<T,N,TTrait>::size() const
00457 {
00458     difference_type p = N-1;
00459 
00460     while (p >= 0 && arr[p] == static_cast<T>(TTrait::Missing))
00461         p--;
00462     return p+1;
00463 }
00464 
00465 template <class T, unsigned N, class TTrait>
00466 void TinyVector<T,N,TTrait>::resize(size_type sz, const T& val)
00467 {
00468     if (sz > max_size())
00469         PLERROR("%s: out-of-range.",typeid(*this).name());
00470         
00471     size_type s = size();
00472     while (s < sz)
00473         arr[s++] = val;
00474     while (sz < N)
00475         arr[sz++] = TTrait::Missing;
00476 }
00477     
00478 template <class T, unsigned N, class TTrait>
00479 void TinyVector<T,N,TTrait>::reserve(size_type n)
00480 {
00481     if (n > max_size())
00482         PLERROR("%s: out-of-range.",typeid(*this).name());
00483         
00484 }
00485     
00486 
00487 //#####  Implementation of Other Functions  ###############################
00488 
00489 template <class T, unsigned N, class TTrait>
00490 void TinyVector<T,N,TTrait>::swap(TinyVector<T,N,TTrait>& other)
00491 {
00492     using namespace std;                     
00493 
00494     for (size_type i=0; i<N; ++i)
00495         swap(arr[i], other.arr[i]);
00496 }
00497 
00498 template <class T, unsigned N, class TTrait>
00499 void TinyVector<T,N,TTrait>::fill(const T& value)
00500 {
00501     for (int i=0, n=size() ; i<n ; ++i)
00502         arr[i] = value;
00503 }
00504 
00505 template <class T, unsigned N, class TTrait>
00506 bool operator==(const TinyVector<T,N,TTrait>& x,
00507                 const TinyVector<T,N,TTrait>& y)
00508 {
00509     bool equal = true;
00510     typename TinyVector<T,N,TTrait>::const_iterator
00511         xit=x.begin(), xend=x.end(), yit=y.begin(), yend=y.end();
00512     if (xend-xit != yend-yit)
00513         return false;
00514     for ( ; equal && xit != xend && yit != yend ; ++xit, ++yit)
00515         equal = (*xit == *yit);
00516     return equal;
00517 }
00518 
00519 template <class T, unsigned N, class TTrait>
00520 bool operator<(const TinyVector<T,N,TTrait>& x,
00521                const TinyVector<T,N,TTrait>& y)
00522 {
00523     return std::lexicographical_compare(x.begin(), x.end(),
00524                                         y.begin(), y.end());
00525 }
00526     
00527 } // end of namespace PLearn
00528 
00529 #endif // TINYVECTOR_H_INC
00530 
00531 
00532 /*
00533   Local Variables:
00534   mode:c++
00535   c-basic-offset:4
00536   c-file-style:"stroustrup"
00537   c-file-offsets:((innamespace . 0)(inline-open . 0))
00538   indent-tabs-mode:nil
00539   fill-column:79
00540   End:
00541 */
00542 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines