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 */