ofstd/include/dcmtk/ofstd/ofvector.h

00001 /*
00002  *
00003  *  Copyright (C) 2010, OFFIS e.V.
00004  *  All rights reserved.  See COPYRIGHT file for details.
00005  *
00006  *  This software and supporting documentation were developed by
00007  *
00008  *    OFFIS e.V.
00009  *    R&D Division Health
00010  *    Escherweg 2
00011  *    D-26121 Oldenburg, Germany
00012  *
00013  *
00014  *  Module:  ofstd
00015  *
00016  *  Author:  Uli Schlachter
00017  *
00018  *  Purpose: Defines a template vector class based on the STL vector class
00019  *
00020  *  Last Update:      $Author: joergr $
00021  *  Update Date:      $Date: 2010-10-14 13:15:51 $
00022  *  CVS/RCS Revision: $Revision: 1.3 $
00023  *  Status:           $State: Exp $
00024  *
00025  *  CVS/RCS Log at end of file
00026  *
00027  */
00028 
00029 #ifndef OFVECTOR_H
00030 #define OFVECTOR_H
00031 
00032 #include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
00033 
00034 #ifndef HAVE_CLASS_TEMPLATE
00035 #error Your C++ compiler cannot handle class templates:
00036 #endif
00037 
00038 #if defined(HAVE_STL) || defined(HAVE_STL_VECTOR)
00039 
00040 // Use the standard template library (STL) vector class.
00041 #include <vector>
00042 
00043 #ifdef HAVE_STD_NAMESPACE
00044 #define OFVector std::vector
00045 #else
00046 #define OFVector vector
00047 #endif
00048 
00049 #else
00050 
00051 #define INCLUDE_CASSERT          /* for assert() */
00052 #define INCLUDE_CSTDLIB          /* for NULL */
00053 #include "dcmtk/ofstd/ofstdinc.h"
00054 #include "dcmtk/ofstd/oftypes.h" /* for OFBool */
00055 
00060 template<typename T>
00061 class OFVector
00062 {
00063 public:
00065     typedef T        value_type;
00067     typedef size_t   size_type;
00069     typedef T*       iterator;
00071     typedef const T* const_iterator;
00072 
00073 protected:
00074 
00076     T* values_;
00077 
00079     size_type allocated_;
00080 
00084     size_type size_;
00085 
00086 public:
00087 
00089     OFVector() : values_(NULL), allocated_(0), size_(0)
00090     {
00091         reserve(0);
00092     }
00093 
00097     OFVector(const OFVector& other) : values_(NULL), allocated_(0), size_(0)
00098     {
00099         reserve(other.size());
00100         for (const_iterator it = other.begin(); it != other.end(); ++it)
00101             push_back(*it);
00102     }
00103 
00108     explicit OFVector(size_type n, const T& v = T()) : values_(NULL), allocated_(0), size_(0)
00109     {
00110         if (n > 0)
00111             resize(n, v);
00112         else
00113             // Make sure that values_ never is a NULL pointer
00114             reserve(0);
00115     }
00116 
00121     OFVector(const_iterator from, const_iterator to) : values_(NULL), allocated_(0), size_(0)
00122     {
00123         reserve(to - from);
00124         while (from != to)
00125             push_back(*(from++));
00126     }
00127 
00130     ~OFVector()
00131     {
00132         delete[] values_;
00133     }
00134 
00140     OFVector& operator=(const OFVector& other)
00141     {
00142         clear();
00143         reserve(other.size());
00144         for (const_iterator it = other.begin(); it != other.end(); ++it)
00145             push_back(*it);
00146         return *this;
00147     }
00148 
00153     void swap(OFVector& other)
00154     {
00155         T* tmp_val = values_;
00156         size_type tmp_all = allocated_;
00157         size_type tmp_size = size_;
00158 
00159         values_ = other.values_;
00160         allocated_ = other.allocated_;
00161         size_ = other.size_;
00162 
00163         other.values_ = tmp_val;
00164         other.allocated_ = tmp_all;
00165         other.size_ = tmp_size;
00166     }
00167 
00171     iterator begin() { return &values_[0]; }
00172 
00176     const_iterator begin() const { return &values_[0]; }
00177 
00181     iterator end() { return &values_[size_]; }
00182 
00186     const_iterator end() const { return &values_[size_]; }
00187 
00191     size_type size() const { return size_; }
00192 
00196     OFBool empty() const { return size_ == 0; }
00197 
00201     void clear()
00202     {
00203         delete[] values_;
00204         values_ = NULL;
00205         size_ = 0;
00206         allocated_ = 0;
00207         // We must never have values_ == NULL
00208         reserve(0);
00209     }
00210 
00216     void erase(iterator it)
00217     {
00218         size_type idx = it - begin();
00219         for (size_type i = idx + 1; i < size_; i++) {
00220             values_[i - 1] = values_[i];
00221         }
00222         size_--;
00223     }
00224 
00232     iterator insert(iterator it, const T& v)
00233     {
00234         size_type idx = it - begin();
00235         reserve(size_ + 1);
00236         if (idx < size_)
00237             for (size_type i = size_; i > idx; i--) {
00238                 values_[i] = values_[i - 1];
00239             }
00240         values_[idx] = v;
00241         size_++;
00242         return &values_[idx];
00243     }
00244 
00252     template<class InputIterator>
00253     void insert(iterator it, InputIterator from, InputIterator to)
00254     {
00255         while (from != to)
00256         {
00257             it = insert(it, *from);
00258             it++;
00259             from++;
00260         }
00261     }
00262 
00266     void push_back(const T& v)
00267     {
00268         insert(end(), v);
00269     }
00270 
00273     void pop_back()
00274     {
00275         erase(end() - 1);
00276     }
00277 
00283     T& operator[](size_type i)
00284     {
00285         return values_[i];
00286     }
00287 
00293     const T& operator[](size_type i) const
00294     {
00295         return values_[i];
00296     }
00297 
00302     T& at(size_type i)
00303     {
00304         assert(i < size_);
00305         return (*this)[i];
00306     }
00307 
00312     const T& at(size_type i) const
00313     {
00314         assert(i < size_);
00315         return (*this)[i];
00316     }
00317 
00322     void resize(size_type n, T v = T())
00323     {
00324         if (n > size_)
00325         {
00326             reserve(n);
00327             // Set up the new elements
00328             for (size_t i = size_; i < n; i++)
00329                 values_[i] = v;
00330         }
00331         size_ = n;
00332     }
00333 
00339     void reserve(size_type n)
00340     {
00341         T* old_values = values_;
00342         T* new_values;
00343 
00344         if (n == 0)
00345             n = 1;
00346         if (n <= allocated_)
00347             return;
00348 
00349         // While we are at it, let's reserve some extra space
00350         n += 10;
00351 
00352         new_values = new T[n];
00353         if (old_values)
00354         {
00355             for (size_type i = 0; i < size_; i++)
00356                 new_values[i] = old_values[i];
00357             delete[] old_values;
00358         }
00359 
00360         values_ = new_values;
00361         allocated_ = n;
00362     }
00363 };
00364 
00365 #endif
00366 
00367 #endif
00368 
00369 
00370 /*
00371  * CVS/RCS Log:
00372  * $Log: ofvector.h,v $
00373  * Revision 1.3  2010-10-14 13:15:51  joergr
00374  * Updated copyright header. Added reference to COPYRIGHT file.
00375  *
00376  * Revision 1.2  2010-10-08 13:25:33  uli
00377  * Implement OFVector.
00378  *
00379  * Revision 1.1  2010-04-26 11:57:35  joergr
00380  * Added initial definitions for using the STL vector class. Please note that
00381  * there is currently no alternative implementation to this standard class.
00382  *
00383  *
00384  */


Generated on 6 Jan 2011 for OFFIS DCMTK Version 3.6.0 by Doxygen 1.5.1