Xalan-C++ API Reference 1.12.0
XalanVector.hpp
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#if !defined(XALANVECTOR_HEADER_GUARD_1357924680)
20#define XALANVECTOR_HEADER_GUARD_1357924680
21
22
23
24// Base include file. Must be first.
26
27
28
29#include <cstddef>
30#include <algorithm>
31#include <cassert>
32#include <new>
33#include <iterator>
34#include <stdexcept>
35
36
37
39
40
41
42namespace XALAN_CPP_NAMESPACE {
43
44
45
46#if defined(_MSC_VER)
47#pragma warning(push)
48#pragma warning(disable: 4100)
49#endif
50
51
52
53using xercesc::MemoryManager;
54
55
56
57template <class Type, class ConstructionTraits = MemoryManagedConstructionTraits<Type> >
59{
60public:
61
62
65 typedef const value_type* const_pointer;
68 typedef size_t size_type;
70
72 typedef const value_type* const_iterator;
73
74 typedef std::reverse_iterator<iterator> reverse_iterator_;
75 typedef std::reverse_iterator<const_iterator> const_reverse_iterator_;
76
79
81
82 typedef typename ConstructionTraits::Constructor Constructor;
83 typedef typename Constructor::ConstructableType ConstructibleType;
84
88 m_memoryManager(&theManager),
89 m_size(0),
90 m_allocation(initialAllocation),
91 m_data(initialAllocation > 0 ? allocate(initialAllocation) : 0)
92 {
93 invariants();
94 }
95
96 static XalanVector*
98 MemoryManager& theManager,
100 {
101 typedef XalanVector ThisType;
102
104
105 ThisType* const theResult =
107
109
110 return theResult;
111 }
112
114 const ThisType& theSource,
117 m_memoryManager(&theManager),
118 m_size(0),
119 m_allocation(0),
120 m_data(0)
121 {
122 if (theSource.m_size > 0)
123 {
125
126 theTemp.insert(theTemp.begin(), theSource.begin(), theSource.end());
127
128 swap(theTemp);
129
130 }
131 else if (theInitialAllocation > 0)
132 {
133 m_data = allocate(theInitialAllocation);
134
135 m_allocation = theInitialAllocation;
136 }
137
138 invariants();
139 }
140
144 MemoryManager& theManager) :
145 m_memoryManager(&theManager),
146 m_size(0),
147 m_allocation(0),
148 m_data(0)
149
150 {
152
153 theTemp.insert(theTemp.begin(), theFirst, theLast);
154
155 swap(theTemp);
156
157 invariants();
158 }
159
160 static XalanVector*
164 MemoryManager& theManager)
165 {
166 typedef XalanVector ThisType;
167
169
170 ThisType* const theResult =
172
174
175 return theResult;
176 }
177
180 const value_type& theData,
181 MemoryManager& theManager) :
182 m_memoryManager(&theManager),
183 m_size(0),
184 m_allocation(0),
185 m_data(0)
186 {
188
189 theTemp.insert(theTemp.begin(), theInsertSize, theData);
190
191 swap(theTemp);
192
193 invariants();
194 }
195
197 {
198 invariants();
199
200 if (m_allocation != 0)
201 {
202 destroy(begin(), end());
203
204 deallocate(m_data);
205 }
206 }
207
208 void
210 {
211 invariants();
212
213 doPushBack(data);
214
215 invariants();
216 }
217
218 void
220 {
221 invariants();
222
223 --m_size;
224
225 destroy(m_data[m_size]);
226
227 invariants();
228 }
229
230 iterator
234 {
235 invariants();
236
237 if (theFirst != theLast)
238 {
239 std::copy(
240 theLast,
241 end(),
242 theFirst);
243
244 shrinkCount(local_distance(theFirst, theLast));
245 }
246
247 invariants();
248
249 return theFirst;
250 }
251
252 iterator
254 {
255 return erase(position, position + 1);
256 }
257
258 void
263 {
264 // Since we're using bare pointers for now, we can
265 // assert this...
267 assert(thePosition >= begin());
268 assert(thePosition <= end());
269
270 invariants();
271
273 local_distance(theFirst, theLast);
274
275 if (theInsertSize == 0)
276 {
277 return;
278 }
279
280 const size_type theTotalSize = size() + theInsertSize;
281
282 if (thePosition == end())
283 {
284 pointer thePointer = ensureCapacity(theTotalSize);
285
286 while (theFirst != theLast)
287 {
288 Constructor::construct(thePointer, *theFirst, *m_memoryManager);
289
290 ++thePointer;
291 ++m_size;
292 ++theFirst;
293 }
294 }
295 else
296 {
297 if (theTotalSize > capacity())
298 {
299 assert (m_memoryManager != 0);
300
301 ThisType theTemp(*m_memoryManager, theTotalSize);
302
303 // insert everything up to the position...
304 theTemp.insert(theTemp.end(), begin(), thePosition);
305
306 // insert the new stuff...
307 theTemp.insert(theTemp.end(), theFirst, theLast);
308
309 // insert everything from the position to the end...
310 theTemp.insert(theTemp.end(), thePosition, end());
311
312 swap(theTemp);
313 }
314 else
315 {
316 // insert into the middle of the vector that has enough capacity
317 const iterator theOriginalEnd = end();
318
320 local_distance(thePosition, theOriginalEnd);
321
323 {
324 // inserted range will go to or beyond edge of current vector
325
326 // append from inserted range, all values that will extend
327 // beyond the current vector
330
331 while (toInsertIter != theLast)
332 {
333 doPushBack(*toInsertIter);
334
335 ++toInsertIter;
336 }
337
338 // copy the "right" of the current vector to the end
341 {
342 doPushBack(*toInsertIter);
343
344 ++toInsertIter;
345 }
346
347 // copy the remaining part of inserted range into
348 // the original vector spaces
350 }
351 else
352 {
353 // inserted range will not extend beyond edge of current vector
354
355 // move end of current vector by insertion size
357
358 while (toMoveIter != theOriginalEnd)
359 {
360 doPushBack(*toMoveIter);
361
362 ++toMoveIter;
363 }
364
365 // reverse copy the remaining part of the "right" piece of the current vector
367
368 // insert into current vector
369 std::copy(theFirst, theLast, thePosition);
370 }
371 }
372 }
373
374 invariants();
375 }
376
377 void
381 const value_type& theData)
382 {
383 invariants();
384
385 const size_type theTotalSize = size() + theCount;
386
387 // Needs to be optimized
388 if (thePosition == end())
389 {
390 pointer thePointer = ensureCapacity(theTotalSize);
391
392 for (size_type index = 0; index < theCount; ++index)
393 {
394 Constructor::construct(thePointer, theData, *m_memoryManager);
395
396 ++thePointer;
397 ++m_size;
398 }
399 }
400 else
401 {
402 if (theTotalSize > capacity())
403 {
404 assert ( m_memoryManager != 0 );
405
406 ThisType theTemp(*m_memoryManager, theTotalSize);
407
408 // insert everything up to the position...
409 theTemp.insert(theTemp.end(), begin(), thePosition);
410
411 // insert the new stuff...
412 theTemp.insert(theTemp.end(), theCount, theData);
413
414 // insert everything from the position to the end...
415 theTemp.insert(theTemp.end(), thePosition, end());
416
417 swap(theTemp);
418 }
419 else
420 {
421 // insert into the middle of the vector that has enough capacity
422 const iterator theOriginalEnd = end();
423
425 local_distance(thePosition, theOriginalEnd);
426
428 {
429 // inserted range will go to or beyond edge of current vector
430
431 // append all copies that will extend
432 // beyond the current vector
433 for (size_type i = 0; i < (theCount - theRightSplitSize); ++i)
434 {
435 doPushBack(theData);
436 }
437
438 // copy the "right" of the current vector to the end
440
442 {
443 doPushBack(*toInsertIter);
444
445 ++toInsertIter;
446 }
447
448 // copy the remaining part of inserted range into
449 // the original vector spaces
451 }
452 else
453 {
454 // inserted range will not extend beyond edge of current vector
455
456 // move end of current vector by insertion size
458
459 while (toMoveIter != theOriginalEnd)
460 {
461 doPushBack(*toMoveIter);
462
463 ++toMoveIter;
464 }
465
466 // reverse copy the remaining part of the "right" piece of the current vector
467 std::copy_backward(thePosition, theOriginalEnd - theCount, theOriginalEnd);
468
469 // insert into current vector
471 }
472 }
473 }
474
475 invariants();
476 }
477
478 iterator
481 const value_type& theData)
482 {
483 if (m_allocation > m_size)
484 {
486
487 return thePosition;
488 }
489 else
490 {
491 const size_type theDistance =
492 local_distance(begin(), thePosition);
493
495
496 return begin() + theDistance;
497 }
498 }
499
500 void
504 {
505 clear();
506
507 insert(
508 begin(),
509 theFirst,
510 theLast);
511 }
512
513 void
522
523 void
526 const value_type& theData)
527 {
528 clear();
529
531 }
532
534 size() const
535 {
536 invariants();
537
538 return m_size;
539 }
540
542 max_size() const
543 {
544 invariants();
545
546 return ~size_type(0);
547 }
548
549 void
551 {
552 const ConstructibleType defaultValue(*m_memoryManager);
553
554 resize(theSize, defaultValue.value);
555 }
556
557 void
560 const value_type& theValue)
561 {
562 invariants();
563
564 if (m_size > theSize)
565 {
566 shrinkToSize(theSize);
567 }
568 else if (m_size < theSize)
569 {
570 // Reserve memory up-front...
572
573 assert(m_allocation >= theSize);
574
575 const value_type* const theEnd = m_data + theSize;
576
577 // Fill the new area...
578 for (value_type* data = endPointer();
579 data != theEnd;
580 ++data, ++m_size)
581 {
582 Constructor::construct(data, theValue, *m_memoryManager);
583 }
584 }
585
586 assert(m_size == theSize);
587
588 invariants();
589 }
590
592 capacity() const
593 {
594 invariants();
595
596 return m_allocation;
597 }
598
599 bool
600 empty() const
601 {
602 invariants();
603
604 return m_size == 0 ? true : false;
605 }
606
607 void
609 {
610 invariants();
611
612 if (theSize > m_allocation)
613 {
614 doReserve(theSize);
615 }
616
617 invariants();
618 }
619
620 reference
622 {
623 invariants();
624
625 return m_data[0];
626 }
627
628 const_reference
629 front() const
630 {
631 invariants();
632
633 return m_data[0];
634 }
635
636 reference
638 {
639 return m_data[m_size - 1];
640 }
641
642 const_reference
643 back() const
644 {
645 return m_data[m_size - 1];
646 }
647
648 iterator
650 {
651 invariants();
652
653 return m_data;
654 }
655
656 const_iterator
657 begin() const
658 {
659 invariants();
660
661 return m_data;
662 }
663
664 iterator
666 {
667 invariants();
668
669 return endPointer();
670 }
671
672 const_iterator
673 end() const
674 {
675 invariants();
676
677 return endPointer();
678 }
679
680 reverse_iterator
682 {
683 invariants();
684
685 return reverse_iterator(end());
686 }
687
688 const_reverse_iterator
689 rbegin() const
690 {
691 invariants();
692
693 return const_reverse_iterator(end());
694 }
695
696 reverse_iterator
698 {
699 invariants();
700
701 return reverse_iterator(begin());
702 }
703
704 const_reverse_iterator
705 rend() const
706 {
707 invariants();
708
709 return const_reverse_iterator(begin());
710 }
711
712
713 reference
715 {
716 if (theIndex >= m_size)
717 {
718 outOfRange();
719 }
720
721 return m_data[theIndex];
722 }
723
724 const_reference
726 {
727 if (theIndex >= m_size)
728 {
729 outOfRange();
730 }
731
732 return m_data[theIndex];
733 }
734
735 reference
737 {
738 assert (theIndex < m_size);
739
740 return m_data[theIndex];
741 }
742
743 const_reference
745 {
746 assert (theIndex < m_size);
747
748 return m_data[theIndex];
749 }
750
751 void
753 {
754 invariants();
755
756 if (m_size > 0)
757 {
758 shrinkToSize(0);
759 }
760
761 invariants();
762 }
763
764 // Operators...
765 ThisType&
767 {
768 invariants();
769
770 if (&theRHS != this)
771 {
772 if (m_allocation < theRHS.m_size)
773 {
774 ThisType theTemp(theRHS,*m_memoryManager);
775
776 swap(theTemp);
777 }
778 else
779 {
781
782 if (m_size > theRHS.m_size)
783 {
784 // Resize to the target size...
785 shrinkToSize(theRHS.m_size);
786 }
787 else if (m_size < theRHS.m_size)
788 {
789 // Insert the portion of theRHS that won't fit
790 // at the end...
792 theRHS.begin() + m_size;
793
794 insert(
795 end(),
797 theRHS.end());
798 }
799
800 // Copy everything that already exists...
801 std::copy(
802 theRHS.begin(),
804 begin());
805 }
806 }
807
808 invariants();
809
810 return *this;
811 }
812
813 void
815 {
816 invariants();
817
818 MemoryManager* const theTempManager = m_memoryManager;
819 const size_type theTempLength = m_size;
820 const size_type theTempAllocation = m_allocation;
821 value_type* const theTempData = m_data;
822
823 m_memoryManager = theOther.m_memoryManager;
824 m_size = theOther.m_size;
825 m_allocation = theOther.m_allocation;
826 m_data = theOther.m_data;
827
828 theOther.m_memoryManager = theTempManager;
829 theOther.m_size = theTempLength;
830 theOther.m_allocation = theTempAllocation;
831 theOther.m_data = theTempData;
832
833 invariants();
834 }
835
836 const MemoryManager&
838 {
839 assert (m_memoryManager != 0);
840
841 return *m_memoryManager;
842 }
843
844 MemoryManager&
846 {
847 assert (m_memoryManager != 0);
848
849 return *m_memoryManager;
850 }
851
852 // Detaches the allocated memory from the vector, and returns
853 // the pointer to the caller. The caller then owns the memory
854 // and must destroy any objects and deallocate it using the
855 // the memory manager returned from getMemoryManager()
856 pointer
858 {
859 m_size = 0;
860 m_allocation = 0;
861
862 value_type* const theTemp = m_data;
863
864 m_data = 0;
865
866 return theTemp;
867 }
868
869private:
870
871#if defined(NDEBUG)
872 void
873 invariants() const
874 {
875 }
876#else
877 void
878 invariants() const
879 {
880 assert(m_allocation >= m_size);
881 assert(
882 (m_data == 0 && m_allocation == 0) ||
883 (m_data != 0 && m_allocation != 0));
884 }
885#endif
886
888 local_distance(
889 const_iterator theFirst,
890 const_iterator theLast)
891 {
892 // Since we're using bare pointers for now, we can
893 // assert this...
894 assert(theFirst <= theLast);
895
896 return std::distance(theFirst, theLast);
897 }
898
899 value_type*
900 allocate(size_type size)
901 {
902 const size_type theBytesNeeded = size * sizeof(value_type);
903
904 assert (m_memoryManager != 0);
905
906 void* pointer = m_memoryManager->allocate(theBytesNeeded);
907
908 assert(pointer != 0);
909
910 return (value_type*) pointer;
911 }
912
913 void
914 deallocate(value_type* pointer)
915 {
916 assert(m_memoryManager != 0);
917
918 m_memoryManager->deallocate(pointer);
919
920 }
921
922 static void
923 destroy(value_type& theValue)
924 {
925 theValue.~Type();
926 }
927
928 static void
929 destroy(
930 iterator theFirst,
931 iterator theLast)
932 {
933 for(; theFirst != theLast; ++theFirst)
934 {
935 destroy(*theFirst);
936 }
937 }
938
939 void
940 grow(const value_type& data)
941 {
942 invariants();
943
944 assert(m_size != 0 && m_size == m_allocation);
945
946 const size_type theNewSize = size_type((m_size * 1.6) + 0.5);
947 assert(theNewSize > m_size);
948
949 ThisType theTemp(*this, *m_memoryManager, theNewSize);
950
951 theTemp.doPushBack(data);
952
953 swap(theTemp);
954
955 invariants();
956 }
957
958 void
959 construct_back(const value_type& data)
960 {
961 invariants();
962
963 assert(m_size < m_allocation);
964
965 Constructor::construct(
966 endPointer(),
967 data,
968 *m_memoryManager);
969
970 ++m_size;
971
972 invariants();
973 }
974
975 void
976 init(const value_type& data)
977 {
978 invariants();
979
980 assert(m_size == 0 && m_allocation == 0);
981
982 m_data = allocate(1);
983
984 m_allocation = 1;
985
986 construct_back(data);
987
988 invariants();
989 }
990
991 void
992 doPushBack(const value_type& data)
993 {
994 invariants();
995
996 if (m_size < m_allocation)
997 {
998 construct_back(data);
999 }
1000 else if (m_size == 0)
1001 {
1002 init(data);
1003 }
1004 else
1005 {
1006 grow(data);
1007 }
1008
1009 invariants();
1010 }
1011
1012 pointer
1013 ensureCapacity(size_type theSize)
1014 {
1015 if (theSize > capacity())
1016 {
1017 doReserve(theSize);
1018 }
1019
1020 return endPointer();
1021 }
1022
1023 void
1024 doReserve(size_type theSize)
1025 {
1026 invariants();
1027
1028 assert(theSize > m_allocation);
1029
1030 ThisType theTemp(*this, *m_memoryManager, theSize);
1031
1032 swap(theTemp);
1033
1034 invariants();
1035 }
1036
1037 pointer
1038 endPointer()
1039 {
1040 return m_data + m_size;
1041 }
1042
1043 const_pointer
1044 endPointer() const
1045 {
1046 return m_data + m_size;
1047 }
1048
1049 static void
1050 outOfRange()
1051 {
1052 throw std::out_of_range("");
1053 }
1054
1055 void
1056 shrinkToSize(size_type theSize)
1057 {
1058 assert(m_size > theSize);
1059
1060 do
1061 {
1062 pop_back();
1063 } while (m_size > theSize);
1064 }
1065
1066 void
1067 shrinkCount(size_type theCount)
1068 {
1069 assert(m_size >= theCount);
1070
1071 while (theCount > 0)
1072 {
1073 pop_back();
1074
1075 --theCount;
1076 }
1077 }
1078
1079 size_type
1080 local_max(
1081 size_type theLHS,
1082 size_type theRHS)
1083 {
1084 return theLHS > theRHS ? theLHS : theRHS;
1085 }
1086
1087#if defined(XALAN_DEVELOPMENT)
1088 //not implemented
1089 XalanVector(const XalanVector&);
1090 XalanVector();
1091#endif
1092
1093 // Data members...
1094 MemoryManager* m_memoryManager;
1095
1096 size_type m_size;
1097
1098 size_type m_allocation;
1099
1100 value_type* m_data;
1101};
1102
1103
1104
1105template <class Type>
1106inline void
1110{
1111 theLHS.swap(theRHS);
1112}
1113
1114
1115
1116template <class Type>
1117inline bool
1121{
1122 if (theLHS.size() != theRHS.size())
1123 {
1124 return false;
1125 }
1126 else if (theLHS.size() == 0)
1127 {
1128 return true;
1129 }
1130 else
1131 {
1132 return std::equal(theLHS.begin(), theLHS.end(), theRHS.begin());
1133 }
1134}
1135
1136
1137
1138template <class Type>
1139inline bool
1143{
1144 return !(theLHS == theRHS);
1145}
1146
1147
1148
1149template <class Type>
1150inline bool
1151operator<(
1154{
1155 return std::lexicographical_compare(
1156 theLHS.begin(),
1157 theLHS.end(),
1158 theRHS.begin(),
1159 theRHS.end());
1160}
1161
1162
1163
1164template <class Type>
1165inline bool
1169{
1170 return !(theRHS < theLHS);
1171}
1172
1173
1174
1175template <class Type>
1176inline bool
1180{
1181 return theRHS < theLHS;
1182}
1183
1184
1185
1186template <class Type>
1187inline bool
1191{
1192 return !(theLHS < theRHS);
1193}
1194
1195
1196
1197#if defined(_MSC_VER)
1198#pragma warning(pop)
1199#endif
1200
1201
1202
1203}
1204
1205
1206
1207#endif // XALANVECTOR_HEADER_GUARD_1357924680
#define XALAN_DEFAULT_CONSTRUCTOR_MEMMGR
#define XALAN_CPP_NAMESPACE
Xalan-C++ namespace, including major and minor version.
MemoryManager & getMemoryManager()
size_type size() const
reference at(size_type theIndex)
XalanVector(MemoryManager &theManager XALAN_DEFAULT_CONSTRUCTOR_MEMMGR, size_type initialAllocation=size_type(0))
const value_type & const_reference
void swap(ThisType &theOther)
void insert(iterator thePosition, const_iterator theFirst, const_iterator theLast)
iterator erase(iterator position)
void push_back(const value_type &data)
const_reference at(size_type theIndex) const
static XalanVector * create(const_iterator theFirst, const_iterator theLast, MemoryManager &theManager)
const_reference front() const
XalanVector(size_type theInsertSize, const value_type &theData, MemoryManager &theManager)
void assign(iterator theFirst, iterator theLast)
const value_type * const_pointer
XalanVector(const ThisType &theSource, MemoryManager &theManager XALAN_DEFAULT_CONSTRUCTOR_MEMMGR, size_type theInitialAllocation=size_type(0))
ConstructionTraits::Constructor Constructor
reverse_iterator rend()
size_type max_size() const
iterator insert(iterator thePosition, const value_type &theData)
const_iterator end() const
const value_type * const_iterator
const_reference back() const
value_type & reference
const_reverse_iterator_ const_reverse_iterator
static XalanVector * create(MemoryManager &theManager, size_type initialAllocation=size_type(0))
XalanVector(const_iterator theFirst, const_iterator theLast, MemoryManager &theManager)
const_reference operator[](size_type theIndex) const
const_reverse_iterator rbegin() const
const_iterator begin() const
XalanVector< value_type, ConstructionTraits > ThisType
const_reverse_iterator rend() const
std::reverse_iterator< iterator > reverse_iterator_
void resize(size_type theSize, const value_type &theValue)
void assign(size_type theCount, const value_type &theData)
iterator erase(iterator theFirst, iterator theLast)
ThisType & operator=(const ThisType &theRHS)
ptrdiff_t difference_type
Constructor::ConstructableType ConstructibleType
value_type * iterator
reverse_iterator_ reverse_iterator
const MemoryManager & getMemoryManager() const
reverse_iterator rbegin()
std::reverse_iterator< const_iterator > const_reverse_iterator_
size_type capacity() const
reference operator[](size_type theIndex)
void assign(const_iterator theFirst, const_iterator theLast)
void reserve(size_type theSize)
value_type * pointer
void insert(iterator thePosition, size_type theCount, const value_type &theData)
void resize(size_type theSize)
void clear(XalanDOMString &theString)
Remove all elements from target string.
XalanDOMString & insert(XalanDOMString &theString, XalanDOMString::size_type thePosition, const XalanDOMString &theStringToInsert)
Insert a string into another string.
void erase(XalanDOMString &theString)
Remove all elements from target string.
void swap(XalanVector< Type > &theLHS, XalanVector< Type > &theRHS)
size_t size_type
Definition XalanMap.hpp:46
XalanDOMString & assign(XalanDOMString &theString, const XalanDOMString &theStringToAssign)
Assign one string to another.
void reserve(XalanDOMString &theString, XalanDOMString::size_type theCount)
Reserve some space in the string for more efficient concatenation...
bool operator==(const XalanVector< Type > &theLHS, const XalanVector< Type > &theRHS)
bool operator!=(const XalanVector< Type > &theLHS, const XalanVector< Type > &theRHS)
bool operator>(const XalanVector< Type > &theLHS, const XalanVector< Type > &theRHS)
bool operator>=(const XalanVector< Type > &theLHS, const XalanVector< Type > &theRHS)