InDesign SDK  20.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
K2VectorHelpers.h
1 //========================================================================================
2 //
3 // $File$
4 //
5 // Owner: Mat Marcus
6 //
7 // $Author$
8 //
9 // $DateTime$
10 //
11 // $Revision$
12 //
13 // $Change$
14 //
15 // ADOBE CONFIDENTIAL. Portions Copyright 2013 Adobe Systems Incorporated. All rights reserved.
16 //
17 // NOTICE: All information contained herein is, and remain the property of Adobe Systems Incorporated
18 // and its suppliers, if any. The intellectual and technical concepts contained herein are proprietary
19 // to Adobe Systems Incorporated and its suppliers and are protected by all applicable intellectual property
20 // laws, including trade secret and copyright laws. Dissemination of this information or reproduction of
21 // this material is strictly forbidden unless prior written permission is obtained from Adobe Systems Incorporated.
22 //
23 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance
24 // with the terms of the Adobe license agreement accompanying it. If you have received
25 // this file from a source other than Adobe, then your use, modification, or
26 // distribution of it requires the prior written permission of Adobe.
27 //
28 //
29 // Copyright (c) 1994
30 // Hewlett-Packard Company
31 //
32 // Copyright (c) 1996,1997
33 // Silicon Graphics Computer Systems, Inc.
34 //
35 // Copyright (c) 1997
36 // Moscow Center for SPARC Technology
37 //
38 // Copyright (c) 1999
39 // Boris Fomitchev
40 //
41 // This material is provided "as is", with absolutely no warranty expressed
42 // or implied. Any use is at your own risk.
43 //
44 // Permission to use or copy this software for any purpose is hereby granted
45 // without fee, provided the above notices are retained on all copies.
46 // Permission to modify the code and to distribute modified code is granted,
47 // provided the above notices are retained, and a notice that the code was
48 // modified is included with the above copyright notice.
49 //
50 //========================================================================================
51 
52 #ifndef __K2VectorHelpers__
53 #define __K2VectorHelpers__
54 
55 namespace VectorHelpers {
56  struct ForwardIterTag {};
57  struct IntegerTag {};
58  struct InputIterTag {};
59 
60  // Forward (or better) Iterators
61  template <class ForwardIterator, class Vector>
62  void assign(ForwardIterator first, ForwardIterator last, Vector* v, typename Vector::Hole h, ForwardIterTag)
63  {
64  typedef typename Vector::size_type size_type;
65  size_type (&fLength) (h.LengthRef(v));
66  typedef typename Vector::pointer pointer;
67 // pointer(&fArray)(h.ArrayRef(v));
68  typedef typename Vector::allocator_type allocator_type;
69  K2EmptyMemberOpt<allocator_type, size_type> (& fAllocator) (h.AllocatorRef(v));
70  size_type len = (size_type)std::distance(first, last); // $$$ need to get rid of all the calls to standard algorithms
71  ASSERT_MSG(len <= v->max_size(), "K2VectorTempBase::assign length error");
72 
73  if (len <= v->capacity())
74  {
75  typename Vector::iterator i = v->begin();
76 
77  if (len <= fLength)
78  {
79  i = K2copy(first, last, i);
80  K2destroy(i, v->end());
81  }
82  else
83  {
84 
85  ForwardIterator mid = first;
86  std::advance(mid, fLength); //$$$ remove std calls
87  i = K2copy(first, mid, i);
88  K2uninitialized_copy(mid, last, i);
89  }
90 
91  fLength = len;
92  }
93  else
94  {
95  typename Vector::pointer newData = fAllocator.allocate(len);
96  K2uninitialized_copy(first, last, newData);
97  v->DoReset(newData, len, len);
98  }
99  }
100 
101  template <class ForwardIterator, class Vector>
102  void insert(typename Vector::iterator position, ForwardIterator first, ForwardIterator last, Vector* v, typename Vector::Hole h, ForwardIterTag)
103  {
104  typedef typename Vector::size_type size_type;
105  typedef typename Vector::Hole Hole;
106  size_type (&fLength) (h.LengthRef(v));
107  typedef typename Vector::pointer pointer;
108  pointer(&fArray)(h.ArrayRef(v));
109 
110  typedef typename Vector::allocator_type allocator_type;
111  K2EmptyMemberOpt<allocator_type, size_type> (& fAllocator) (h.AllocatorRef(v));
112 
113  ASSERT(position >= v->begin());
114  ASSERT(position <= v->end());
115  ASSERT(first <= last);
116 
117  size_type n = (size_type) std::distance(first, last); // $$$ remove calls to std::
118  ASSERT(n <= v->max_size());
119  ASSERT(fLength <= v->max_size() - n);
120 
121  if (first == last)
122  return;
123 
124  if (fLength + n <= v->capacity())
125  {
126  typename Vector::pointer oldFinish = fArray + fLength; // same as end()
127  const size_type elementsAfter = static_cast<size_type>(oldFinish - position);
128  if (n <= elementsAfter)
129  {
130  // Copy the elements at the end of the array into the uninitialized part
131  // of the vector
132  K2uninitialized_copy(oldFinish - n, oldFinish, oldFinish);
133 
134  // Move any remaining elements over to make room for the new elements
135  K2copy_backward(position, oldFinish - n, oldFinish);
136 
137  // Copy the new elements in
138  K2copy(first, last, position);
139  }
140  else
141  {
142  // Copy the elements at the end of the array into the uninitialized part
143  // of the vector
144  K2uninitialized_copy(position, oldFinish, oldFinish + n - elementsAfter);
145 
146  // Copy the new elements in
147  K2copy(first, first+elementsAfter, position);
148 
149  std::advance(first, elementsAfter); //$$$ remove calls to std::
150 
151  // Construct the new elements after the old array end
152  K2uninitialized_copy(first, last, oldFinish);
153  }
154  fLength += n;
155  }
156  else
157  {
158  size_type newLen = fLength + n;
159  size_type newCap = v->DoGetCapacity(newLen);
160 
161  // Copy over the old data up to our insertion point
162  typename Vector::pointer newData = fAllocator.allocate(newCap);
163  typename Vector::pointer newFinish = K2uninitialized_copy(fArray, position, newData);
164 
165  // Stick the new data in
166  newFinish = K2uninitialized_copy(first, last, newFinish);
167 
168  // And copy any old data after the insertion point
169  K2uninitialized_copy(position, fArray + fLength, newFinish);
170 
171  v->DoReset(newData, newLen, newCap);
172  }
173  }
174 
175  template <class ForwardIterator, class Vector>
176  void initialize(ForwardIterator first, ForwardIterator last, Vector* v, typename Vector::Hole h, ForwardIterTag)
177 
178  {
179  typedef typename Vector::size_type size_type;
180  typedef typename Vector::Hole Hole;
181  size_type (&fLength) (h.LengthRef(v));
182  typedef typename Vector::pointer pointer;
183  pointer(&fArray)(h.ArrayRef(v));
184  typedef typename Vector::allocator_type allocator_type;
185  K2EmptyMemberOpt<allocator_type, size_type> (& fAllocator) (h.AllocatorRef(v));
186 
187  fLength = fAllocator.f = std::distance(first, last); // $$$ remove calls to std::
188  ASSERT_MSG (fAllocator.f <= v->max_size(), "K2VectorTempBase::construction length error");
189  fArray = nil;
190 
191  if (fAllocator.f > 0)
192  {
193  fArray = fAllocator.allocate(fAllocator.f);
194  K2uninitialized_copy(first, last, fArray);
195  }
196  }
197 
198  // Integers
199  template <typename I, class Vector>
200  void assign(I count, I value, Vector* v, typename Vector::Hole h, IntegerTag)
201  {
202  v->fill_assign(count, value);
203  }
204 
205 
206  template <typename I, class Vector>
207  void initialize(I count, I value, Vector* v, typename Vector::Hole h, IntegerTag)
208  {
209  v->initialize(count, value);
210  }
211 
212  template <typename I, class Vector>
213  void insert(typename Vector::iterator pos, I count, I value, Vector* v, typename Vector::Hole /* h */, IntegerTag)
214  {
215  v->fill_insert(pos, count, value);
216  }
217 
218  // Input Iterators
219  template <class InputIterator, class Vector>
220  void assign(InputIterator first, InputIterator last, Vector* v, typename Vector::Hole h, InputIterTag)
221  {
222  typename Vector::iterator cur = v->begin();
223  for ( ; first != last && cur != v->end(); ++cur, ++first)
224  *cur = *first;
225 
226  if (first == last)
227  v->erase(cur, v->end());
228  else
229  v->insert(v->end(), first, last);
230  }
231 
232  template <class InputIterator, class Vector>
233  void initialize(InputIterator first, InputIterator last, Vector* v, typename Vector::Hole h, InputIterTag)
234  {
235  for ( ; first != last; ++first)
236  v->push_back(*first);
237  }
238 
239  template <class InputIterator, class Vector>
240  void insert(typename Vector::iterator pos, InputIterator first, InputIterator last, Vector* v, typename Vector::Hole h, InputIterTag)
241  {
242  uint32 index = pos - v->begin();
243  for ( ; first != last; ++first) // with a normal iterator we can optimize the code using std::distance
244  { // but this doesn't work too well with input iterators so we have to go the inefficient route
245  v->insert(v->begin() + index, *first);
246  ++index; // insert invalidates iterators so we'll use indices
247  }
248  }
249 
250 } // namespace VectorHelpers
251 #endif // __K2VectorHelpers__