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