docs/ikteam: Delete most files.
[haiku.git] / headers / cpp / stl_algobase.h
blob15e535f483d26385b1f6e133f100a12900989791
1 /*
3 * Copyright (c) 1994
4 * Hewlett-Packard Company
6 * Permission to use, copy, modify, distribute and sell this software
7 * and its documentation for any purpose is hereby granted without fee,
8 * provided that the above copyright notice appear in all copies and
9 * that both that copyright notice and this permission notice appear
10 * in supporting documentation. Hewlett-Packard Company makes no
11 * representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
15 * Copyright (c) 1996-1998
16 * Silicon Graphics Computer Systems, Inc.
18 * Permission to use, copy, modify, distribute and sell this software
19 * and its documentation for any purpose is hereby granted without fee,
20 * provided that the above copyright notice appear in all copies and
21 * that both that copyright notice and this permission notice appear
22 * in supporting documentation. Silicon Graphics makes no
23 * representations about the suitability of this software for any
24 * purpose. It is provided "as is" without express or implied warranty.
27 /* NOTE: This is an internal header file, included by other STL headers.
28 * You should not attempt to use it directly.
32 #ifndef __SGI_STL_INTERNAL_ALGOBASE_H
33 #define __SGI_STL_INTERNAL_ALGOBASE_H
35 #ifndef __STL_CONFIG_H
36 #include <stl_config.h>
37 #endif
38 #ifndef __SGI_STL_INTERNAL_RELOPS
39 #include <stl_relops.h>
40 #endif
41 #ifndef __SGI_STL_INTERNAL_PAIR_H
42 #include <stl_pair.h>
43 #endif
44 #ifndef __TYPE_TRAITS_H_
45 #include <type_traits.h>
46 #endif
48 #include <string.h>
49 #include <limits.h>
50 #include <stdlib.h>
51 #include <stddef.h>
52 #include <new.h>
53 #include <iostream.h>
55 #ifndef __SGI_STL_INTERNAL_ITERATOR_H
56 #include <stl_iterator.h>
57 #endif
59 __STL_BEGIN_NAMESPACE
61 // swap and iter_swap
63 template <class _ForwardIter1, class _ForwardIter2, class _Tp>
64 inline void __iter_swap(_ForwardIter1 __a, _ForwardIter2 __b, _Tp*) {
65 _Tp __tmp = *__a;
66 *__a = *__b;
67 *__b = __tmp;
70 template <class _ForwardIter1, class _ForwardIter2>
71 inline void iter_swap(_ForwardIter1 __a, _ForwardIter2 __b) {
72 __iter_swap(__a, __b, __VALUE_TYPE(__a));
75 template <class _Tp>
76 inline void swap(_Tp& __a, _Tp& __b) {
77 _Tp __tmp = __a;
78 __a = __b;
79 __b = __tmp;
82 //--------------------------------------------------
83 // min and max
85 #ifndef __BORLANDC__
87 #undef min
88 #undef max
90 template <class _Tp>
91 inline const _Tp& min(const _Tp& __a, const _Tp& __b) {
92 return __b < __a ? __b : __a;
95 template <class _Tp>
96 inline const _Tp& max(const _Tp& __a, const _Tp& __b) {
97 return __a < __b ? __b : __a;
100 #endif /* __BORLANDC__ */
102 template <class _Tp, class _Compare>
103 inline const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) {
104 return __comp(__b, __a) ? __b : __a;
107 template <class _Tp, class _Compare>
108 inline const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) {
109 return __comp(__a, __b) ? __b : __a;
112 //--------------------------------------------------
113 // copy
115 // All of these auxiliary functions serve two purposes. (1) Replace
116 // calls to copy with memmove whenever possible. (Memmove, not memcpy,
117 // because the input and output ranges are permitted to overlap.)
118 // (2) If we're using random access iterators, then write the loop as
119 // a for loop with an explicit count. The auxiliary class __copy_dispatch
120 // is a workaround for compilers that don't support partial ordering of
121 // function templates.
123 template <class _InputIter, class _OutputIter, class _Distance>
124 inline _OutputIter __copy(_InputIter __first, _InputIter __last,
125 _OutputIter __result,
126 input_iterator_tag, _Distance*)
128 for ( ; __first != __last; ++__result, ++__first)
129 *__result = *__first;
130 return __result;
133 template <class _RandomAccessIter, class _OutputIter, class _Distance>
134 inline _OutputIter
135 __copy(_RandomAccessIter __first, _RandomAccessIter __last,
136 _OutputIter __result, random_access_iterator_tag, _Distance*)
138 for (_Distance __n = __last - __first; __n > 0; --__n) {
139 *__result = *__first;
140 ++__first;
141 ++__result;
143 return __result;
146 template <class _Tp>
147 inline _Tp*
148 __copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result) {
149 memmove(__result, __first, sizeof(_Tp) * (__last - __first));
150 return __result + (__last - __first);
153 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
155 template <class _InputIter, class _OutputIter, class _BoolType>
156 struct __copy_dispatch {
157 static _OutputIter copy(_InputIter __first, _InputIter __last,
158 _OutputIter __result) {
159 typedef typename iterator_traits<_InputIter>::iterator_category _Category;
160 typedef typename iterator_traits<_InputIter>::difference_type _Distance;
161 return __copy(__first, __last, __result, _Category(), (_Distance*) 0);
165 template <class _Tp>
166 struct __copy_dispatch<_Tp*, _Tp*, __true_type>
168 static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) {
169 return __copy_trivial(__first, __last, __result);
173 template <class _Tp>
174 struct __copy_dispatch<const _Tp*, _Tp*, __true_type>
176 static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) {
177 return __copy_trivial(__first, __last, __result);
181 template <class _InputIter, class _OutputIter>
182 inline _OutputIter copy(_InputIter __first, _InputIter __last,
183 _OutputIter __result) {
184 typedef typename iterator_traits<_InputIter>::value_type _Tp;
185 typedef typename __type_traits<_Tp>::has_trivial_assignment_operator
186 _Trivial;
187 return __copy_dispatch<_InputIter, _OutputIter, _Trivial>
188 ::copy(__first, __last, __result);
191 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
193 template <class _InputIter, class _OutputIter>
194 inline _OutputIter copy(_InputIter __first, _InputIter __last,
195 _OutputIter __result)
197 return __copy(__first, __last, __result,
198 __ITERATOR_CATEGORY(__first),
199 __DISTANCE_TYPE(__first));
202 inline char* copy(const char* __first, const char* __last, char* __result) {
203 memmove(__result, __first, __last - __first);
204 return __result + (__last - __first);
207 inline wchar_t* copy(const wchar_t* __first, const wchar_t* __last,
208 wchar_t* __result) {
209 memmove(__result, __first, sizeof(wchar_t) * (__last - __first));
210 return __result + (__last - __first);
213 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
215 //--------------------------------------------------
216 // copy_backward
218 template <class _BidirectionalIter1, class _BidirectionalIter2,
219 class _Distance>
220 inline _BidirectionalIter2 __copy_backward(_BidirectionalIter1 __first,
221 _BidirectionalIter1 __last,
222 _BidirectionalIter2 __result,
223 bidirectional_iterator_tag,
224 _Distance*)
226 while (__first != __last)
227 *--__result = *--__last;
228 return __result;
231 template <class _RandomAccessIter, class _BidirectionalIter, class _Distance>
232 inline _BidirectionalIter __copy_backward(_RandomAccessIter __first,
233 _RandomAccessIter __last,
234 _BidirectionalIter __result,
235 random_access_iterator_tag,
236 _Distance*)
238 for (_Distance __n = __last - __first; __n > 0; --__n)
239 *--__result = *--__last;
240 return __result;
243 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
245 // This dispatch class is a workaround for compilers that do not
246 // have partial ordering of function templates. All we're doing is
247 // creating a specialization so that we can turn a call to copy_backward
248 // into a memmove whenever possible.
250 template <class _BidirectionalIter1, class _BidirectionalIter2,
251 class _BoolType>
252 struct __copy_backward_dispatch
254 typedef typename iterator_traits<_BidirectionalIter1>::iterator_category
255 _Cat;
256 typedef typename iterator_traits<_BidirectionalIter1>::difference_type
257 _Distance;
259 static _BidirectionalIter2 copy(_BidirectionalIter1 __first,
260 _BidirectionalIter1 __last,
261 _BidirectionalIter2 __result) {
262 return __copy_backward(__first, __last, __result, _Cat(), (_Distance*) 0);
266 template <class _Tp>
267 struct __copy_backward_dispatch<_Tp*, _Tp*, __true_type>
269 static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) {
270 const ptrdiff_t _Num = __last - __first;
271 memmove(__result - _Num, __first, sizeof(_Tp) * _Num);
272 return __result - _Num;
276 template <class _Tp>
277 struct __copy_backward_dispatch<const _Tp*, _Tp*, __true_type>
279 static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) {
280 return __copy_backward_dispatch<_Tp*, _Tp*, __true_type>
281 ::copy(__first, __last, __result);
285 template <class _BI1, class _BI2>
286 inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) {
287 typedef typename __type_traits<typename iterator_traits<_BI2>::value_type>
288 ::has_trivial_assignment_operator
289 _Trivial;
290 return __copy_backward_dispatch<_BI1, _BI2, _Trivial>
291 ::copy(__first, __last, __result);
294 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
296 template <class _BI1, class _BI2>
297 inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) {
298 return __copy_backward(__first, __last, __result,
299 __ITERATOR_CATEGORY(__first),
300 __DISTANCE_TYPE(__first));
303 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
305 //--------------------------------------------------
306 // copy_n (not part of the C++ standard)
308 template <class _InputIter, class _Size, class _OutputIter>
309 pair<_InputIter, _OutputIter> __copy_n(_InputIter __first, _Size __count,
310 _OutputIter __result,
311 input_iterator_tag) {
312 for ( ; __count > 0; --__count) {
313 *__result = *__first;
314 ++__first;
315 ++__result;
317 return pair<_InputIter, _OutputIter>(__first, __result);
320 template <class _RAIter, class _Size, class _OutputIter>
321 inline pair<_RAIter, _OutputIter>
322 __copy_n(_RAIter __first, _Size __count,
323 _OutputIter __result,
324 random_access_iterator_tag) {
325 _RAIter __last = __first + __count;
326 return pair<_RAIter, _OutputIter>(__last, copy(__first, __last, __result));
329 template <class _InputIter, class _Size, class _OutputIter>
330 inline pair<_InputIter, _OutputIter>
331 __copy_n(_InputIter __first, _Size __count, _OutputIter __result) {
332 return __copy_n(__first, __count, __result,
333 __ITERATOR_CATEGORY(__first));
336 template <class _InputIter, class _Size, class _OutputIter>
337 inline pair<_InputIter, _OutputIter>
338 copy_n(_InputIter __first, _Size __count, _OutputIter __result) {
339 return __copy_n(__first, __count, __result);
342 //--------------------------------------------------
343 // fill and fill_n
346 template <class _ForwardIter, class _Tp>
347 void fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) {
348 for ( ; __first != __last; ++__first)
349 *__first = __value;
352 template <class _OutputIter, class _Size, class _Tp>
353 _OutputIter fill_n(_OutputIter __first, _Size __n, const _Tp& __value) {
354 for ( ; __n > 0; --__n, ++__first)
355 *__first = __value;
356 return __first;
359 //--------------------------------------------------
360 // equal and mismatch
362 template <class _InputIter1, class _InputIter2>
363 pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1,
364 _InputIter1 __last1,
365 _InputIter2 __first2) {
366 while (__first1 != __last1 && *__first1 == *__first2) {
367 ++__first1;
368 ++__first2;
370 return pair<_InputIter1, _InputIter2>(__first1, __first2);
373 template <class _InputIter1, class _InputIter2, class _BinaryPredicate>
374 pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1,
375 _InputIter1 __last1,
376 _InputIter2 __first2,
377 _BinaryPredicate __binary_pred) {
378 while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) {
379 ++__first1;
380 ++__first2;
382 return pair<_InputIter1, _InputIter2>(__first1, __first2);
385 template <class _InputIter1, class _InputIter2>
386 inline bool equal(_InputIter1 __first1, _InputIter1 __last1,
387 _InputIter2 __first2) {
388 for ( ; __first1 != __last1; ++__first1, ++__first2)
389 if (*__first1 != *__first2)
390 return false;
391 return true;
394 template <class _InputIter1, class _InputIter2, class _BinaryPredicate>
395 inline bool equal(_InputIter1 __first1, _InputIter1 __last1,
396 _InputIter2 __first2, _BinaryPredicate __binary_pred) {
397 for ( ; __first1 != __last1; ++__first1, ++__first2)
398 if (!__binary_pred(*__first1, *__first2))
399 return false;
400 return true;
403 //--------------------------------------------------
404 // lexicographical_compare and lexicographical_compare_3way.
405 // (the latter is not part of the C++ standard.)
407 template <class _InputIter1, class _InputIter2>
408 bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
409 _InputIter2 __first2, _InputIter2 __last2) {
410 for ( ; __first1 != __last1 && __first2 != __last2
411 ; ++__first1, ++__first2) {
412 if (*__first1 < *__first2)
413 return true;
414 if (*__first2 < *__first1)
415 return false;
417 return __first1 == __last1 && __first2 != __last2;
420 template <class _InputIter1, class _InputIter2, class _Compare>
421 bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
422 _InputIter2 __first2, _InputIter2 __last2,
423 _Compare __comp) {
424 for ( ; __first1 != __last1 && __first2 != __last2
425 ; ++__first1, ++__first2) {
426 if (__comp(*__first1, *__first2))
427 return true;
428 if (__comp(*__first2, *__first1))
429 return false;
431 return __first1 == __last1 && __first2 != __last2;
434 inline bool
435 lexicographical_compare(const unsigned char* __first1,
436 const unsigned char* __last1,
437 const unsigned char* __first2,
438 const unsigned char* __last2)
440 const size_t __len1 = __last1 - __first1;
441 const size_t __len2 = __last2 - __first2;
442 const int __result = memcmp(__first1, __first2, min(__len1, __len2));
443 return __result != 0 ? __result < 0 : __len1 < __len2;
446 inline bool lexicographical_compare(const char* __first1, const char* __last1,
447 const char* __first2, const char* __last2)
449 #if CHAR_MAX == SCHAR_MAX
450 return lexicographical_compare((const signed char*) __first1,
451 (const signed char*) __last1,
452 (const signed char*) __first2,
453 (const signed char*) __last2);
454 #else /* CHAR_MAX == SCHAR_MAX */
455 return lexicographical_compare((const unsigned char*) __first1,
456 (const unsigned char*) __last1,
457 (const unsigned char*) __first2,
458 (const unsigned char*) __last2);
459 #endif /* CHAR_MAX == SCHAR_MAX */
462 template <class _InputIter1, class _InputIter2>
463 int __lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1,
464 _InputIter2 __first2, _InputIter2 __last2)
466 while (__first1 != __last1 && __first2 != __last2) {
467 if (*__first1 < *__first2)
468 return -1;
469 if (*__first2 < *__first1)
470 return 1;
471 ++__first1;
472 ++__first2;
474 if (__first2 == __last2) {
475 return !(__first1 == __last1);
477 else {
478 return -1;
482 inline int
483 __lexicographical_compare_3way(const unsigned char* __first1,
484 const unsigned char* __last1,
485 const unsigned char* __first2,
486 const unsigned char* __last2)
488 const ptrdiff_t __len1 = __last1 - __first1;
489 const ptrdiff_t __len2 = __last2 - __first2;
490 const int __result = memcmp(__first1, __first2, min(__len1, __len2));
491 return __result != 0 ? __result
492 : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1));
495 inline int
496 __lexicographical_compare_3way(const char* __first1, const char* __last1,
497 const char* __first2, const char* __last2)
499 #if CHAR_MAX == SCHAR_MAX
500 return __lexicographical_compare_3way(
501 (const signed char*) __first1,
502 (const signed char*) __last1,
503 (const signed char*) __first2,
504 (const signed char*) __last2);
505 #else
506 return __lexicographical_compare_3way((const unsigned char*) __first1,
507 (const unsigned char*) __last1,
508 (const unsigned char*) __first2,
509 (const unsigned char*) __last2);
510 #endif
513 template <class _InputIter1, class _InputIter2>
514 int lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1,
515 _InputIter2 __first2, _InputIter2 __last2)
517 return __lexicographical_compare_3way(__first1, __last1, __first2, __last2);
520 __STL_END_NAMESPACE
522 #endif /* __SGI_STL_INTERNAL_ALGOBASE_H */
524 // Local Variables:
525 // mode:C++
526 // End: