00001 /* 00002 * Copyright 1999-2004 The Apache Software Foundation. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00022 #if !defined(XALANVECTOR_HEADER_GUARD_1357924680) 00023 #define XALANVECTOR_HEADER_GUARD_1357924680 00024 00025 00026 00027 // Base include file. Must be first. 00028 #include <xalanc/Include/PlatformDefinitions.hpp> 00029 00030 00031 #include <xalanc/Include/XalanMemoryManagement.hpp> 00032 #include <xalanc/Include/XalanMemMgrAutoPtr.hpp> 00033 00034 00035 #include <cstddef> 00036 #include <algorithm> 00037 #include <cassert> 00038 #include <new> 00039 #include <iterator> 00040 #include <stdexcept> 00041 00042 00043 00044 00045 00046 XALAN_CPP_NAMESPACE_BEGIN 00047 00048 00049 #if defined(_MSC_VER) 00050 #pragma warning(push) 00051 #pragma warning(disable: 4100) 00052 #endif 00053 00054 template <class Type, class ConstructionTraits = MemoryManagedConstructionTraits<Type> > 00055 class XalanVector 00056 { 00057 public: 00058 00059 00060 typedef Type value_type; 00061 typedef value_type* pointer; 00062 typedef const value_type* const_pointer; 00063 typedef value_type& reference; 00064 typedef const value_type& const_reference; 00065 typedef size_t size_type; 00066 typedef ptrdiff_t difference_type; 00067 00068 #if defined(XALAN_VCPP_USE_PTRIT) 00069 typedef std::_Ptrit< 00070 Type, 00071 ptrdiff_t, 00072 pointer, 00073 reference, 00074 pointer, 00075 reference> iterator; 00076 00077 typedef std::_Ptrit< 00078 Type, 00079 ptrdiff_t, 00080 const_pointer, 00081 const_reference, 00082 pointer, 00083 reference> const_iterator; 00084 #else 00085 typedef value_type* iterator; 00086 typedef const value_type* const_iterator; 00087 #endif 00088 00089 #if defined(XALAN_HAS_STD_ITERATORS) 00090 typedef XALAN_STD_QUALIFIER reverse_iterator<iterator> reverse_iterator_; 00091 typedef XALAN_STD_QUALIFIER reverse_iterator<const_iterator> const_reverse_iterator_; 00092 #elif defined(XALAN_RW_NO_CLASS_PARTIAL_SPEC) 00093 typedef XALAN_STD_QUALIFIER reverse_iterator< 00094 iterator, 00095 XALAN_STD_QUALIFIER random_access_iterator_tag, 00096 value_type> reverse_iterator_; 00097 typedef XALAN_STD_QUALIFIER reverse_iterator< 00098 const_iterator, 00099 XALAN_STD_QUALIFIER random_access_iterator_tag, 00100 const value_type> const_reverse_iterator_; 00101 #else 00102 typedef XALAN_STD_QUALIFIER reverse_iterator<iterator, value_type> reverse_iterator_; 00103 typedef XALAN_STD_QUALIFIER reverse_iterator<const_iterator, value_type, const_reference> const_reverse_iterator_; 00104 #endif 00105 00106 typedef reverse_iterator_ reverse_iterator; 00107 typedef const_reverse_iterator_ const_reverse_iterator; 00108 00109 typedef XalanVector<value_type, ConstructionTraits> ThisType; 00110 00111 typedef typename ConstructionTraits::Constructor Constructor; 00112 00113 XalanVector( 00114 MemoryManagerType& theManager XALAN_DEFAULT_CONSTRACTOR_MEMORY_MGR, 00115 size_type initialAllocation = size_type(0)) : 00116 m_memoryManager(&theManager), 00117 m_size(0), 00118 m_allocation(initialAllocation), 00119 m_data(initialAllocation > 0 ? allocate(initialAllocation) : 0) 00120 { 00121 invariants(); 00122 } 00123 00124 static XalanVector* 00125 create( 00126 MemoryManagerType& theManager, 00127 size_type initialAllocation = size_type(0)) 00128 { 00129 typedef XalanVector ThisType; 00130 00131 XalanMemMgrAutoPtr<ThisType, false> theGuard( theManager , (ThisType*)theManager.allocate(sizeof(ThisType))); 00132 00133 ThisType* theResult = theGuard.get(); 00134 00135 new (theResult) ThisType(theManager, initialAllocation); 00136 00137 theGuard.release(); 00138 00139 return theResult; 00140 } 00141 00142 XalanVector( 00143 const ThisType& theSource, 00144 MemoryManagerType& theManager XALAN_DEFAULT_CONSTRACTOR_MEMORY_MGR, 00145 size_type theInitialAllocation = size_type(0)) : 00146 m_memoryManager(&theManager), 00147 m_size(0), 00148 m_allocation(0), 00149 m_data(0) 00150 { 00151 if (theSource.m_size > 0) 00152 { 00153 ThisType theTemp(theManager, local_max(theSource.m_size, theInitialAllocation)); 00154 00155 theTemp.insert(theTemp.begin(), theSource.begin(), theSource.end()); 00156 00157 swap(theTemp); 00158 00159 } 00160 else if (theInitialAllocation > 0) 00161 { 00162 m_data = allocate(theInitialAllocation); 00163 00164 m_allocation = theInitialAllocation; 00165 } 00166 00167 invariants(); 00168 } 00169 00170 XalanVector( 00171 const_iterator theFirst, 00172 const_iterator theLast, 00173 MemoryManagerType& theManager) : 00174 m_memoryManager(&theManager), 00175 m_size(0), 00176 m_allocation(0), 00177 m_data(0) 00178 00179 { 00180 ThisType theTemp(theManager); 00181 00182 theTemp.insert(theTemp.begin(), theFirst, theLast); 00183 00184 swap(theTemp); 00185 00186 invariants(); 00187 } 00188 00189 static XalanVector* 00190 create( 00191 const_iterator theFirst, 00192 const_iterator theLast, 00193 MemoryManagerType& theManager) 00194 { 00195 typedef XalanVector ThisType; 00196 00197 XalanMemMgrAutoPtr<ThisType, false> theGuard( theManager , (ThisType*)theManager.allocate(sizeof(ThisType))); 00198 00199 ThisType* theResult = theGuard.get(); 00200 00201 new (theResult) ThisType(theFirst, theLast, theManager); 00202 00203 theGuard.release(); 00204 00205 return theResult; 00206 } 00207 XalanVector( 00208 size_type theInsertSize, 00209 const value_type& theData, 00210 MemoryManagerType& theManager) : 00211 m_memoryManager(&theManager), 00212 m_size(0), 00213 m_allocation(0), 00214 m_data(0) 00215 { 00216 ThisType theTemp(theManager); 00217 00218 theTemp.insert(theTemp.begin(), theInsertSize, theData); 00219 00220 swap(theTemp); 00221 00222 invariants(); 00223 } 00224 00225 ~XalanVector() 00226 { 00227 invariants(); 00228 00229 if (m_allocation != 0) 00230 { 00231 destroy(begin(), end()); 00232 00233 deallocate(m_data); 00234 } 00235 } 00236 00237 void 00238 push_back(const value_type& data) 00239 { 00240 invariants(); 00241 00242 doPushBack(data); 00243 00244 invariants(); 00245 } 00246 00247 void 00248 pop_back() 00249 { 00250 invariants(); 00251 00252 --m_size; 00253 00254 destroy(m_data[m_size]); 00255 00256 invariants(); 00257 } 00258 00259 iterator 00260 erase( 00261 iterator theFirst, 00262 iterator theLast) 00263 { 00264 invariants(); 00265 00266 if (theFirst != theLast) 00267 { 00268 XALAN_STD_QUALIFIER copy( 00269 theLast, 00270 end(), 00271 theFirst); 00272 00273 shrinkCount(local_distance(theFirst, theLast)); 00274 } 00275 00276 invariants(); 00277 00278 return theFirst; 00279 } 00280 00281 iterator 00282 erase(iterator position) 00283 { 00284 return erase(position, position + 1); 00285 } 00286 00287 void 00288 insert( 00289 iterator thePosition, 00290 const_iterator theFirst, 00291 const_iterator theLast) 00292 { 00293 // Since we're using bare pointers for now, we can 00294 // assert this... 00295 assert(theFirst <= theLast); 00296 00297 invariants(); 00298 00299 const size_type theInsertSize = 00300 local_distance(theFirst, theLast); 00301 00302 if (theInsertSize == 0) 00303 { 00304 return; 00305 } 00306 00307 const size_type theTotalSize = size() + theInsertSize; 00308 00309 if (thePosition == end()) 00310 { 00311 pointer thePointer = ensureCapacity(theTotalSize); 00312 00313 while (theFirst != theLast) 00314 { 00315 Constructor::construct(thePointer, *theFirst, *m_memoryManager); 00316 00317 ++thePointer; 00318 ++m_size; 00319 ++theFirst; 00320 } 00321 } 00322 else 00323 { 00324 if (theTotalSize > capacity()) 00325 { 00326 assert (m_memoryManager != 0); 00327 00328 ThisType theTemp(*m_memoryManager, theTotalSize); 00329 00330 // insert everything up to the position... 00331 theTemp.insert(theTemp.end(), begin(), thePosition); 00332 00333 // insert the new stuff... 00334 theTemp.insert(theTemp.end(), theFirst, theLast); 00335 00336 // insert everything from the position to the end... 00337 theTemp.insert(theTemp.end(), thePosition, end()); 00338 00339 swap(theTemp); 00340 } 00341 else 00342 { 00343 // insert into the middle of the vector that has enough capacity 00344 const iterator theOriginalEnd = end(); 00345 00346 const size_type theRightSplitSize = 00347 local_distance(thePosition, theOriginalEnd); 00348 00349 if (theRightSplitSize <= theInsertSize) 00350 { 00351 // inserted range will go to or beyond edge of current vector 00352 00353 // append from inserted range, all values that will extend 00354 // beyond the current vector 00355 const const_iterator toInsertSplit = theFirst + theRightSplitSize; 00356 const_iterator toInsertIter = toInsertSplit; 00357 00358 while (toInsertIter != theLast) 00359 { 00360 doPushBack(*toInsertIter); 00361 00362 ++toInsertIter; 00363 } 00364 00365 // copy the "right" of the current vector to the end 00366 toInsertIter = thePosition; 00367 while (toInsertIter != theOriginalEnd) 00368 { 00369 doPushBack(*toInsertIter); 00370 00371 ++toInsertIter; 00372 } 00373 00374 // copy the remaining part of inserted range into 00375 // the original vector spaces 00376 XALAN_STD_QUALIFIER copy(theFirst, toInsertSplit, thePosition); 00377 } 00378 else 00379 { 00380 // inserted range will not extend beyond edge of current vector 00381 00382 // move end of current vector by insertion size 00383 const_iterator toMoveIter = end() - theInsertSize; 00384 00385 while (toMoveIter != theOriginalEnd) 00386 { 00387 doPushBack(*toMoveIter); 00388 00389 ++toMoveIter; 00390 } 00391 00392 // reverse copy the remaining part of the "right" piece of the current vector 00393 XALAN_STD_QUALIFIER copy_backward(thePosition, theOriginalEnd - theInsertSize, theOriginalEnd); 00394 00395 // insert into current vector 00396 XALAN_STD_QUALIFIER copy(theFirst, theLast, thePosition); 00397 } 00398 } 00399 } 00400 00401 invariants(); 00402 } 00403 00404 void 00405 insert( 00406 iterator thePosition, 00407 iterator theFirst, 00408 iterator theLast) 00409 { 00410 insert( 00411 thePosition, 00412 const_iterator(theFirst), 00413 const_iterator(theLast)); 00414 } 00415 00416 void 00417 insert( 00418 iterator thePosition, 00419 size_type theCount, 00420 const value_type& theData) 00421 { 00422 invariants(); 00423 00424 const size_type theTotalSize = size() + theCount; 00425 00426 // Needs to be optimized 00427 if (thePosition == end()) 00428 { 00429 pointer thePointer = ensureCapacity(theTotalSize); 00430 00431 for (size_type index = 0; index < theCount; ++index) 00432 { 00433 Constructor::construct(thePointer, theData, *m_memoryManager); 00434 00435 ++thePointer; 00436 ++m_size; 00437 } 00438 } 00439 else 00440 { 00441 if (theTotalSize > capacity()) 00442 { 00443 assert ( m_memoryManager != 0 ); 00444 00445 ThisType theTemp(*m_memoryManager, theTotalSize); 00446 00447 // insert everything up to the position... 00448 theTemp.insert(theTemp.end(), begin(), thePosition); 00449 00450 // insert the new stuff... 00451 theTemp.insert(theTemp.end(), theCount, theData); 00452 00453 // insert everything from the position to the end... 00454 theTemp.insert(theTemp.end(), thePosition, end()); 00455 00456 swap(theTemp); 00457 } 00458 else 00459 { 00460 // insert into the middle of the vector that has enough capacity 00461 const iterator theOriginalEnd = end(); 00462 00463 const size_type theRightSplitSize = 00464 local_distance(thePosition, theOriginalEnd); 00465 00466 if (theRightSplitSize <= theCount) 00467 { 00468 // inserted range will go to or beyond edge of current vector 00469 00470 // append all copies that will extend 00471 // beyond the current vector 00472 for (size_type i = 0; i < (theCount - theRightSplitSize); ++i) 00473 { 00474 doPushBack(theData); 00475 } 00476 00477 // copy the "right" of the current vector to the end 00478 iterator toInsertIter = thePosition; 00479 00480 while (toInsertIter != theOriginalEnd) 00481 { 00482 doPushBack(*toInsertIter); 00483 00484 ++toInsertIter; 00485 } 00486 00487 // copy the remaining part of inserted range into 00488 // the original vector spaces 00489 XALAN_STD_QUALIFIER fill(thePosition, thePosition + theRightSplitSize, theData); 00490 } 00491 else 00492 { 00493 // inserted range will not extend beyond edge of current vector 00494 00495 // move end of current vector by insertion size 00496 const_iterator toMoveIter = end() - theCount; 00497 00498 while (toMoveIter != theOriginalEnd) 00499 { 00500 doPushBack(*toMoveIter); 00501 00502 ++toMoveIter; 00503 } 00504 00505 // reverse copy the remaining part of the "right" piece of the current vector 00506 XALAN_STD_QUALIFIER copy_backward(thePosition, theOriginalEnd - theCount, theOriginalEnd); 00507 00508 // insert into current vector 00509 XALAN_STD_QUALIFIER fill(thePosition, thePosition + theCount, theData); 00510 } 00511 } 00512 } 00513 00514 invariants(); 00515 } 00516 00517 iterator 00518 insert( 00519 iterator thePosition, 00520 const value_type& theData) 00521 { 00522 if (m_allocation > m_size) 00523 { 00524 insert(thePosition, 1, theData); 00525 00526 return thePosition; 00527 } 00528 else 00529 { 00530 const size_type theDistance = 00531 local_distance(begin(), thePosition); 00532 00533 insert(thePosition, 1, theData); 00534 00535 return begin() + theDistance; 00536 } 00537 } 00538 00539 void 00540 assign( 00541 const_iterator theFirst, 00542 const_iterator theLast) 00543 { 00544 clear(); 00545 00546 insert( 00547 begin(), 00548 theFirst, 00549 theLast); 00550 } 00551 00552 void 00553 assign( 00554 iterator theFirst, 00555 iterator theLast) 00556 { 00557 assign( 00558 const_iterator(theFirst), 00559 const_iterator(theLast)); 00560 } 00561 00562 void 00563 assign( 00564 size_type theCount, 00565 const value_type& theData) 00566 { 00567 clear(); 00568 00569 insert(theCount, theData); 00570 } 00571 00572 size_type 00573 size() const 00574 { 00575 invariants(); 00576 00577 return m_size; 00578 } 00579 00580 size_type 00581 max_size() const 00582 { 00583 invariants(); 00584 00585 return ~size_type(0); 00586 } 00587 00588 void 00589 resize(size_type theSize) 00590 { 00591 typename ConstructionTraits::Constructor::ConstructableType defaultValue(*m_memoryManager); 00592 00593 resize(theSize , defaultValue.value); 00594 } 00595 00596 void 00597 resize( size_type theSize, 00598 const value_type& theValue) 00599 { 00600 invariants(); 00601 00602 if (m_size > theSize) 00603 { 00604 shrinkToSize(theSize); 00605 } 00606 else if (m_size < theSize) 00607 { 00608 // Reserve memory up-front... 00609 reserve(theSize); 00610 00611 assert(m_allocation >= theSize); 00612 00613 const value_type* const theEnd = m_data + theSize; 00614 00615 // Fill the new area... 00616 for (value_type* data = endPointer(); 00617 data != theEnd; 00618 ++data, ++m_size) 00619 { 00620 Constructor::construct(data, theValue, *m_memoryManager); 00621 } 00622 } 00623 00624 assert(m_size == theSize); 00625 00626 invariants(); 00627 } 00628 00629 size_type 00630 capacity() const 00631 { 00632 invariants(); 00633 00634 return m_allocation; 00635 } 00636 00637 bool 00638 empty() const 00639 { 00640 invariants(); 00641 00642 return m_size == 0 ? true : false; 00643 } 00644 00645 void 00646 reserve(size_type theSize) 00647 { 00648 invariants(); 00649 00650 if (theSize > m_allocation) 00651 { 00652 doReserve(theSize); 00653 } 00654 00655 invariants(); 00656 } 00657 00658 reference 00659 front() 00660 { 00661 invariants(); 00662 00663 return m_data[0]; 00664 } 00665 00666 const_reference 00667 front() const 00668 { 00669 invariants(); 00670 00671 return m_data[0]; 00672 } 00673 00674 reference 00675 back() 00676 { 00677 return m_data[m_size - 1]; 00678 } 00679 00680 const_reference 00681 back() const 00682 { 00683 return m_data[m_size - 1]; 00684 } 00685 00686 iterator 00687 begin() 00688 { 00689 invariants(); 00690 00691 return m_data; 00692 } 00693 00694 const_iterator 00695 begin() const 00696 { 00697 invariants(); 00698 00699 return m_data; 00700 } 00701 00702 iterator 00703 end() 00704 { 00705 invariants(); 00706 00707 return endPointer(); 00708 } 00709 00710 const_iterator 00711 end() const 00712 { 00713 invariants(); 00714 00715 return endPointer(); 00716 } 00717 00718 reverse_iterator 00719 rbegin() 00720 { 00721 invariants(); 00722 00723 return reverse_iterator(end()); 00724 } 00725 00726 const_reverse_iterator 00727 rbegin() const 00728 { 00729 invariants(); 00730 00731 return const_reverse_iterator(end()); 00732 } 00733 00734 reverse_iterator 00735 rend() 00736 { 00737 invariants(); 00738 00739 return reverse_iterator(begin()); 00740 } 00741 00742 const_reverse_iterator 00743 rend() const 00744 { 00745 invariants(); 00746 00747 return const_reverse_iterator(begin()); 00748 } 00749 00750 00751 reference 00752 at(size_type theIndex) 00753 { 00754 if (theIndex >= m_size) 00755 { 00756 outOfRange(); 00757 } 00758 00759 return m_data[theIndex]; 00760 } 00761 00762 const_reference 00763 at(size_type theIndex) const 00764 { 00765 if (theIndex >= m_size) 00766 { 00767 outOfRange(); 00768 } 00769 00770 return m_data[theIndex]; 00771 } 00772 00773 reference 00774 operator[](size_type theIndex) 00775 { 00776 assert (theIndex < m_size); 00777 00778 return m_data[theIndex]; 00779 } 00780 00781 const_reference 00782 operator[](size_type theIndex) const 00783 { 00784 assert (theIndex < m_size); 00785 00786 return m_data[theIndex]; 00787 } 00788 00789 void 00790 clear() 00791 { 00792 invariants(); 00793 00794 if (m_size > 0) 00795 { 00796 shrinkToSize(0); 00797 } 00798 00799 invariants(); 00800 } 00801 00802 // Operators... 00803 ThisType& 00804 operator=(const ThisType& theRHS) 00805 { 00806 invariants(); 00807 00808 if (&theRHS != this) 00809 { 00810 if (m_allocation < theRHS.m_size) 00811 { 00812 ThisType theTemp(theRHS,*m_memoryManager); 00813 00814 swap(theTemp); 00815 } 00816 else 00817 { 00818 const_iterator theRHSCopyEnd = theRHS.end(); 00819 00820 if (m_size > theRHS.m_size) 00821 { 00822 // Resize to the target size... 00823 shrinkToSize(theRHS.m_size); 00824 } 00825 else if (m_size < theRHS.m_size) 00826 { 00827 theRHSCopyEnd = 00828 theRHS.begin() + m_size; 00829 00830 insert( 00831 end(), 00832 theRHSCopyEnd, 00833 theRHS.end()); 00834 } 00835 00836 // Copy everything that already exists... 00837 XALAN_STD_QUALIFIER copy( 00838 theRHS.begin(), 00839 theRHSCopyEnd, 00840 begin()); 00841 } 00842 } 00843 00844 invariants(); 00845 00846 return *this; 00847 } 00848 00849 void 00850 swap(ThisType& theOther) 00851 { 00852 invariants(); 00853 00854 MemoryManagerType* const theTempManager = m_memoryManager; 00855 const size_type theTempLength = m_size; 00856 const size_type theTempAllocation = m_allocation; 00857 value_type* const theTempData = m_data; 00858 00859 m_memoryManager = theOther.m_memoryManager; 00860 m_size = theOther.m_size; 00861 m_allocation = theOther.m_allocation; 00862 m_data = theOther.m_data; 00863 00864 theOther.m_memoryManager = theTempManager; 00865 theOther.m_size = theTempLength; 00866 theOther.m_allocation = theTempAllocation; 00867 theOther.m_data = theTempData; 00868 00869 invariants(); 00870 } 00871 00872 const MemoryManagerType* 00873 getMemoryManager() const 00874 { 00875 return m_memoryManager; 00876 } 00877 00878 MemoryManagerType& 00879 getMemoryManager() 00880 { 00881 assert (m_memoryManager != 0); 00882 00883 return *m_memoryManager; 00884 } 00885 00886 // Detaches the allocated memory from the vector, and returns 00887 // the pointer to the caller. The caller then owns the memory 00888 // and must destroy any objects and deallocate it using the 00889 // the memory manager returned from getMemoryManager() 00890 pointer 00891 detach() 00892 { 00893 m_size = 0; 00894 m_allocation = 0; 00895 00896 value_type* const theTemp = m_data; 00897 00898 m_data = 0; 00899 00900 return theTemp; 00901 } 00902 00903 private: 00904 00905 #if defined(NDEBUG) 00906 void 00907 invariants() const 00908 { 00909 } 00910 #else 00911 void 00912 invariants() const 00913 { 00914 assert(m_allocation >= m_size); 00915 assert(m_data == 0 && m_allocation == 0 || m_data != 0 && m_allocation != 0); 00916 } 00917 #endif 00918 00919 size_type 00920 local_distance( 00921 const_iterator theFirst, 00922 const_iterator theLast) 00923 { 00924 // Since we're using bare pointers for now, we can 00925 // assert this... 00926 assert(theFirst <= theLast); 00927 00928 #if defined(XALAN_HAS_STD_DISTANCE) 00929 return XALAN_STD_QUALIFIER distance(theFirst, theLast); 00930 #else 00931 size_type theDistance; 00932 00933 XALAN_STD_QUALIFIER distance(theFirst, theLast, theDistance); 00934 00935 return theDistance; 00936 #endif 00937 } 00938 00939 value_type* 00940 allocate(size_type size) 00941 { 00942 const size_type theBytesNeeded = size * sizeof(value_type); 00943 00944 assert (m_memoryManager != 0); 00945 00946 void* pointer = m_memoryManager->allocate(theBytesNeeded); 00947 00948 assert(pointer != 0); 00949 00950 return (value_type*) pointer; 00951 } 00952 00953 void 00954 deallocate(value_type* pointer) 00955 { 00956 assert(m_memoryManager != 0); 00957 00958 m_memoryManager->deallocate(pointer); 00959 00960 } 00961 00962 static void 00963 destroy(value_type& theValue) 00964 { 00965 theValue.~Type(); 00966 } 00967 00968 static void 00969 destroy( 00970 iterator theFirst, 00971 iterator theLast) 00972 { 00973 for(; theFirst != theLast; ++theFirst) 00974 { 00975 destroy(*theFirst); 00976 } 00977 } 00978 00979 void 00980 doPushBack(const value_type& data) 00981 { 00982 invariants(); 00983 00984 if (m_size < m_allocation) 00985 { 00986 Constructor::construct(endPointer(), data, *m_memoryManager); 00987 00988 ++m_size; 00989 } 00990 else 00991 { 00992 assert(m_size == m_allocation); 00993 00994 const size_type theNewSize = m_size == 0 ? 1 : size_type((m_size * 1.6) + 0.5); 00995 assert(theNewSize > m_size); 00996 00997 ThisType theTemp(*this, *m_memoryManager, theNewSize); 00998 00999 theTemp.doPushBack(data); 01000 01001 swap(theTemp); 01002 } 01003 01004 invariants(); 01005 } 01006 01007 pointer 01008 ensureCapacity(size_type theSize) 01009 { 01010 if (theSize > capacity()) 01011 { 01012 doReserve(theSize); 01013 } 01014 01015 return endPointer(); 01016 } 01017 01018 void 01019 doReserve(size_type theSize) 01020 { 01021 invariants(); 01022 01023 assert(theSize > m_allocation); 01024 01025 ThisType theTemp(*this, *m_memoryManager, theSize); 01026 01027 swap(theTemp); 01028 01029 invariants(); 01030 } 01031 01032 pointer 01033 endPointer() 01034 { 01035 return m_data + m_size; 01036 } 01037 01038 const_pointer 01039 endPointer() const 01040 { 01041 return m_data + m_size; 01042 } 01043 01044 static void 01045 outOfRange() 01046 { 01047 throw XALAN_STD_QUALIFIER out_of_range(""); 01048 } 01049 01050 void 01051 shrinkToSize(size_type theSize) 01052 { 01053 assert(m_size > theSize); 01054 01055 do 01056 { 01057 pop_back(); 01058 } while (m_size > theSize); 01059 } 01060 01061 void 01062 shrinkCount(size_type theCount) 01063 { 01064 assert(m_size >= theCount); 01065 01066 while (theCount > 0) 01067 { 01068 pop_back(); 01069 01070 --theCount; 01071 } 01072 } 01073 01074 size_type 01075 local_max( 01076 size_type theLHS, 01077 size_type theRHS) 01078 { 01079 return theLHS > theRHS ? theLHS : theRHS; 01080 } 01081 01082 #if defined(XALAN_DEVELOPMENT) 01083 //not implemented 01084 XalanVector(const XalanVector&); 01085 XalanVector(); 01086 #endif 01087 01088 // Data members... 01089 MemoryManagerType* m_memoryManager; 01090 01091 size_type m_size; 01092 01093 size_type m_allocation; 01094 01095 value_type* m_data; 01096 }; 01097 01098 01099 01100 template <class Type> 01101 inline void 01102 swap( 01103 XalanVector<Type>& theLHS, 01104 XalanVector<Type>& theRHS) 01105 { 01106 theLHS.swap(theRHS); 01107 } 01108 01109 01110 01111 template <class Type> 01112 inline bool 01113 operator==( 01114 const XalanVector<Type>& theLHS, 01115 const XalanVector<Type>& theRHS) 01116 { 01117 if (theLHS.size() != theRHS.size()) 01118 { 01119 return false; 01120 } 01121 else if (theLHS.size() == 0) 01122 { 01123 return true; 01124 } 01125 else 01126 { 01127 return XALAN_STD_QUALIFIER equal(theLHS.begin(), theLHS.end(), theRHS.begin()); 01128 } 01129 } 01130 01131 01132 01133 template <class Type> 01134 inline bool 01135 operator!=( 01136 const XalanVector<Type>& theLHS, 01137 const XalanVector<Type>& theRHS) 01138 { 01139 return !(theLHS == theRHS); 01140 } 01141 01142 01143 01144 template <class Type> 01145 inline bool 01146 operator<( 01147 const XalanVector<Type>& theLHS, 01148 const XalanVector<Type>& theRHS) 01149 { 01150 return XALAN_STD_QUALIFIER lexicographical_compare( 01151 theLHS.begin(), 01152 theLHS.end(), 01153 theRHS.begin(), 01154 theRHS.end()); 01155 } 01156 01157 01158 01159 template <class Type> 01160 inline bool 01161 operator<=( 01162 const XalanVector<Type>& theLHS, 01163 const XalanVector<Type>& theRHS) 01164 { 01165 return !(theRHS < theLHS); 01166 } 01167 01168 01169 01170 template <class Type> 01171 inline bool 01172 operator>( 01173 const XalanVector<Type>& theLHS, 01174 const XalanVector<Type>& theRHS) 01175 { 01176 return theRHS < theLHS; 01177 } 01178 01179 01180 01181 template <class Type> 01182 inline bool 01183 operator>=( 01184 const XalanVector<Type>& theLHS, 01185 const XalanVector<Type>& theRHS) 01186 { 01187 return !(theLHS < theRHS); 01188 } 01189 01190 01191 01192 #if defined(_MSC_VER) 01193 #pragma warning(pop) 01194 #endif 01195 01196 01197 01198 XALAN_CPP_NAMESPACE_END 01199 01200 01201 01202 #endif // XALANVECTOR_HEADER_GUARD_1357924680
Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.
![]() |
Xalan-C++ XSLT Processor Version 1.9 |
|