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