TDynamicArray.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002 * Copyright (c) 2001 - 2008 Marcus Boerger.  All rights reserved.
00003 *
00004 * This library is free software; you can redistribute it and/or
00005 * modify it under the terms of the GNU Lesser General Public
00006 * License as published by the Free Software Foundation; either
00007 * version 2.1 of the License, or (at your option) any later version.
00008 *
00009 * This library is distributed in the hope that it will be useful,
00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 * Lesser General Public License for more details.
00013 *
00014 * You should have received a copy of the GNU Lesser General Public
00015 * License along with this library; if not, write to the Free Software
00016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00017 * ========================================================================= */
00018 
00019 /* ------------------------------------------------------------------------ */
00020 /* Name:      TDynamicArray.h
00021  *
00022  * Requires:  
00023  * - Mbo.h
00024  * - reallocator.h
00025  */
00035 /* ------------------------------------------------------------------------ */
00036 
00037 #ifndef _TDYNAMICARRAY_H_
00038 #define _TDYNAMICARRAY_H_
00039 
00040 #include "Mbo.h"
00041 
00042 #include "reallocator.h"
00043 
00044 #if defined(_MSC_VER)
00045 # pragma warning(push)
00046 # pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
00047 #endif
00048 
00049 namespace mbo
00050 {
00051 
00062 #ifndef MBO_TDA_VERIFY
00063 # define MBO_TDA_VERIFY 1
00064 #endif
00065 
00074 #ifndef MBO_TDA_STL_ITERATOR
00075 # define MBO_TDA_STL_ITERATOR 1
00076 #endif
00077 
00083 #if MBO_TDA_VERIFY
00084 # define mbo_tda_throw_if_not(exception, condition)  mbo_throw_if_not(exception, condition)
00085 #else
00086 # define mbo_tda_throw_if_not(exception, condition)
00087 #endif
00088 
00089 /* \def __DEPRECATED
00090  * Postfix increment and decrement are marked as deprecated. However they are
00091  * used by the microsoft STL so we do not expose this fact to the compiler.
00092  */
00093 #ifndef __DEPRECATED
00094 # if !MBO_TDA_STL_ITERATOR && !defined(DOXYGEN) && _MSC_VER >= 1300
00095 #  define __DEPRECATED __declspec(deprecated)
00096 # else
00097 #  define __DEPRECATED
00098 # endif
00099 #endif
00100 
00124 template< class  __ValueType
00125         , class  __Allocator                = mem_reallocator<__ValueType>
00126 # if defined(_MSC_VER) && _MSC_VER < 1300
00127         , size_t  __MinSize                 = 8
00128         , size_t  __Append                  = 8
00129 #else
00130         , typename __Allocator::size_type __MinSize  = 8
00131         , typename __Allocator::size_type __Append   = 8
00132 # endif
00133         >
00134 class TDynamicArray
00135 {
00136 public:
00137 
00138     typedef TDynamicArray<__ValueType, __Allocator, __MinSize, __Append>  _MyType;         
00139     typedef typename __Allocator                  allocator;               
00140     typedef typename __Allocator::size_type       size_type;               
00141     typedef typename __Allocator::value_type      value_type;              
00142     typedef typename __Allocator::reference       reference;               
00143     typedef typename __Allocator::const_reference const_reference;         
00144     typedef typename __Allocator::pointer         pointer;                 
00145     typedef typename __Allocator::const_pointer   const_pointer;           
00146     typedef typename __Allocator::difference_type difference_type;         
00148     class iterator; // forward declaration
00149 
00152     class const_iterator
00153 #if MBO_TDA_STL_ITERATOR
00154 # if !defined(_MSC_VER) || _MSC_VER >= 1300 || defined(_STLPORT_VERSION)
00155         : public std::iterator<std::random_access_iterator_tag, value_type, difference_type, const_pointer, const_reference>
00156 # else
00157         : public std::_Ranit<value_type, difference_type>
00158 # endif
00159 #endif
00160     {
00161     public:
00162 
00166         explicit inline const_iterator(const _MyType & array, size_type pos = 0)
00167             : m_array(array), m_pos(pos)
00168         {
00169         }
00170 
00173         inline const_iterator(const const_iterator& oth)
00174             : m_array(oth.m_array), m_pos(oth.m_pos)
00175         {
00176         }
00177 
00180         inline const_iterator(const iterator& oth)
00181             : m_array(oth.m_array), m_pos(oth.m_pos)
00182         {
00183         }
00184 
00187         inline const_reference operator * () const
00188         {
00189             return m_array[m_pos];
00190         }
00191 
00194         inline const_pointer operator -> () const
00195         {
00196             return &(operator*());
00197         }
00198 
00202         inline const_iterator & operator ++ ()
00203         {
00204             ++m_pos;
00205             return *this;
00206         }
00207 
00212         inline __DEPRECATED const_iterator operator ++ (int)
00213         {
00214             /* postfix operator return an unchanged copy prior to the operaration */
00215             return const_iterator(m_array, m_pos++);
00216         }
00217 
00221         inline const_iterator & operator -- ()
00222         {
00223             --m_pos;
00224             return *this;
00225         }
00226 
00231         inline __DEPRECATED const_iterator operator -- (int)
00232         {
00233             /* postfix operator return an unchanged copy prior to the operaration */
00234             return const_iterator(m_array, m_pos--);
00235         }
00236 
00242         inline bool operator == (const const_iterator &rhs) const __THROWS(logic_error)
00243         {
00244             mbo_tda_throw_if_not(logic_error, &m_array == &rhs.m_array);
00245             return m_pos == rhs.m_pos;
00246         }
00247 
00253         inline bool operator != (const const_iterator &rhs) const __THROWS(logic_error)
00254         {
00255             return !operator == (rhs);
00256         }
00257 
00262         inline const_iterator & operator = (const const_iterator & rhs)
00263         {
00264             new (this) const_iterator(rhs.m_array, rhs.m_pos);
00265             return *this;
00266         }
00267 
00272         inline const_reference operator [] (size_type pos) const __THROWS(out_of_range)
00273         {
00274             return m_array[pos];
00275         }
00276 
00282         inline difference_type operator - (const const_iterator & rhs) const __THROWS(logic_error)
00283         {
00284             mbo_tda_throw_if_not(logic_error, &m_array == &rhs.m_array);
00285             return m_pos - rhs.m_pos;
00286         }
00287 
00293         inline const_iterator & operator -= (difference_type diff) __THROWS(logic_error)
00294         {
00295 #if defined(_MSC_VER) && _MSC_VER >= 1300
00296 # pragma warning(disable: 4018) // '>=' : signed/unsigned mismatch
00297 #endif
00298             mbo_tda_throw_if_not(logic_error, m_pos >= diff);
00299             m_pos -= diff;
00300 #if defined(_MSC_VER) && _MSC_VER >= 1300
00301 # pragma warning(disable: 4018) // '>=' : signed/unsigned mismatch
00302 #endif
00303             return *this;
00304         }
00305 
00311         inline const_iterator & operator += (difference_type diff) __THROWS(logic_error)
00312         {
00313 #if defined(_MSC_VER) && _MSC_VER >= 1300
00314 # pragma warning(disable: 4018) // '>=' : signed/unsigned mismatch
00315 #endif
00316             mbo_tda_throw_if_not(logic_error, m_pos + diff >= m_pos && m_pos + diff >= diff && m_pos + diff <= m_array.size());
00317             m_pos += diff;
00318 #if defined(_MSC_VER) && _MSC_VER >= 1300
00319 # pragma warning(default: 4018)
00320 #endif
00321             return *this;
00322         }
00323 
00329         inline const_iterator operator - (difference_type diff) const __THROWS(logic_error)
00330         {
00331 #if defined(_MSC_VER) && _MSC_VER >= 1300
00332 # pragma warning(disable: 4018) // '>=' : signed/unsigned mismatch
00333 #endif
00334             mbo_tda_throw_if_not(logic_error, m_pos >= diff);
00335             return const_iterator(m_array, m_pos - diff);
00336 #if defined(_MSC_VER) && _MSC_VER >= 1300
00337 # pragma warning(disable: 4018) // '>=' : signed/unsigned mismatch
00338 #endif
00339         }
00340 
00346         inline const_iterator operator + (difference_type diff) const __THROWS(logic_error)
00347         {
00348 #if defined(_MSC_VER) && _MSC_VER >= 1300
00349 # pragma warning(disable: 4018) // '>=' : signed/unsigned mismatch
00350 #endif
00351             mbo_tda_throw_if_not(logic_error, m_pos + diff >= m_pos && m_pos + diff >= diff && m_pos + diff <= m_array.size());
00352             return const_iterator(m_array, m_pos + diff);
00353 #if defined(_MSC_VER) && _MSC_VER >= 1300
00354 # pragma warning(default: 4018)
00355 #endif
00356         }
00357 
00363         inline bool operator < (const const_iterator & rhs) const __THROWS(logic_error)
00364         {
00365             mbo_tda_throw_if_not(logic_error, &m_array == &rhs.m_array);
00366             return m_pos < rhs.m_pos;
00367         }
00368 
00374         inline bool operator > (const const_iterator & rhs) const __THROWS(logic_error)
00375         {
00376             mbo_tda_throw_if_not(logic_error, &m_array == &rhs.m_array);
00377             return m_pos > rhs.m_pos;
00378         }
00379 
00385         inline bool operator <= (const const_iterator & rhs) const __THROWS(logic_error)
00386         {
00387             mbo_tda_throw_if_not(logic_error, &m_array == &rhs.m_array);
00388             return m_pos <= rhs.m_pos;
00389         }
00390 
00396         inline bool operator >= (const const_iterator & rhs) const __THROWS(logic_error)
00397         {
00398             mbo_tda_throw_if_not(logic_error, &m_array == &rhsrhs.m_array);
00399             return m_pos >= rhs.m_pos;
00400         }
00401 
00402     protected:
00403         const _MyType &   m_array; 
00404         size_type         m_pos;  
00405     };
00406 
00409     class iterator
00410 #if MBO_TDA_STL_ITERATOR
00411 # if !defined(_MSC_VER) || _MSC_VER >= 1300 || defined(_STLPORT_VERSION)
00412         : public std::iterator<std::random_access_iterator_tag, value_type, difference_type, pointer, reference>
00413 # else
00414         : public std::_Ranit<value_type, difference_type>
00415 # endif
00416 #endif
00417     {
00418     public:
00419 
00423         explicit inline iterator(_MyType & array, size_type pos = 0)
00424             : m_array(array), m_pos(pos)
00425         {
00426         }
00427 
00430         explicit inline iterator(const iterator& oth)
00431             : m_array(oth.m_array), m_pos(oth.m_pos)
00432         {
00433         }
00434 
00437         operator const_iterator()
00438         {
00439             return const_iterator(m_array, m_pos);
00440         }
00441 
00444         inline const_reference operator * () const
00445         {
00446             return m_array[m_pos];
00447         }
00448 
00451         inline reference operator * ()
00452         {
00453             return m_array[m_pos];
00454         }
00455 
00458         inline const_pointer operator -> () const
00459         {
00460             return &(operator*());
00461         }
00462 
00465         inline pointer operator -> ()
00466         {
00467             return &(operator*());
00468         }
00469 
00473         inline iterator & operator ++ ()
00474         {
00475             ++m_pos;
00476             return *this;
00477         }
00478 
00483         inline __DEPRECATED iterator operator ++ (int)
00484         {
00485             /* postfix operator return an unchanged copy prior to the operaration */
00486             return iterator(m_array, m_pos++);
00487         }
00488 
00492         inline iterator & operator -- ()
00493         {
00494             --m_pos;
00495             return *this;
00496         }
00497 
00502         inline __DEPRECATED iterator operator -- (int)
00503         {
00504             /* postfix operator return an unchanged copy prior to the operaration */
00505             return iterator(m_array, m_pos--);
00506         }
00507 
00513         inline bool operator == (const iterator &rhs) const __THROWS(logic_error)
00514         {
00515             mbo_tda_throw_if_not(logic_error, &m_array == &rhs.m_array);
00516             return m_pos == rhs.m_pos;
00517         }
00518 
00524         inline bool operator != (const iterator &rhs) const __THROWS(logic_error)
00525         {
00526             return !operator == (rhs);
00527         }
00528 
00533         inline iterator & operator = (const iterator & rhs)
00534         {
00535             new (this) iterator(rhs.m_array, rhs.m_pos);
00536             return *this;
00537         }
00538 
00543         inline reference operator [] (size_type pos) __THROWS(out_of_range)
00544         {
00545             return m_array[pos];
00546         }
00547 
00552         inline const_reference operator [] (size_type pos) const __THROWS(out_of_range)
00553         {
00554             return m_array[pos];
00555         }
00556 
00562         inline difference_type operator - (const iterator & rhs) const __THROWS(logic_error)
00563         {
00564             mbo_tda_throw_if_not(logic_error, &m_array == &rhs.m_array);
00565             return m_pos - rhs.m_pos;
00566         }
00567 
00573         inline iterator & operator -= (difference_type diff) __THROWS(logic_error)
00574         {
00575 #if defined(_MSC_VER) && _MSC_VER >= 1300
00576 # pragma warning(disable: 4018) // '>=' : signed/unsigned mismatch
00577 #endif
00578             mbo_tda_throw_if_not(logic_error, m_pos >= diff);
00579             m_pos -= diff;
00580 #if defined(_MSC_VER) && _MSC_VER >= 1300
00581 # pragma warning(disable: 4018) // '>=' : signed/unsigned mismatch
00582 #endif
00583             return *this;
00584         }
00585 
00591         inline iterator & operator += (difference_type diff) __THROWS(logic_error)
00592         {
00593 #if defined(_MSC_VER) && _MSC_VER >= 1300
00594 # pragma warning(disable: 4018) // '>=' : signed/unsigned mismatch
00595 #endif
00596             mbo_tda_throw_if_not(logic_error, m_pos + diff >= m_pos && m_pos + diff >= diff && m_pos + diff <= m_array.size());
00597             m_pos += diff;
00598 #if defined(_MSC_VER) && _MSC_VER >= 1300
00599 # pragma warning(default: 4018)
00600 #endif
00601             return *this;
00602         }
00603 
00609         inline iterator operator - (difference_type diff) const __THROWS(logic_error)
00610         {
00611 #if defined(_MSC_VER) && _MSC_VER >= 1300
00612 # pragma warning(disable: 4018) // '>=' : signed/unsigned mismatch
00613 #endif
00614             mbo_tda_throw_if_not(logic_error, m_pos >= diff);
00615             return iterator(m_array, m_pos - diff);
00616 #if defined(_MSC_VER) && _MSC_VER >= 1300
00617 # pragma warning(default: 4018)
00618 #endif
00619         }
00620 
00626         inline iterator operator + (difference_type diff) const __THROWS(logic_error)
00627         {
00628 #if defined(_MSC_VER) && _MSC_VER >= 1300
00629 # pragma warning(disable: 4018) // '>=' : signed/unsigned mismatch
00630 #endif
00631             mbo_tda_throw_if_not(logic_error, m_pos + diff >= m_pos && m_pos + diff >= diff && m_pos + diff <= m_array.size());
00632             return iterator(m_array, m_pos + diff);
00633 #if defined(_MSC_VER) && _MSC_VER >= 1300
00634 # pragma warning(default: 4018)
00635 #endif
00636         }
00637 
00643         inline bool operator < (const iterator & rhs) const __THROWS(logic_error)
00644         {
00645             mbo_tda_throw_if_not(logic_error, &m_array == &rhs.m_array);
00646             return m_pos < rhs.m_pos;
00647         }
00648 
00654         inline bool operator > (const iterator & rhs) const __THROWS(logic_error)
00655         {
00656             mbo_tda_throw_if_not(logic_error, &m_array == &rhs.m_array);
00657             return m_pos > rhs.m_pos;
00658         }
00659 
00665         inline bool operator <= (const iterator & rhs) const __THROWS(logic_error)
00666         {
00667             mbo_tda_throw_if_not(logic_error, &m_array == &rhs.m_array);
00668             return m_pos <= rhs.m_pos;
00669         }
00670 
00676         inline bool operator >= (const iterator & rhs) const __THROWS(logic_error)
00677         {
00678             mbo_tda_throw_if_not(logic_error, &m_array == &rhs.m_array);
00679             return m_pos >= rhs.m_pos;
00680         }
00681 
00682     protected:
00683         _MyType &         m_array; 
00684         size_type         m_pos;  
00685     };
00686 
00687 #if MBO_TDA_STL_ITERATOR
00688 
00691 # if !defined(_MSC_VER) || _MSC_VER >= 1300
00692     typedef std::reverse_iterator<iterator> reverse_iterator;
00693 # else
00694     typedef std::reverse_iterator<iterator, value_type, reference, pointer, difference_type> reverse_iterator;
00695 # endif
00696                                  
00697 
00701 # if !defined(_MSC_VER) || _MSC_VER >= 1300
00702     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00703 # else
00704     typedef std::reverse_iterator<const_iterator, value_type, const_reference, const_pointer, difference_type> const_reverse_iterator;
00705 # endif
00706 #endif
00707 
00718     explicit TDynamicArray(
00719             size_type nMinSize = __MinSize, 
00720             size_type nAppend  = __Append, 
00721             size_type nMaxSize = 0
00722         ) __THROWS(bad_alloc)
00723         : m_alloc()
00724         , m_nSize(0)
00725         , m_nCapacity(nMinSize)
00726         , m_nAppend(  nAppend)
00727         , m_nMaxSize( nMaxSize ? nMaxSize : m_alloc.max_size())
00728         , m_acValues(0L)
00729     {
00730         if (m_nCapacity)
00731         {
00732             reserve(m_nCapacity);
00733         }
00734         mbo_tda_throw_if_not(bad_alloc, !m_nCapacity || m_acValues);
00735     }
00736 
00742     TDynamicArray(const TDynamicArray & oth) __THROWS(bad_alloc)
00743         : m_alloc(oth.m_alloc)
00744         , m_nSize(0)
00745         , m_nCapacity(0)
00746         , m_nAppend(  oth.append())
00747         , m_nMaxSize( oth.max_size())
00748         , m_acValues(0L)
00749     {
00750         assign(oth.begin(), oth.end());
00751     }
00752 
00758     TDynamicArray & operator = (const TDynamicArray & oth) __THROWS(bad_alloc)
00759     {
00760         assign(oth.begin(), oth.end());
00761         return *this;
00762     }
00763 
00768     virtual ~TDynamicArray() __THROWS(logic_error)
00769     {
00770         clear();
00771         mbo_tda_throw_if_not(logic_error, !m_acValues);
00772     }
00773 
00776     inline size_type size() const
00777     {
00778         return m_nSize;
00779     }
00780 
00783     inline bool empty() const
00784     {
00785         return size() == 0;
00786     }
00787 
00790     inline size_type capacity() const
00791     {
00792         return m_nCapacity;
00793     }
00794 
00797     size_type max_size() const
00798     {
00799         return m_nMaxSize;
00800     }
00801 
00804     inline size_type append() const
00805     {
00806         return m_nAppend;
00807     }
00808 
00813     inline const_reference operator [] (_IN size_type index) const __THROWS(out_of_range)
00814     {
00815         mbo_tda_throw_if_not(out_of_range, index < m_nSize);
00816         return m_acValues[index];
00817     }
00818 
00823     inline reference operator [] (_IN size_type index) __THROWS(out_of_range)
00824     {
00825         mbo_tda_throw_if_not(out_of_range, index < m_nSize);
00826         return m_acValues[index];
00827     }
00828 
00833     inline const_reference at(_IN size_type index) const __THROWS(out_of_range)
00834     {
00835         return operator [] (index);
00836     }
00837 
00842     inline reference at(_IN size_type index) __THROWS(out_of_range)
00843     {
00844         return operator [] (index);
00845     }
00846 
00850     inline const_reference back() const __THROWS(out_of_range)
00851     {
00852         mbo_tda_throw_if_not(out_of_range, m_nSize > 0);
00853         return m_acValues[m_nSize-1];
00854     }
00855 
00859     inline reference back() __THROWS(out_of_range)
00860     {
00861         mbo_tda_throw_if_not(out_of_range, m_nSize > 0);
00862         return m_acValues[m_nSize-1];
00863     }
00864 
00868     inline const_reference front() const __THROWS(out_of_range)
00869     {
00870         mbo_tda_throw_if_not(out_of_range, m_nSize > 0);
00871         return m_acValues[0];
00872     }
00873 
00877     inline reference front() __THROWS(out_of_range)
00878     {
00879         mbo_tda_throw_if_not(out_of_range, m_nSize > 0);
00880         return m_acValues[0];
00881     }
00882 
00889     inline void push_front(_IN const_reference value) __THROW2(bad_alloc, overflow_error)
00890     {
00891         check_resize();
00892         
00893         if (m_nSize)
00894         {
00895             m_alloc.move(m_alloc.address(m_acValues[1]), m_alloc.address(m_acValues[0]), m_nSize);
00896         }
00897         
00898         ++m_nSize;
00899         insert_at(0, value);
00900     }
00901     
00905     inline void pop_front() __THROWS(out_of_range)
00906     {
00907         mbo_tda_throw_if_not(out_of_range, m_nSize > 0);
00908 
00909         delete_at(0);
00910 
00911         if (--m_nSize)
00912         {
00913             m_alloc.move(m_alloc.address(m_acValues[0]), m_alloc.address(m_acValues[1]), m_nSize);
00914         }
00915     }
00916     
00923     inline void push_back(_IN const_reference value) __THROW2(bad_alloc, overflow_error)
00924     {
00925         check_resize();
00926 
00927         insert_at(m_nSize++, value);
00928     }
00929 
00933     inline void pop_back() __THROWS(out_of_range)
00934     {
00935         mbo_tda_throw_if_not(out_of_range, m_nSize > 0);
00936         delete_at(m_nSize-1);
00937         --m_nSize;
00938     }
00939 
00942     inline const_iterator begin() const
00943     {
00944         return const_iterator(*this, 0);
00945     }
00946 
00949     inline iterator begin()
00950     {
00951         return iterator(*this, 0);
00952     }
00953 
00956     inline const_iterator end() const
00957     {
00958         return const_iterator(*this, m_nSize);
00959     }
00960 
00963     inline iterator end()
00964     {
00965         return iterator(*this, m_nSize);
00966     }
00967 
00968 #if MBO_TDA_STL_ITERATOR
00969 
00973     inline const_reverse_iterator rbegin() const
00974     {
00975         return const_reverse_iterator(end());
00976     }
00977 
00981     inline reverse_iterator rbegin()
00982     {
00983         return reverse_iterator(end());
00984     }
00985 
00989     inline const_reverse_iterator rend() const
00990     {
00991         return const_reverse_iterator(begin());
00992     }
00993 
00997     inline reverse_iterator rend()
00998     {
00999         return reverse_iterator(begin());
01000     }
01001 #endif
01002 
01007     void assign(size_type count, const_reference val)
01008     {
01009         clear();
01010         if (count > capacity())
01011         {
01012             reserve(count);
01013         }
01014         while(count--)
01015         {
01016             push_back(val);
01017         }
01018     }
01019 
01024     template<class InputIterator>
01025     void assign(InputIterator first, InputIterator end)
01026     {
01027         clear();
01028         if (static_cast<size_type>(end - first) > capacity())
01029         {
01030             reserve(end - first);
01031         }
01032         while(first != end)
01033         {
01034             push_back(*first);
01035             ++first;
01036         }
01037     }
01038 
01044     void erase(size_t where)
01045     {
01046         mbo_tda_throw_if_not(logic_error, where < m_nSize);
01047         if (where == 0)
01048         {
01049             pop_front();
01050         }
01051         else if (where + 1 == m_nSize)
01052         {
01053             pop_back();
01054         }
01055         else
01056         {
01057             delete_at(where);
01058 
01059             if (--m_nSize)
01060             {
01061                 m_alloc.move(m_alloc.address(m_acValues[where]), m_alloc.address(m_acValues[where+1]), m_nSize - where);
01062             }
01063         }
01064     }
01065 
01071     iterator erase(iterator where)
01072     {
01073         erase(where - begin());
01074         return where;
01075     }
01076 
01082     iterator erase(iterator first, iterator end)
01083     {
01084         size_type nLength = end - first;
01085 
01086         if (nLength == 1)
01087         {
01088             return erase(first);
01089         }
01090         else if (nLength)
01091         {
01092             size_type nStart = first - begin();
01093             size_type nPos   = nStart + nLength;
01094 
01095             while(nPos > nStart)
01096             {
01097                 delete_at(--nPos);
01098             }
01099 
01100             m_nSize -= nLength;
01101 
01102             if (m_nSize)
01103             {
01104                 m_alloc.move(m_alloc.address(m_acValues[nStart]), m_alloc.address(m_acValues[nStart + nLength]), m_nSize - nStart);
01105             }
01106         }
01107         return first;
01108     }
01109 
01115     inline void clear()
01116     {
01117         while(m_nSize)
01118         {
01119             m_alloc.destroy(m_alloc.address(m_acValues[--m_nSize]));
01120         }
01121         if (m_acValues)
01122         {
01123             m_alloc.deallocate(m_acValues, m_nCapacity);
01124             m_acValues = 0L;
01125             m_nCapacity = 0;
01126         }
01127     }
01128 
01136     inline reserve(size_type nNewCapacity) __THROW2(bad_alloc, overflow_error)
01137     {
01138         mbo_tda_throw_if_not(overflow_error, nNewCapacity >= m_nSize && nNewCapacity <= max_size());
01139 
01140         pointer pNewValues = m_alloc.reallocate(m_acValues, m_nCapacity, nNewCapacity);
01141 
01142         mbo_tda_throw_if_not(bad_alloc, pNewValues || !nNewCapacity);
01143 
01144         m_acValues = pNewValues;
01145         m_nCapacity = nNewCapacity;
01146     }
01147 
01157     void resize(size_type nNewSize) __THROW2(bad_alloc, overflow_error)
01158     {
01159         resize(nNewSize, value_type());
01160     }
01161 
01172     void resize(size_type nNewSize, value_type value) __THROW2(bad_alloc, overflow_error)
01173     {
01174         while(size() < nNewSize)
01175         {
01176             push_back(value);
01177         }
01178         while(size() > nNewSize)
01179         {
01180             pop_back();
01181         }
01182     }
01183 
01188     inline void limit_size(size_type nNewSize)
01189     {
01190         while(size() > nNewSize)
01191         {
01192             pop_back();
01193         }
01194     }
01195 
01196 protected:
01197 
01204     inline void check_resize() __THROW2(bad_alloc, overflow_error)
01205     {   
01206         if (m_nSize == m_nCapacity)
01207         {
01208             mbo_tda_throw_if_not(overflow_error, m_nSize + m_nAppend > m_nSize);
01209 
01210             reserve(m_nSize + m_nAppend);
01211         }
01212     }
01213 
01221     inline void delete_at(size_type nPos) __THROWS(out_of_range)
01222     {
01223         mbo_tda_throw_if_not(out_of_range, nPos < m_nSize);
01224         m_alloc.destroy(m_alloc.address(m_acValues[nPos]));
01225     }
01226 
01235     inline void insert_at(size_type nPos, _IN const_reference value) __THROWS(out_of_range)
01236     {
01237         mbo_tda_throw_if_not(out_of_range, nPos < m_nSize);
01238         m_alloc.construct(m_alloc.address(m_acValues[nPos]), value);
01239     }
01240 
01241     allocator       m_alloc;        
01242     size_type       m_nSize;        
01243     size_type       m_nCapacity;    
01244     size_type       m_nAppend;      
01245     size_type       m_nMaxSize;     
01246     pointer         m_acValues;     
01247 };
01248 
01249 }; // namespace mbo
01250 
01251 #if defined(_MSC_VER)
01252 # pragma warning(pop)
01253 #endif
01254 
01255 #endif // _TDYNAMICARRAY_H_

  Hosted on code.google.com  
© Marcus Börger
Generated on Fri Jan 18 21:21:08 2008 for MBO-lib by doxygen 1.5.4