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
Lines 366 ... 375 are skipped.
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