|
|
|
1 |
|
// memory stl/clr header |
2 |
|
#ifndef _CLI_MEMORY_ |
3 |
|
#define _CLI_MEMORY_ |
4 |
|
#include <cliext/iterator> |
5 |
|
#include <cliext/utility> // for pair |
6 |
|
|
7 |
|
#ifdef _M_CEE_SAFE |
8 |
|
#define _PAIR_TYPE(iter_t) cliext::pair<iter_t, iter_t> // iterator pair |
9 |
|
#define _PAIR_TYPE2(iter1_t, iter2_t) \ |
10 |
|
cliext::pair<iter1_t, iter2_t> // iterator pair |
11 |
|
|
12 |
|
#define _STLCLRDB_ERROR(mesg) |
13 |
|
#define _STLCLRDB_LT(left, right) ((left) < (right)) |
14 |
|
#define _STLCLRDB_LT_PRED(pred, left, right) ((pred)(left, right)) |
15 |
|
|
16 |
|
#define _STLCLRDB_POINTER(first) |
17 |
|
|
18 |
|
#define _STLCLRDB_ORDER(first, last) |
19 |
|
#define _STLCLRDB_ORDER_PRED(first, last, pred) |
20 |
|
|
21 |
|
#define _STLCLRDB_RANGE(first, last) |
22 |
|
|
23 |
|
#else /* _M_CEE_SAFE */ |
24 |
|
#include <climits> // for CHAR_MAX, UCHAR_MAX |
25 |
|
#include <cstddef> // for ptrdiff_t, size_t |
26 |
|
#include <cstring> // form mem* functions |
27 |
|
#include <new> // for placement new |
28 |
|
#include <utility> // for std::pair |
29 |
|
#include <xutility> // for CHAR_MAX, UCHAR_MAX, iterator debugging |
30 |
|
|
31 |
|
#define _PAIR_TYPE(iter_t) typename cliext::_Pick_pair< \ |
32 |
|
__is_value_class(iter_t) || __is_ref_class(iter_t), \ |
33 |
|
iter_t, iter_t>::value_type |
34 |
|
#define _PAIR_TYPE2(iter1_t, iter2_t) typename cliext::_Pick_pair< \ |
35 |
|
__is_value_class(iter1_t) || __is_ref_class(iter1_t), \ |
36 |
|
iter1_t, iter2_t>::value_type // both managed or both unmanaged |
37 |
|
|
38 |
|
namespace cliext { |
39 |
|
template<bool _Is_managed, |
40 |
|
typename _Value1_t, |
41 |
|
typename _Value2_t> |
42 |
|
class _Pick_pair; // select managed or unmanaged type |
43 |
|
|
44 |
|
template<typename _Value1_t, |
45 |
|
typename _Value2_t> |
46 |
|
class _Pick_pair<false, _Value1_t, _Value2_t> |
47 |
|
{ // define unmanaged type |
48 |
|
public: |
49 |
|
typedef std::pair<_Value1_t, _Value2_t> value_type; |
50 |
|
}; |
51 |
|
|
52 |
|
template<typename _Value1_t, |
53 |
|
typename _Value2_t> |
54 |
|
class _Pick_pair<true, _Value1_t, _Value2_t> |
55 |
|
{ // define managed type |
56 |
|
public: |
57 |
|
typedef cliext::pair<_Value1_t, _Value2_t> value_type; |
58 |
|
}; |
59 |
|
} // namespace cliext |
60 |
|
|
61 |
|
#if _HAS_ITERATOR_DEBUGGING |
62 |
|
#ifndef _STLCLRDB_REPORT |
63 |
|
#define _STLCLRDB_REPORT(mesg, file, line) \ |
64 |
|
std::_DEBUG_ERROR2(mesg, file, line) |
65 |
|
#endif /* _STLCLRDB_REPORT */ |
66 |
|
|
67 |
|
#define _STLCLRDB_ERROR(mesg) \ |
68 |
|
_STLCLRDB_REPORT(mesg, __FILEW__, __LINE__) |
69 |
|
|
70 |
|
#define _STLCLRDB_LT(left, right) \ |
71 |
|
cliext::_Stlclrdb_lt(left, right, __FILEW__, __LINE__) |
72 |
|
#define _STLCLRDB_LT_PRED(pred, left, right) \ |
73 |
|
cliext::_Stlclrdb_lt_pred(pred, left, right, __FILEW__, __LINE__) |
74 |
|
|
75 |
|
#define _STLCLRDB_POINTER(first) \ |
76 |
|
cliext::_Stlclrdb_pointer(first, __FILEW__, __LINE__) |
77 |
|
#define _STLCLRDB_POINTER2(first, filew, line) \ |
78 |
|
cliext::_Stlclrdb_pointer(first, filew, line) |
79 |
|
|
80 |
|
#define _STLCLRDB_ORDER(first, last) \ |
81 |
|
cliext::_Stlclrdb_order(first, last, __FILEW__, __LINE__) |
82 |
|
#define _STLCLRDB_ORDER_PRED(first, last, pred) \ |
83 |
|
cliext::_Stlclrdb_order(first, last, pred, __FILEW__, __LINE__) |
84 |
|
|
85 |
|
#define _STLCLRDB_RANGE(first, last) \ |
86 |
|
cliext::_Stlclrdb_range(first, last, __FILEW__, __LINE__) |
87 |
|
#define _STLCLRDB_RANGE2(first, last, filew, line) \ |
88 |
|
cliext::_Stlclrdb_range(first, last, filew, line) |
89 |
|
|
90 |
|
namespace cliext { |
91 |
|
template<class _Ty1, class _Ty2> inline |
92 |
|
bool _Stlclrdb_lt(_Ty1% _Left, _Ty2% _Right, |
93 |
|
const wchar_t *_File, unsigned int _Line) |
94 |
|
{ // test if _Left < _Right and operator< is strict weak ordering |
95 |
|
if (!(_Left < _Right)) |
96 |
|
return (false); |
97 |
|
else if (_Right < _Left) |
98 |
|
_STLCLRDB_REPORT("invalid operator<", _File, _Line); |
99 |
|
return (true); |
100 |
|
} |
101 |
|
|
102 |
|
template<class _Pr, class _Ty1, class _Ty2> inline |
103 |
|
bool _Stlclrdb_lt_pred(_Pr _Pred, _Ty1% _Left, _Ty2% _Right, |
104 |
|
const wchar_t *_File, unsigned int _Line) |
105 |
|
{ // test if _Pred(_Left, _Right) and _Pred is strict weak ordering |
106 |
|
if (!_Pred(_Left, _Right)) |
107 |
|
return (false); |
108 |
|
else if (_Pred(_Right, _Left)) |
109 |
|
_STLCLRDB_REPORT("invalid operator<", _File, _Line); |
110 |
|
return (true); |
111 |
|
} |
112 |
|
|
113 |
|
// TEMPLATE FUNCTION _Stlclrdb_pointer |
114 |
|
template<class _InIt> inline |
115 |
|
void _Stlclrdb_pointer(_InIt%, const wchar_t *, unsigned int) |
116 |
|
{ // test pointer for non-singularity, arbitrary type |
117 |
|
} |
118 |
|
|
119 |
|
template<class _Ty> inline |
120 |
|
void _Stlclrdb_pointer(const _Ty *_First, const wchar_t *_File, |
121 |
|
unsigned int _Line) |
122 |
|
{ // test iterator for non-singularity, const pointers |
123 |
|
if (_First == 0) |
124 |
|
_STLCLRDB_REPORT("invalid null pointer", _File, _Line); |
125 |
|
} |
126 |
|
|
127 |
|
template<class _Ty> inline |
128 |
|
void _Stlclrdb_pointer(_Ty *_First, const wchar_t *_File, |
129 |
|
unsigned int _Line) |
130 |
|
{ // test iterator for non-singularity, pointers |
131 |
|
if (_First == 0) |
132 |
|
_STLCLRDB_REPORT("invalid null pointer", _File, _Line); |
133 |
|
} |
134 |
|
|
135 |
|
// TEMPLATE FUNCTION _Stlclrdb_order |
136 |
|
template<class _InIt> inline |
137 |
|
void _Stlclrdb_order2(_InIt _First, _InIt _Last, |
138 |
|
const wchar_t *_File, unsigned int _Line, input_iterator_tag) |
139 |
|
{ // test if range is ordered by operator<, input iterators |
140 |
|
} |
141 |
|
|
142 |
|
template<class _FwdIt> inline |
143 |
|
void _Stlclrdb_order2(_FwdIt _First, _FwdIt _Last, |
144 |
|
const wchar_t *_File, unsigned int _Line, forward_iterator_tag) |
145 |
|
{ // test if range is ordered by operator<, forward iterators |
146 |
|
for (_FwdIt _Next = _First; _First != _Last && ++_Next != _Last; ++_First) |
147 |
|
if (_STLCLRDB_LT(*_Next, *_First)) |
148 |
|
_STLCLRDB_REPORT("sequence not ordered", _File, _Line); |
149 |
|
} |
150 |
|
|
151 |
|
template<class _InIt> inline |
152 |
|
void _Stlclrdb_order(_InIt _First, _InIt _Last, |
153 |
|
const wchar_t *_File, unsigned int _Line) |
154 |
|
{ // test is range is ordered by operator< |
155 |
|
_STLCLRDB_RANGE2(_First, _Last, _File, _Line); |
156 |
|
_Stlclrdb_order2(_First, _Last, _File, _Line, _Iter_category(_First)); |
157 |
|
} |
158 |
|
|
159 |
|
// TEMPLATE FUNCTION _Stlclrdb_order WITH PRED |
160 |
|
template<class _InIt, |
161 |
|
class _Pr> inline |
162 |
|
void _Stlclrdb_order2(_InIt _First, _InIt _Last, _Pr _Pred, |
163 |
|
const wchar_t *_File, unsigned int _Line, input_iterator_tag) |
164 |
|
{ // test if range is ordered by predicate, input iterators |
165 |
|
} |
166 |
|
|
167 |
|
template<class _FwdIt, |
168 |
|
class _Pr> inline |
169 |
|
void _Stlclrdb_order2(_FwdIt _First, _FwdIt _Last, _Pr _Pred, |
170 |
|
const wchar_t *_File, unsigned int _Line, forward_iterator_tag) |
171 |
|
{ // test if range is ordered by predicate, forward iterators |
172 |
|
for (_FwdIt _Next = _First; _First != _Last && ++_Next != _Last; ++_First) |
173 |
|
if (_STLCLRDB_LT_PRED(_Pred, *_Next, *_First)) |
174 |
|
_STLCLRDB_REPORT("sequence not ordered", _File, _Line); |
175 |
|
} |
176 |
|
|
177 |
|
template<class _InIt, |
178 |
|
class _Pr> inline |
179 |
|
void _Stlclrdb_order(_InIt _First, _InIt _Last, _Pr _Pred, |
180 |
|
const wchar_t *_File, unsigned int _Line) |
181 |
|
{ // test if range is ordered by predicate |
182 |
|
_STLCLRDB_RANGE2(_First, _Last, _File, _Line); |
183 |
|
_STLCLRDB_POINTER2(_Pred, _File, _Line); |
184 |
|
_Stlclrdb_order2(_First, _Last, _Pred, _File, _Line, |
185 |
|
_Iter_category(_First)); |
186 |
|
} |
187 |
|
|
188 |
|
// TEMPLATE FUNCTION _Stlclrdb_range |
189 |
|
template<class _InIt> inline |
190 |
|
void _Stlclrdb_range2(_InIt, _InIt, |
191 |
|
const wchar_t *, unsigned int, input_iterator_tag) |
192 |
|
{ // test iterator pair for valid range, arbitrary iterators |
193 |
|
} |
194 |
|
|
195 |
|
template<class _RanIt> inline |
196 |
|
void _Stlclrdb_range2(_RanIt _First, _RanIt _Last, |
197 |
|
const wchar_t *_Filew, unsigned int _Line, |
198 |
|
random_access_iterator_tag) |
199 |
|
{ // test iterator pair for valid range, random-access iterators |
200 |
|
if (_First != _Last) |
201 |
|
{ // check for non-null pointers, valid range |
202 |
|
_STLCLRDB_POINTER2(_First, _Filew, _Line); |
203 |
|
_STLCLRDB_POINTER2(_Last, _Filew, _Line); |
204 |
|
if (_Last < _First) |
205 |
|
_STLCLRDB_REPORT("invalid iterator range", _Filew, _Line); |
206 |
|
} |
207 |
|
} |
208 |
|
|
209 |
|
template<class _InIt> inline |
210 |
|
void _Stlclrdb_range(_InIt _First, _InIt _Last, |
211 |
|
const wchar_t *_Filew, unsigned int _Line) |
212 |
|
{ // test iterator pair for valid range |
213 |
|
_Stlclrdb_range2(_First, _Last, _Filew, _Line, _Iter_category(_First)); |
214 |
|
} |
215 |
|
} // namespace cliext |
216 |
|
|
217 |
|
#else /* _HAS_ITERATOR_DEBUGGING */ |
218 |
|
#define _STLCLRDB_LT(left, right) ((left) < (right)) |
219 |
|
#define _STLCLRDB_LT_PRED(pred, left, right) ((pred)(left, right)) |
220 |
|
|
221 |
|
#define _STLCLRDB_POINTER(first) |
222 |
|
|
223 |
|
#define _STLCLRDB_ORDER(first, last) |
224 |
|
#define _STLCLRDB_ORDER_PRED(first, last, pred) |
225 |
|
|
226 |
|
#define _STLCLRDB_RANGE(first, last) |
227 |
|
#endif /* _HAS_ITERATOR_DEBUGGING */ |
228 |
|
#endif /* _M_CEE_SAFE */ |
229 |
|
|
230 |
|
namespace cliext { |
231 |
|
// |
232 |
|
// UN/MANAGED TEMP BUFFER SELECTOR |
233 |
|
// |
234 |
|
template<typename _Value_t> |
235 |
|
value class _Temp_gc_iterator; |
236 |
|
|
237 |
|
template<typename _Value_t> |
238 |
|
class _Temp_iterator; |
239 |
|
|
240 |
|
#ifdef _M_CEE_SAFE |
241 |
|
#define _TEMP_ITER(iter_t, value_t) _Temp_gc_iterator<value_t> |
242 |
|
|
243 |
|
#else /* _M_CEE_SAFE */ |
244 |
|
#define _TEMP_ITER(iter_t, value_t) typename cliext::_Pick_tbuf< \ |
245 |
|
__is_value_class(iter_t) || __is_ref_class(iter_t), value_t>::value_type |
246 |
|
|
247 |
|
template<bool _Is_managed, |
248 |
|
typename _Value_t> |
249 |
|
class _Pick_tbuf; // select managed or unmanaged type |
250 |
|
|
251 |
|
template<typename _Value_t> |
252 |
|
class _Pick_tbuf<false, _Value_t> |
253 |
|
{ // define unmanaged type |
254 |
|
public: |
255 |
|
typedef cliext::_Temp_iterator<_Value_t> value_type; |
256 |
|
}; |
257 |
|
|
258 |
|
template<typename _Value_t> |
259 |
|
class _Pick_tbuf<true, _Value_t> |
260 |
|
{ // define managed type |
261 |
|
public: |
262 |
|
typedef cliext::_Temp_gc_iterator<_Value_t> value_type; |
263 |
|
}; |
264 |
|
|
265 |
|
// TEMPLATE FUNCTION get_temporary_buffer |
266 |
|
template<class _Ty> inline |
267 |
|
pair<_Ty *, std::ptrdiff_t> |
268 |
|
get_temporary_buffer(std::ptrdiff_t _Count) |
269 |
|
{ // get raw temporary buffer of up to _Count elements |
270 |
|
_Ty *_Pbuf; |
271 |
|
|
272 |
|
if (_Count < 0) |
273 |
|
_Count = 0; |
274 |
|
for (_Pbuf = 0; 0 < _Count; _Count /= 2) |
275 |
|
try |
276 |
|
{ // try to allocate storage |
277 |
|
_Pbuf = (_Ty *)::operator new(_Count * sizeof (_Ty)); |
278 |
|
break; |
279 |
|
} |
280 |
|
catch (...) |
281 |
|
{ // loop if new fails |
282 |
|
} |
283 |
|
|
284 |
|
return (pair<_Ty *, std::ptrdiff_t>(_Pbuf, _Count)); |
285 |
|
} |
286 |
|
|
287 |
|
// TEMPLATE FUNCTION return_temporary_buffer |
288 |
|
template<class _Ty> inline |
289 |
|
void return_temporary_buffer(_Ty *_Pbuf) |
290 |
|
{ // delete raw temporary buffer |
291 |
|
::operator delete(_Pbuf); |
292 |
|
} |
293 |
|
|
294 |
|
// TEMPLATE CLASS _Temp_iterator |
295 |
|
template<class _Ty> |
296 |
|
class _Temp_iterator |
297 |
|
{ // wrap stores to unmanaged temporary buffer as output iterator |
298 |
|
public: |
299 |
|
typedef _Temp_iterator<_Ty> _Mytype_t; |
300 |
|
typedef _Ty *_Pty; |
301 |
|
typedef output_iterator_tag iterator_category; |
302 |
|
|
303 |
|
_Temp_iterator(std::ptrdiff_t _Count = 0) |
304 |
|
{ // construct from desired temporary buffer size |
305 |
|
_Buf._Begin = 0; |
306 |
|
_Buf._Current = 0; |
307 |
|
_Buf._Hiwater = 0; |
308 |
|
_Buf._Size = _Count; // memorize size for lazy allocation |
309 |
|
_Pbuf = &_Buf; |
310 |
|
} |
311 |
|
|
312 |
|
_Temp_iterator(const _Temp_iterator& _Right) |
313 |
|
{ // construct from _Right (share active buffer) |
314 |
|
_Buf._Begin = 0; // clear stored buffer, for safe destruction |
315 |
|
_Buf._Current = 0; |
316 |
|
_Buf._Hiwater = 0; |
317 |
|
_Buf._Size = 0; |
318 |
|
*this = _Right; |
319 |
|
} |
320 |
|
|
321 |
|
~_Temp_iterator() |
322 |
|
{ // destroy the object |
323 |
|
if (_Buf._Begin != 0) |
324 |
|
{ // destroy any constructed elements in buffer |
325 |
|
for (_Pty _Next = _Buf._Begin; |
326 |
|
_Next != _Buf._Hiwater; ++_Next) |
327 |
|
_Next->~_Ty(); |
328 |
|
return_temporary_buffer(_Buf._Begin); |
329 |
|
} |
330 |
|
} |
331 |
|
|
332 |
|
_Temp_iterator& operator=(const _Temp_iterator& _Right) |
333 |
|
{ // assign _Right (share active buffer) |
334 |
|
_Pbuf = _Right._Pbuf; |
335 |
|
return (*this); |
336 |
|
} |
337 |
|
|
338 |
|
_Temp_iterator& operator=(_Ty& _Val) |
339 |
|
{ // assign or construct value into active buffer, and increment |
340 |
|
if (_Pbuf->_Current < _Pbuf->_Hiwater) |
341 |
|
*_Pbuf->_Current++ = _Val; // below high water mark, assign |
342 |
|
else |
343 |
|
{ // above high water mark, construct |
344 |
|
_Pty _Ptr = &*_Pbuf->_Current; |
345 |
|
::new (_Ptr) _Ty(_Val); |
346 |
|
_Pbuf->_Hiwater = ++_Pbuf->_Current; |
347 |
|
} |
348 |
|
return (*this); |
349 |
|
} |
350 |
|
|
351 |
|
_Temp_iterator& operator*() |
352 |
|
{ // pretend to return designated value |
353 |
|
return (*this); |
354 |
|
} |
355 |
|
|
356 |
|
_Temp_iterator& operator++() |
357 |
|
{ // pretend to preincrement |
358 |
|
return (*this); |
359 |
|
} |
360 |
|
|
361 |
|
_Temp_iterator& operator++(int) |
362 |
|
{ // pretend to postincrement |
363 |
|
return (*this); |
364 |
|
} |
365 |
|
|
376 |
|
|
377 |
|
_Pty _Last() const |
378 |
|
{ // return pointer past end of buffer contents |
379 |
|
return (_Pbuf->_Current); |
380 |
|
} |
381 |
|
|
382 |
|
std::ptrdiff_t _Maxlen() |
383 |
|
{ // return size of buffer |
384 |
|
if (_Pbuf->_Begin == 0 && 0 < _Pbuf->_Size) |
385 |
|
{ // allocate buffer on first size query |
386 |
|
pair<_Pty, std::ptrdiff_t> _Pair = |
387 |
|
get_temporary_buffer<_Ty>(_Pbuf->_Size); |
388 |
|
|
389 |
|
_Pbuf->_Begin = _Pair.first; |
390 |
|
_Pbuf->_Current = _Pair.first; |
391 |
|
_Pbuf->_Hiwater = _Pair.first; |
392 |
|
_Pbuf->_Size = _Pair.second; |
393 |
|
} |
394 |
|
return (_Pbuf->_Size); |
395 |
|
} |
396 |
|
|
397 |
|
//_STLCLR_FIELD_ACCESS: |
398 |
|
struct _Bufpar |
399 |
|
{ // control information for a temporary buffer |
400 |
|
_Pty _Begin; // pointer to beginning of buffer |
401 |
|
_Pty _Current; // pointer to next available element |
402 |
|
_Pty _Hiwater; // pointer to first unconstructed element |
403 |
|
std::ptrdiff_t _Size; // length of buffer |
404 |
|
}; |
405 |
|
|
406 |
|
_Bufpar _Buf; // buffer control stored in iterator |
407 |
|
_Bufpar *_Pbuf; // pointer to active buffer control |
408 |
|
}; |
409 |
|
#endif /* _M_CEE_SAFE */ |
410 |
|
|
411 |
|
// TEMPLATE CLASS _Temp_gc_iterator |
412 |
|
template<class _Ty> |
413 |
|
value class _Temp_gc_iterator |
414 |
|
{ // wrap stores to managed temporary buffer as output iterator |
415 |
|
public: |
416 |
|
typedef _Temp_gc_iterator<_Ty> _Mytype_t; |
417 |
|
typedef cli::array<_Ty> _Myarray_t; |
418 |
|
typedef ArrayContainer<_Ty> _Mycont_t; |
419 |
|
typedef typename _Mycont_t::iterator iterator; |
420 |
|
|
421 |
|
_Temp_gc_iterator(int _Count) |
422 |
|
: _Mysize(_Count), _Mycont(nullptr), _Next(nullptr) |
423 |
|
{ // construct from desired temporary buffer size |
424 |
|
} |
425 |
|
|
426 |
|
static _Ty% operator*(_Temp_gc_iterator% _Left) |
427 |
|
{ // return designated value |
428 |
|
return (_Left._Next->get_ref()); |
429 |
|
} |
430 |
|
|
431 |
|
_Temp_gc_iterator operator++() |
432 |
|
{ // preincrement |
433 |
|
_Next->next(); |
434 |
|
return (*this); |
435 |
|
} |
436 |
|
|
437 |
|
iterator operator++(int) |
438 |
|
{ // postincrement |
439 |
|
iterator _Temp = *_Next; |
440 |
|
|
441 |
|
_Next->next(); |
442 |
|
return (_Temp); |
443 |
|
} |
444 |
|
|
445 |
|
_Temp_gc_iterator _Init() |
446 |
|
{ // set pointer at beginning of buffer |
447 |
|
*_Next = _Mycont->begin(); |
448 |
|
return (*this); |
449 |
|
} |
450 |
|
|
451 |
|
iterator _First() |
452 |
|
{ // return pointer to beginning of buffer |
453 |
|
return (_Mycont->begin()); |
454 |
|
} |
455 |
|
|
456 |
|
iterator _Last() |
457 |
|
{ // return pointer past end of buffer contents |
458 |
|
return (*_Next); |
459 |
|
} |
460 |
|
|
461 |
|
int _Maxlen() |
462 |
|
{ // return size of buffer |
463 |
|
if (_Mycont == nullptr) |
464 |
|
{ // allocate buffer and iterator on first size query |
465 |
|
_Mycont = gcnew _Mycont_t(_Mysize); |
466 |
|
_Next = gcnew iterator; |
467 |
|
} |
468 |
|
return (_Mycont->size()); |
469 |
|
} |
470 |
|
|
471 |
|
_STLCLR_FIELD_ACCESS: |
472 |
|
int _Mysize; // size of desired buffer |
473 |
|
_Mycont_t^ _Mycont; // handle for buffer |
474 |
|
iterator^ _Next; // iterator into buffer |
475 |
|
}; |
476 |
|
|
477 |
|
// ALGORITHM STUFF (from <algorithm>) |
478 |
|
|
479 |
|
// TEMPLATE FUNCTION swap |
480 |
|
template<class _Ty> inline |
481 |
|
void swap(_Ty% _Left, _Ty% _Right) |
482 |
|
{ // exchange values stored at _Left and _Right |
483 |
|
_Ty _Tmp = _Left; |
484 |
|
_Left = _Right, _Right = _Tmp; |
485 |
|
} |
486 |
|
|
487 |
|
// TEMPLATE FUNCTION copy |
488 |
|
template<class _InIt, |
489 |
|
class _OutIt> inline |
490 |
|
_OutIt copy_unchecked(_InIt _First, _InIt _Last, _OutIt _Dest) |
491 |
|
{ // copy [_First, _Last) to [_Dest, ...) |
492 |
|
for (; _First != _Last; ++_Dest, ++_First) |
493 |
|
*_Dest = *_First; |
494 |
|
return (_Dest); |
495 |
|
} |
496 |
|
|
497 |
|
template<class _InIt, |
498 |
|
class _OutIt> inline |
499 |
|
_OutIt copy(_InIt _First, _InIt _Last, _OutIt _Dest) |
500 |
|
{ // copy [_First, _Last) to [_Dest, ...) |
501 |
|
#if _HAS_ITERATOR_DEBUGGING |
502 |
|
_STLCLRDB_RANGE(_First, _Last); |
503 |
|
if (_First != _Last) |
504 |
|
_STLCLRDB_POINTER(_Dest); |
505 |
|
#endif /* _HAS_ITERATOR_DEBUGGING */ |
506 |
|
return (cliext::copy_unchecked( |
507 |
|
_Unchecked(_First), _Unchecked(_Last), |
508 |
|
_Unchecked(_Dest))); |
509 |
|
} |
510 |
|
|
511 |
|
// TEMPLATE FUNCTION copy_backward |
512 |
|
template<class _BidIt1, |
513 |
|
class _BidIt2> inline |
514 |
|
_BidIt2 copy_backward_unchecked(_BidIt1 _First, _BidIt1 _Last, |
515 |
|
_BidIt2 _Dest) |
516 |
|
{ // copy [_First, _Last) backwards to [..., _Dest) |
517 |
|
while (_First != _Last) |
518 |
|
*--_Dest = *--_Last; |
519 |
|
return (_Dest); |
520 |
|
} |
521 |
|
|
522 |
|
template<class _BidIt1, |
523 |
|
class _BidIt2> inline |
524 |
|
_BidIt2 copy_backward(_BidIt1 _First, _BidIt1 _Last, _BidIt2 _Dest) |
525 |
|
{ // copy [_First, _Last) backwards to [..., _Dest) |
526 |
|
#if _HAS_ITERATOR_DEBUGGING |
527 |
|
_STLCLRDB_RANGE(_First, _Last); |
528 |
|
if (_First != _Last) |
529 |
|
_STLCLRDB_POINTER(_Dest); |
530 |
|
#endif /* _HAS_ITERATOR_DEBUGGING */ |
531 |
|
return (cliext::copy_backward_unchecked( |
532 |
|
_Unchecked(_First), _Unchecked(_Last), |
533 |
|
_Unchecked(_Dest))); |
534 |
|
} |
535 |
|
|
536 |
|
// TEMPLATE FUNCTION mismatch |
537 |
|
template<class _InIt1, |
538 |
|
class _InIt2> inline |
539 |
|
_PAIR_TYPE2(_InIt1, _InIt2) |
540 |
|
mismatch_unchecked(_InIt1 _First1, _InIt1 _Last1, |
541 |
|
_InIt2 _First2) |
542 |
|
{ // return [_First1, _Last1) and [_First2, _Last2) mismatch |
543 |
|
for (; _First1 != _Last1 && *_First1 == *_First2; ) |
544 |
|
++_First1, ++_First2; |
545 |
|
return (_PAIR_TYPE2(_InIt1, _InIt2)(_First1, _First2)); |
546 |
|
} |
547 |
|
|
548 |
|
template<class _InIt1, |
549 |
|
class _InIt2> inline |
550 |
|
_PAIR_TYPE2(_InIt1, _InIt2) |
551 |
|
mismatch(_InIt1 _First1, _InIt1 _Last1, |
552 |
|
_InIt2 _First2) |
553 |
|
{ // return [_First1, _Last1) and [_First2, _Last2) mismatch |
554 |
|
#if _HAS_ITERATOR_DEBUGGING |
555 |
|
_STLCLRDB_RANGE(_First1, _Last1); |
556 |
|
if (_First1 != _Last1) |
557 |
|
_STLCLRDB_POINTER(_First2); |
558 |
|
#endif /* _HAS_ITERATOR_DEBUGGING */ |
559 |
|
|
560 |
|
return (cliext::mismatch_unchecked( |
561 |
|
_Unchecked(_First1), _Unchecked(_Last1), |
562 |
|
_Unchecked(_First2))); |
563 |
|
} |
564 |
|
|
565 |
|
// TEMPLATE FUNCTION mismatch WITH PRED |
566 |
|
template<class _InIt1, |
567 |
|
class _InIt2, |
568 |
|
class _Pr> inline |
569 |
|
_PAIR_TYPE2(_InIt1, _InIt2) |
570 |
|
mismatch_unchecked(_InIt1 _First1, _InIt1 _Last1, |
571 |
|
_InIt2 _First2, _Pr _Pred) |
572 |
|
{ // return [_First1, _Last1) and [_First2, _Last2) mismatch using _Pred |
573 |
|
for (; _First1 != _Last1 && _Pred(*_First1, *_First2); ) |
574 |
|
++_First1, ++_First2; |
575 |
|
return (_PAIR_TYPE2(_InIt1, _InIt2)(_First1, _First2)); |
576 |
|
} |
577 |
|
|
578 |
|
template<class _InIt1, |
579 |
|
class _InIt2, |
580 |
|
class _Pr> inline |
581 |
|
_PAIR_TYPE2(_InIt1, _InIt2) |
582 |
|
mismatch(_InIt1 _First1, _InIt1 _Last1, |
583 |
|
_InIt2 _First2, _Pr _Pred) |
584 |
|
{ // return [_First1, _Last1) and [_First2, _Last2) mismatch using _Pred |
585 |
|
#if _HAS_ITERATOR_DEBUGGING |
586 |
|
_STLCLRDB_RANGE(_First1, _Last1); |
587 |
|
if (_First1 != _Last1) |
588 |
|
_STLCLRDB_POINTER(_First2); |
589 |
|
_STLCLRDB_POINTER(_Pred); |
590 |
|
#endif /* _HAS_ITERATOR_DEBUGGING */ |
591 |
|
|
592 |
|
return (cliext::mismatch_unchecked( |
593 |
|
_Unchecked(_First1), _Unchecked(_Last1), |
594 |
|
_Unchecked(_First2), _Pred)); |
595 |
|
} |
596 |
|
|
597 |
|
// TEMPLATE FUNCTION equal |
598 |
|
template<class _InIt1, |
599 |
|
class _InIt2> inline |
600 |
|
bool equal_unchecked(_InIt1 _First1, _InIt1 _Last1, |
601 |
|
_InIt2 _First2) |
602 |
|
{ // compare [_First1, _Last1) to [First2, ...) |
603 |
|
for (; _First1 != _Last1; ++_First1, ++_First2) |
604 |
|
if (!(*_First1 == *_First2)) |
605 |
|
return (false); |
606 |
|
return (true); |
607 |
|
} |
608 |
|
|
609 |
|
template<class _InIt1, |
610 |
|
class _InIt2> inline |
611 |
|
bool equal(_InIt1 _First1, _InIt1 _Last1, |
612 |
|
_InIt2 _First2) |
613 |
|
{ // compare [_First1, _Last1) to [First2, ...) |
614 |
|
#if _HAS_ITERATOR_DEBUGGING |
615 |
|
_STLCLRDB_RANGE(_First1, _Last1); |
616 |
|
if (_First1 != _Last1) |
617 |
|
_STLCLRDB_POINTER(_First2); |
618 |
|
#endif /* _HAS_ITERATOR_DEBUGGING */ |
619 |
|
return (cliext::equal_unchecked( |
620 |
|
_Unchecked(_First1), _Unchecked(_Last1), |
621 |
|
_Unchecked(_First2))); |
622 |
|
} |
623 |
|
|
624 |
|
#ifdef _M_CEE_SAFE |
625 |
|
#else /* _M_CEE_SAFE */ |
626 |
|
inline bool equal(const char *_First1, const char *_Last1, |
627 |
|
const char *_First2) |
628 |
|
{ // compare [_First1, _Last1) to [First2, ...), for chars |
629 |
|
#if _HAS_ITERATOR_DEBUGGING |
630 |
|
_STLCLRDB_RANGE(_First1, _Last1); |
631 |
|
if (_First1 != _Last1) |
632 |
|
_STLCLRDB_POINTER(_First2); |
633 |
|
#endif /* _HAS_ITERATOR_DEBUGGING */ |
634 |
|
|
635 |
|
return (std::memcmp(_First1, _First2, _Last1 - _First1) == 0); |
636 |
|
} |
637 |
|
|
638 |
|
inline bool equal(const signed char *_First1, const signed char *_Last1, |
639 |
|
const signed char *_First2) |
640 |
|
{ // compare [_First1, _Last1) to [First2, ...), for signed chars |
641 |
|
#if _HAS_ITERATOR_DEBUGGING |
642 |
|
_STLCLRDB_RANGE(_First1, _Last1); |
643 |
|
if (_First1 != _Last1) |
644 |
|
_STLCLRDB_POINTER(_First2); |
645 |
|
#endif /* _HAS_ITERATOR_DEBUGGING */ |
646 |
|
|
647 |
|
return (std::memcmp(_First1, _First2, _Last1 - _First1) == 0); |
648 |
|
} |
649 |
|
|
650 |
|
inline bool equal(const unsigned char *_First1, const unsigned char *_Last1, |
651 |
|
const unsigned char *_First2) |
652 |
|
{ // compare [_First1, _Last1) to [First2, ...), for unsigned chars |
653 |
|
#if _HAS_ITERATOR_DEBUGGING |
654 |
|
_STLCLRDB_RANGE(_First1, _Last1); |
655 |
|
if (_First1 != _Last1) |
656 |
|
_STLCLRDB_POINTER(_First2); |
657 |
|
#endif /* _HAS_ITERATOR_DEBUGGING */ |
658 |
|
|
659 |
|
return (std::memcmp(_First1, _First2, _Last1 - _First1) == 0); |
660 |
|
} |
661 |
|
#endif /* _M_CEE_SAFE */ |
662 |
|
|
663 |
|
// TEMPLATE FUNCTION equal WITH PRED |
664 |
|
template<class _InIt1, |
665 |
|
class _InIt2, |
666 |
|
class _Pr> inline |
667 |
|
bool equal_unchecked(_InIt1 _First1, _InIt1 _Last1, |
668 |
|
_InIt2 _First2, _Pr _Pred) |
669 |
|
{ // compare [_First1, _Last1) to [First2, ...) using _Pred |
670 |
|
for (; _First1 != _Last1; ++_First1, ++_First2) |
671 |
|
if (!_Pred(*_First1, *_First2)) |
672 |
|
return (false); |
673 |
|
return (true); |
674 |
|
} |
675 |
|
|
676 |
|
template<class _InIt1, |
677 |
|
class _InIt2, |
678 |
|
class _Pr> inline |
679 |
|
bool equal(_InIt1 _First1, _InIt1 _Last1, |
680 |
|
_InIt2 _First2, _Pr _Pred) |
681 |
|
{ // compare [_First1, _Last1) to [First2, ...) using _Pred |
682 |
|
#if _HAS_ITERATOR_DEBUGGING |
683 |
|
_STLCLRDB_RANGE(_First1, _Last1); |
684 |
|
if (_First1 != _Last1) |
685 |
|
_STLCLRDB_POINTER(_First2); |
686 |
|
_STLCLRDB_POINTER(_Pred); |
687 |
|
#endif /* _HAS_ITERATOR_DEBUGGING */ |
688 |
|
return (cliext::equal_unchecked( |
689 |
|
_Unchecked(_First1), _Unchecked(_Last1), |
690 |
|
_Unchecked(_First2), _Pred)); |
691 |
|
} |
692 |
|
|
693 |
|
// TEMPLATE FUNCTION fill |
694 |
|
template<class _FwdIt, |
695 |
|
class _Ty> inline |
696 |
|
void fill_unchecked(_FwdIt _First, _FwdIt _Last, const _Ty% _Val) |
697 |
|
{ // copy _Val through [_First, _Last) |
698 |
|
for (; _First != _Last; ++_First) |
699 |
|
*_First = _Val; |
700 |
|
} |
701 |
|
|
702 |
|
#ifdef _M_CEE_SAFE |
703 |
|
#else /* _M_CEE_SAFE */ |
704 |
|
#ifndef _Out_capcount_x_ |
705 |
|
#define _Out_capcount_x_ __out_ecount_full |
706 |
|
#endif /* _Out_capcount_x_ */ |
707 |
|
|
708 |
|
#ifndef _In_opt |
709 |
|
#define _In_opt __in_opt |
710 |
|
#endif /* _In_opt */ |
711 |
|
|
712 |
|
inline void fill_unchecked( |
713 |
|
_Out_capcount_x_(_Last - _First) char *_First, |
714 |
|
_In_opt char *_Last, |
715 |
|
int _Val) |
716 |
|
{ // copy char _Val through [_First, _Last) |
717 |
|
std::memset(_First, _Val, _Last - _First); |
718 |
|
} |
719 |
|
|
720 |
|
inline void fill_unchecked( |
721 |
|
_Out_capcount_x_(_Last - _First) signed char *_First, |
722 |
|
_In_opt signed char *_Last, |
723 |
|
int _Val) |
724 |
|
{ // copy signed char _Val through [_First, _Last) |
725 |
|
std::memset(_First, _Val, _Last - _First); |
726 |
|
} |
727 |
|
|
728 |
|
inline void fill_unchecked( |
729 |
|
_Out_capcount_x_(_Last - _First) unsigned char *_First, |
730 |
|
_In_opt unsigned char *_Last, |
731 |
|
int _Val) |
732 |
|
{ // copy unsigned char _Val through [_First, _Last) |
733 |
|
std::memset(_First, _Val, _Last - _First); |
734 |
|
} |
735 |
|
#endif /* _M_CEE_SAFE */ |
736 |
|
|
737 |
|
template<class _FwdIt, |
738 |
|
class _Ty> inline |
739 |
|
void fill(_FwdIt _First, _FwdIt _Last, const _Ty% _Val) |
740 |
|
{ // copy _Val through [_First, _Last) |
741 |
|
_STLCLRDB_RANGE(_First, _Last); |
742 |
|
cliext::fill_unchecked(_Unchecked(_First), _Unchecked(_Last), _Val); |
743 |
|
} |
744 |
|
|
745 |
|
// TEMPLATE FUNCTION fill_n |
746 |
|
template<class _OutIt, |
747 |
|
class _Diff, |
748 |
|
class _Ty> inline |
749 |
|
void fill_n_unchecked(_OutIt _First, _Diff _Count, const _Ty% _Val) |
750 |
|
{ // copy _Val _Count times through [_First, ...) |
751 |
|
for (; 0 < _Count; --_Count, ++_First) |
752 |
|
*_First = _Val; |
753 |
|
} |
754 |
|
|
755 |
|
#ifdef _M_CEE_SAFE |
756 |
|
#else /* _M_CEE_SAFE */ |
757 |
|
#ifndef _Out_opt_capcount_ |
758 |
|
#define _Out_opt_capcount_ __out_ecount_full_opt |
759 |
|
#endif /* _Out_opt_capcount_ */ |
760 |
|
|
761 |
|
#ifndef _In_opt |
762 |
|
#define _In_opt __in_opt |
763 |
|
#endif /* _In_opt */ |
764 |
|
|
765 |
|
inline void fill_n_unchecked( |
766 |
|
_Out_opt_capcount_(_Count) char *_First, |
767 |
|
size_t _Count, |
768 |
|
int _Val) |
769 |
|
{ // copy char _Val _Count times through [_First, ...) |
770 |
|
std::memset(_First, _Val, _Count); |
771 |
|
} |
772 |
|
|
773 |
|
inline void fill_n_unchecked( |
774 |
|
_Out_opt_capcount_(_Count) signed char *_First, |
775 |
|
size_t _Count, |
776 |
|
int _Val) |
777 |
|
{ // copy signed char _Val _Count times through [_First, ...) |
778 |
|
std::memset(_First, _Val, _Count); |
779 |
|
} |
780 |
|
|
781 |
|
inline void fill_n_unchecked( |
782 |
|
_Out_opt_capcount_(_Count) unsigned char *_First, |
783 |
|
size_t _Count, |
784 |
|
int _Val) |
785 |
|
{ // copy unsigned char _Val _Count times through [_First, ...) |
786 |
|
std::memset(_First, _Val, _Count); |
787 |
|
} |
788 |
|
#endif /* _M_CEE_SAFE */ |
789 |
|
|
790 |
|
template<class _OutIt, |
791 |
|
class _Diff, |
792 |
|
class _Ty> inline |
793 |
|
void fill_n(_OutIt _First, _Diff _Count, const _Ty% _Val) |
794 |
|
{ // copy _Val _Count times through [_First, ...) |
795 |
|
#if _HAS_ITERATOR_DEBUGGING |
796 |
|
if (0 < _Count) |
797 |
|
_STLCLRDB_POINTER(_First); |
798 |
|
#endif /* _HAS_ITERATOR_DEBUGGING */ |
799 |
|
|
800 |
|
cliext::fill_n_unchecked(_Unchecked(_First), _Count, _Val); |
801 |
|
} |
802 |
|
|
803 |
|
// TEMPLATE FUNCTION lexicographical_compare |
804 |
|
template<class _InIt1, |
805 |
|
class _InIt2> inline |
806 |
|
bool lexicographical_compare_unchecked(_InIt1 _First1, _InIt1 _Last1, |
807 |
|
_InIt2 _First2, _InIt2 _Last2) |
808 |
|
{ // order [_First1, _Last1) vs. [First2, Last2) |
809 |
|
for (; _First1 != _Last1 && _First2 != _Last2; ++_First1, ++_First2) |
810 |
|
if (_STLCLRDB_LT(*_First1, *_First2)) |
811 |
|
return (true); |
812 |
|
else if (*_First2 < *_First1) |
813 |
|
return (false); |
814 |
|
return (_First1 == _Last1 && _First2 != _Last2); |
815 |
|
} |
816 |
|
|
817 |
|
#ifdef _M_CEE_SAFE |
818 |
|
#else /* _M_CEE_SAFE */ |
819 |
|
inline bool lexicographical_compare_unchecked( |
820 |
|
const unsigned char *_First1, const unsigned char *_Last1, |
821 |
|
const unsigned char *_First2, const unsigned char *_Last2) |
822 |
|
{ // order [_First1, _Last1) vs. [First2, Last2), for unsigned char |
823 |
|
std::ptrdiff_t _Num1 = _Last1 - _First1; |
824 |
|
std::ptrdiff_t _Num2 = _Last2 - _First2; |
825 |
|
int _Ans = std::memcmp(_First1, _First2, _Num1 < _Num2 ? _Num1 : _Num2); |
826 |
|
return (_Ans < 0 || _Ans == 0 && _Num1 < _Num2); |
827 |
|
} |
828 |
|
|
829 |
|
#if CHAR_MAX == UCHAR_MAX |
830 |
|
inline bool lexicographical_compare_unchecked( |
831 |
|
const char *_First1, const char *_Last1, |
832 |
|
const char *_First2, const char *_Last2) |
833 |
|
{ // order [_First1, _Last1) vs. [First2, Last2), for nonnegative char |
834 |
|
std::ptrdiff_t _Num1 = _Last1 - _First1; |
835 |
|
std::ptrdiff_t _Num2 = _Last2 - _First2; |
836 |
|
int _Ans = std::memcmp(_First1, _First2, _Num1 < _Num2 ? _Num1 : _Num2); |
837 |
|
return (_Ans < 0 || _Ans == 0 && _Num1 < _Num2); |
838 |
|
} |
839 |
|
#endif /* CHAR_MAX == UCHAR_MAX */ |
840 |
|
#endif /* _M_CEE_SAFE */ |
841 |
|
|
842 |
|
template<class _InIt1, |
843 |
|
class _InIt2> inline |
844 |
|
bool lexicographical_compare(_InIt1 _First1, _InIt1 _Last1, |
845 |
|
_InIt2 _First2, _InIt2 _Last2) |
846 |
|
{ // order [_First1, _Last1) vs. [First2, Last2) |
847 |
|
_STLCLRDB_RANGE(_First1, _Last1); |
848 |
|
_STLCLRDB_RANGE(_First2, _Last2); |
849 |
|
return (cliext::lexicographical_compare_unchecked( |
850 |
|
_Unchecked(_First1), _Unchecked(_Last1), |
851 |
|
_Unchecked(_First2), _Unchecked(_Last2))); |
852 |
|
} |
853 |
|
|
854 |
|
// TEMPLATE FUNCTION lexicographical_compare WITH PRED |
855 |
|
template<class _InIt1, |
856 |
|
class _InIt2, |
857 |
|
class _Pr> inline |
858 |
|
bool lexicographical_compare_unchecked(_InIt1 _First1, _InIt1 _Last1, |
859 |
|
_InIt2 _First2, _InIt2 _Last2, _Pr _Pred) |
860 |
|
{ // order [_First1, _Last1) vs. [First2, Last2) using _Pred |
861 |
|
for (; _First1 != _Last1 && _First2 != _Last2; ++_First1, ++_First2) |
862 |
|
if (_STLCLRDB_LT_PRED(_Pred, *_First1, *_First2)) |
863 |
|
return (true); |
864 |
|
else if (_Pred(*_First2, *_First1)) |
865 |
|
return (false); |
866 |
|
return (_First1 == _Last1 && _First2 != _Last2); |
867 |
|
} |
868 |
|
|
869 |
|
template<class _InIt1, |
870 |
|
class _InIt2, |
871 |
|
class _Pr> inline |
872 |
|
bool lexicographical_compare(_InIt1 _First1, _InIt1 _Last1, |
873 |
|
_InIt2 _First2, _InIt2 _Last2, _Pr _Pred) |
874 |
|
{ // order [_First1, _Last1) vs. [First2, Last2) using _Pred |
875 |
|
_STLCLRDB_RANGE(_First1, _Last1); |
876 |
|
_STLCLRDB_RANGE(_First2, _Last2); |
877 |
|
_STLCLRDB_POINTER(_Pred); |
878 |
|
return (cliext::lexicographical_compare_unchecked( |
879 |
|
_Unchecked(_First1), _Unchecked(_Last1), |
880 |
|
_Unchecked(_First2), _Unchecked(_Last2), _Pred)); |
881 |
|
} |
882 |
|
|
883 |
|
// TEMPLATE FUNCTION max |
884 |
|
template<class _Ty> inline |
885 |
|
const _Ty (max)(const _Ty% _Left, const _Ty% _Right) |
886 |
|
{ // return larger of _Left and _Right |
887 |
|
return (_STLCLRDB_LT(_Left, _Right) ? _Right : _Left); |
888 |
|
} |
889 |
|
|
890 |
|
// TEMPLATE FUNCTION max WITH PRED |
891 |
|
template<class _Ty, |
892 |
|
class _Pr> inline |
893 |
|
const _Ty (max)(const _Ty% _Left, const _Ty% _Right, _Pr _Pred) |
894 |
|
{ // return larger of _Left and _Right using _Pred |
895 |
|
return (_STLCLRDB_LT_PRED(_Pred, _Left, _Right) ? _Right : _Left); |
896 |
|
} |
897 |
|
|
898 |
|
// TEMPLATE FUNCTION min |
899 |
|
template<class _Ty> inline |
900 |
|
const _Ty (min)(const _Ty% _Left, const _Ty% _Right) |
901 |
|
{ // return smaller of _Left and _Right |
902 |
|
return (_STLCLRDB_LT(_Right, _Left) ? _Right : _Left); |
903 |
|
} |
904 |
|
|
905 |
|
// TEMPLATE FUNCTION min WITH PRED |
906 |
|
template<class _Ty, |
907 |
|
class _Pr> inline |
908 |
|
const _Ty (min)(const _Ty% _Left, const _Ty% _Right, _Pr _Pred) |
909 |
|
{ // return smaller of _Left and _Right using _Pred |
910 |
|
return (_STLCLRDB_LT_PRED(_Pred, _Right, _Left) ? _Right : _Left); |
911 |
|
} |
912 |
|
} // namespace cliext |
913 |
|
#endif /* _CLI_MEMORY_ */ |
914 |
|
|
915 |
|
/* |
916 |
|
* Copyright (c) 2004-2007 by Dinkumware, Ltd. ALL RIGHTS RESERVED. |
917 |
|
* Consult your license regarding permissions and restrictions. |
918 |
|
V5.03:0009 */ |
919 |
|
|
|
|
|