Nugget
algorithm.h
1 // Copyright (c) Electronic Arts Inc. All rights reserved.
4 
6 // This file implements some of the primary algorithms from the C++ STL
7 // algorithm library. These versions are just like that STL versions and so
8 // are redundant. They are provided solely for the purpose of projects that
9 // either cannot use standard C++ STL or want algorithms that have guaranteed
10 // identical behaviour across platforms.
12 
13 
15 // Definitions
16 //
17 // You will notice that we are very particular about the templated typenames
18 // we use here. You will notice that we follow the C++ standard closely in
19 // these respects. Each of these typenames have a specific meaning;
20 // this is why we don't just label templated arguments with just letters
21 // such as T, U, V, A, B. Here we provide a quick reference for the typenames
22 // we use. See the C++ standard, section 25-8 for more details.
23 // --------------------------------------------------------------
24 // typename Meaning
25 // --------------------------------------------------------------
26 // T The value type.
27 // Compare A function which takes two arguments and returns the lesser of the two.
28 // Predicate A function which takes one argument returns true if the argument meets some criteria.
29 // BinaryPredicate A function which takes two arguments and returns true if some criteria is met (e.g. they are equal).
30 // StrickWeakOrdering A BinaryPredicate that compares two objects, returning true if the first precedes the second. Like Compare but has additional requirements. Used for sorting routines.
31 // Function A function which takes one argument and applies some operation to the target.
32 // Size A count or size.
33 // Generator A function which takes no arguments and returns a value (which will usually be assigned to an object).
34 // UnaryOperation A function which takes one argument and returns a value (which will usually be assigned to second object).
35 // BinaryOperation A function which takes two arguments and returns a value (which will usually be assigned to a third object).
36 // InputIterator An input iterator (iterator you read from) which allows reading each element only once and only in a forward direction.
37 // ForwardIterator An input iterator which is like InputIterator except it can be reset back to the beginning.
38 // BidirectionalIterator An input iterator which is like ForwardIterator except it can be read in a backward direction as well.
39 // RandomAccessIterator An input iterator which can be addressed like an array. It is a superset of all other input iterators.
40 // OutputIterator An output iterator (iterator you write to) which allows writing each element only once in only in a forward direction.
41 //
42 // Note that with iterators that a function which takes an InputIterator will
43 // also work with a ForwardIterator, BidirectionalIterator, or RandomAccessIterator.
44 // The given iterator type is merely the -minimum- supported functionality the
45 // iterator must support.
47 
48 
50 // Optimizations
51 //
52 // There are a number of opportunities for optimizations that we take here
53 // in this library. The most obvious kinds are those that substitute memcpy
54 // in the place of a conventional loop for data types with which this is
55 // possible. The algorithms here are optimized to a higher level than currently
56 // available C++ STL algorithms from vendors such as Microsoft. This is especially
57 // so for game programming on console devices, as we do things such as reduce
58 // branching relative to other STL algorithm implementations. However, the
59 // proper implementation of these algorithm optimizations is a fairly tricky
60 // thing.
61 //
62 // The various things we look to take advantage of in order to implement
63 // optimizations include:
64 // - Taking advantage of random access iterators.
65 // - Taking advantage of POD (plain old data) data types.
66 // - Taking advantage of type_traits in general.
67 // - Reducing branching and taking advantage of likely branch predictions.
68 // - Taking advantage of issues related to pointer and reference aliasing.
69 // - Improving cache coherency during memory accesses.
70 // - Making code more likely to be inlinable by the compiler.
71 //
73 
74 
76 // Supported Algorithms
77 //
78 // Algorithms that we implement are listed here. Note that these items are not
79 // all within this header file, as we split up the header files in order to
80 // improve compilation performance. Items marked with '+' are items that are
81 // extensions which don't exist in the C++ standard.
82 //
83 // -------------------------------------------------------------------------------
84 // Algorithm Notes
85 // -------------------------------------------------------------------------------
86 // adjacent_find
87 // adjacent_find<Compare>
88 // all_of C++11
89 // any_of C++11
90 // none_of C++11
91 // binary_search
92 // binary_search<Compare>
93 // +binary_search_i
94 // +binary_search_i<Compare>
95 // +change_heap Found in heap.h
96 // +change_heap<Compare> Found in heap.h
97 // clamp
98 // copy
99 // copy_if C++11
100 // copy_n C++11
101 // copy_backward
102 // count
103 // count_if
104 // equal
105 // equal<Compare>
106 // equal_range
107 // equal_range<Compare>
108 // fill
109 // fill_n
110 // find
111 // find_end
112 // find_end<Compare>
113 // find_first_of
114 // find_first_of<Compare>
115 // +find_first_not_of
116 // +find_first_not_of<Compare>
117 // +find_last_of
118 // +find_last_of<Compare>
119 // +find_last_not_of
120 // +find_last_not_of<Compare>
121 // find_if
122 // find_if_not
123 // for_each
124 // generate
125 // generate_n
126 // +identical
127 // +identical<Compare>
128 // iter_swap
129 // lexicographical_compare
130 // lexicographical_compare<Compare>
131 // lower_bound
132 // lower_bound<Compare>
133 // make_heap Found in heap.h
134 // make_heap<Compare> Found in heap.h
135 // min
136 // min<Compare>
137 // max
138 // max<Compare>
139 // +min_alt Exists to work around the problem of conflicts with min/max #defines on some systems.
140 // +min_alt<Compare>
141 // +max_alt
142 // +max_alt<Compare>
143 // +median
144 // +median<Compare>
145 // merge Found in sort.h
146 // merge<Compare> Found in sort.h
147 // min_element
148 // min_element<Compare>
149 // max_element
150 // max_element<Compare>
151 // mismatch
152 // mismatch<Compare>
153 // move
154 // move_backward
155 // nth_element Found in sort.h
156 // nth_element<Compare> Found in sort.h
157 // partial_sort Found in sort.h
158 // partial_sort<Compare> Found in sort.h
159 // push_heap Found in heap.h
160 // push_heap<Compare> Found in heap.h
161 // pop_heap Found in heap.h
162 // pop_heap<Compare> Found in heap.h
163 // random_shuffle<Random>
164 // remove
165 // remove_if
166 // remove_copy
167 // remove_copy_if
168 // +remove_heap Found in heap.h
169 // +remove_heap<Compare> Found in heap.h
170 // replace
171 // replace_if
172 // replace_copy
173 // replace_copy_if
174 // reverse_copy
175 // reverse
176 // random_shuffle
177 // rotate
178 // rotate_copy
179 // search
180 // search<Compare>
181 // search_n
182 // set_difference
183 // set_difference<Compare>
184 // set_difference_2
185 // set_difference_2<Compare>
186 // set_decomposition
187 // set_decomposition<Compare>
188 // set_intersection
189 // set_intersection<Compare>
190 // set_symmetric_difference
191 // set_symmetric_difference<Compare>
192 // set_union
193 // set_union<Compare>
194 // sort Found in sort.h
195 // sort<Compare> Found in sort.h
196 // sort_heap Found in heap.h
197 // sort_heap<Compare> Found in heap.h
198 // stable_sort Found in sort.h
199 // stable_sort<Compare> Found in sort.h
200 // swap
201 // swap_ranges
202 // transform
203 // transform<Operation>
204 // unique
205 // unique<Compare>
206 // upper_bound
207 // upper_bound<Compare>
208 // is_permutation
209 // is_permutation<Predicate>
210 // next_permutation
211 // next_permutation<Compare>
212 //
213 // Algorithms from the C++ standard that we don't implement are listed here.
214 // Most of these items are absent because they aren't used very often.
215 // They also happen to be the more complicated than other algorithms.
216 // However, we can implement any of these functions for users that might
217 // need them.
218 // includes
219 // includes<Compare>
220 // inplace_merge
221 // inplace_merge<Compare>
222 // partial_sort_copy
223 // partial_sort_copy<Compare>
224 // paritition
225 // prev_permutation
226 // prev_permutation<Compare>
227 // search_n<Compare>
228 // stable_partition
229 // unique_copy
230 // unique_copy<Compare>
231 //
233 
234 
235 #ifndef EASTL_ALGORITHM_H
236 #define EASTL_ALGORITHM_H
237 
238 
239 #include <EASTL/internal/config.h>
240 #include <EASTL/type_traits.h>
241 #include <EASTL/internal/move_help.h>
242 #include <EASTL/internal/copy_help.h>
243 #include <EASTL/internal/fill_help.h>
244 #include <EASTL/initializer_list.h>
245 #include <EASTL/iterator.h>
246 #include <EASTL/functional.h>
247 #include <EASTL/utility.h>
248 #include <EASTL/internal/generic_iterator.h>
249 #include <EASTL/random.h>
250 
251 EA_DISABLE_ALL_VC_WARNINGS();
252 
253  #if defined(EA_COMPILER_MSVC) && (defined(EA_PROCESSOR_X86) || defined(EA_PROCESSOR_X86_64))
254  #include <intrin.h>
255  #endif
256 
257  #include <stddef.h>
258 
259 EA_RESTORE_ALL_VC_WARNINGS();
260 
261 #if defined(EA_PRAGMA_ONCE_SUPPORTED)
262  #pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result.
263 #endif
264 
265 
266 
268 // min/max workaround
269 //
270 // MSVC++ has #defines for min/max which collide with the min/max algorithm
271 // declarations. The following may still not completely resolve some kinds of
272 // problems with MSVC++ #defines, though it deals with most cases in production
273 // game code.
274 //
275 #if EASTL_NOMINMAX
276  #ifdef min
277  #undef min
278  #endif
279  #ifdef max
280  #undef max
281  #endif
282 #endif
283 
284 
285 
286 
287 namespace eastl
288 {
303  template <typename ForwardIterator>
304  ForwardIterator min_element(ForwardIterator first, ForwardIterator last)
305  {
306  if(first != last)
307  {
308  ForwardIterator currentMin = first;
309 
310  while(++first != last)
311  {
312  if(*first < *currentMin)
313  currentMin = first;
314  }
315  return currentMin;
316  }
317  return first;
318  }
319 
320 
335  template <typename ForwardIterator, typename Compare>
336  ForwardIterator min_element(ForwardIterator first, ForwardIterator last, Compare compare)
337  {
338  if(first != last)
339  {
340  ForwardIterator currentMin = first;
341 
342  while(++first != last)
343  {
344  if(compare(*first, *currentMin))
345  currentMin = first;
346  }
347  return currentMin;
348  }
349  return first;
350  }
351 
352 
367  template <typename ForwardIterator>
368  ForwardIterator max_element(ForwardIterator first, ForwardIterator last)
369  {
370  if(first != last)
371  {
372  ForwardIterator currentMax = first;
373 
374  while(++first != last)
375  {
376  if(*currentMax < *first)
377  currentMax = first;
378  }
379  return currentMax;
380  }
381  return first;
382  }
383 
384 
399  template <typename ForwardIterator, typename Compare>
400  ForwardIterator max_element(ForwardIterator first, ForwardIterator last, Compare compare)
401  {
402  if(first != last)
403  {
404  ForwardIterator currentMax = first;
405 
406  while(++first != last)
407  {
408  if(compare(*currentMax, *first))
409  currentMax = first;
410  }
411  return currentMax;
412  }
413  return first;
414  }
415 
416 
417  #if EASTL_MINMAX_ENABLED
418 
442  template <typename T>
443  inline EA_CONSTEXPR typename eastl::enable_if<eastl::is_scalar<T>::value, T>::type
444  min(T a, T b)
445  {
446  return b < a ? b : a;
447  }
448 
449  template <typename T>
450  inline EA_CONSTEXPR typename eastl::enable_if<!eastl::is_scalar<T>::value, const T&>::type
451  min(const T& a, const T& b)
452  {
453  return b < a ? b : a;
454  }
455 
456  inline EA_CONSTEXPR float min(float a, float b) { return b < a ? b : a; }
457  inline EA_CONSTEXPR double min(double a, double b) { return b < a ? b : a; }
458  inline EA_CONSTEXPR long double min(long double a, long double b) { return b < a ? b : a; }
459 
460  #endif // EASTL_MINMAX_ENABLED
461 
462 
470  template <typename T>
471  inline EA_CONSTEXPR typename eastl::enable_if<eastl::is_scalar<T>::value, T>::type
472  min_alt(T a, T b)
473  {
474  return b < a ? b : a;
475  }
476 
477  template <typename T>
478  inline typename eastl::enable_if<!eastl::is_scalar<T>::value, const T&>::type
479  min_alt(const T& a, const T& b)
480  {
481  return b < a ? b : a;
482  }
483 
484  inline EA_CONSTEXPR float min_alt(float a, float b) { return b < a ? b : a; }
485  inline EA_CONSTEXPR double min_alt(double a, double b) { return b < a ? b : a; }
486  inline EA_CONSTEXPR long double min_alt(long double a, long double b) { return b < a ? b : a; }
487 
488 
489  #if EASTL_MINMAX_ENABLED
490 
515  template <typename T, typename Compare>
516  inline const T&
517  min(const T& a, const T& b, Compare compare)
518  {
519  return compare(b, a) ? b : a;
520  }
521 
522  #endif // EASTL_MINMAX_ENABLED
523 
524 
532  template <typename T, typename Compare>
533  inline const T&
534  min_alt(const T& a, const T& b, Compare compare)
535  {
536  return compare(b, a) ? b : a;
537  }
538 
539 
540  #if EASTL_MINMAX_ENABLED
541 
556  template <typename T>
557  inline EA_CONSTEXPR typename eastl::enable_if<eastl::is_scalar<T>::value, T>::type
558  max(T a, T b)
559  {
560  return a < b ? b : a;
561  }
562 
563  template <typename T>
564  inline EA_CONSTEXPR typename eastl::enable_if<!eastl::is_scalar<T>::value, const T&>::type
565  max(const T& a, const T& b)
566  {
567  return a < b ? b : a;
568  }
569 
570  inline EA_CONSTEXPR float max(float a, float b) { return a < b ? b : a; }
571  inline EA_CONSTEXPR double max(double a, double b) { return a < b ? b : a; }
572  inline EA_CONSTEXPR long double max(long double a, long double b) { return a < b ? b : a; }
573 
574  #endif // EASTL_MINMAX_ENABLED
575 
576 
582  template <typename T>
583  inline EA_CONSTEXPR typename eastl::enable_if<eastl::is_scalar<T>::value, T>::type
584  max_alt(T a, T b)
585  {
586  return a < b ? b : a;
587  }
588 
589  template <typename T>
590  inline EA_CONSTEXPR typename eastl::enable_if<!eastl::is_scalar<T>::value, const T&>::type
591  max_alt(const T& a, const T& b)
592  {
593  return a < b ? b : a;
594  }
595 
596  inline EA_CONSTEXPR float max_alt(float a, float b) { return a < b ? b : a; }
597  inline EA_CONSTEXPR double max_alt(double a, double b) { return a < b ? b : a; }
598  inline EA_CONSTEXPR long double max_alt(long double a, long double b) { return a < b ? b : a; }
599 
600 
601  #if EASTL_MINMAX_ENABLED
610  template <typename T, typename Compare>
611  inline const T&
612  max(const T& a, const T& b, Compare compare)
613  {
614  return compare(a, b) ? b : a;
615  }
616  #endif
617 
618 
624  template <typename T, typename Compare>
625  inline const T&
626  max_alt(const T& a, const T& b, Compare compare)
627  {
628  return compare(a, b) ? b : a;
629  }
630 
631 
634  template <typename T >
636  {
637  return *eastl::min_element(ilist.begin(), ilist.end());
638  }
639 
642  template <typename T, typename Compare>
643  T min(std::initializer_list<T> ilist, Compare compare)
644  {
645  return *eastl::min_element(ilist.begin(), ilist.end(), compare);
646  }
647 
648 
651  template <typename T >
653  {
654  return *eastl::max_element(ilist.begin(), ilist.end());
655  }
656 
659  template <typename T, typename Compare>
660  T max(std::initializer_list<T> ilist, Compare compare)
661  {
662  return *eastl::max_element(ilist.begin(), ilist.end(), compare);
663  }
664 
665 
676  template <typename ForwardIterator, typename Compare>
678  minmax_element(ForwardIterator first, ForwardIterator last, Compare compare)
679  {
681 
682  if(!(first == last) && !(++first == last))
683  {
684  if(compare(*first, *result.first))
685  {
686  result.second = result.first;
687  result.first = first;
688  }
689  else
690  result.second = first;
691 
692  while(++first != last)
693  {
694  ForwardIterator i = first;
695 
696  if(++first == last)
697  {
698  if(compare(*i, *result.first))
699  result.first = i;
700  else if(!compare(*i, *result.second))
701  result.second = i;
702  break;
703  }
704  else
705  {
706  if(compare(*first, *i))
707  {
708  if(compare(*first, *result.first))
709  result.first = first;
710 
711  if(!compare(*i, *result.second))
712  result.second = i;
713  }
714  else
715  {
716  if(compare(*i, *result.first))
717  result.first = i;
718 
719  if(!compare(*first, *result.second))
720  result.second = first;
721  }
722  }
723  }
724  }
725 
726  return result;
727  }
728 
729 
730  template <typename ForwardIterator>
732  minmax_element(ForwardIterator first, ForwardIterator last)
733  {
734  typedef typename eastl::iterator_traits<ForwardIterator>::value_type value_type;
735 
736  return eastl::minmax_element(first, last, eastl::less<value_type>());
737  }
738 
739 
740 
748 
749  // The following optimization is a problem because it changes the return value in a way that would break
750  // users unless they used auto (e.g. auto result = minmax(17, 33); )
751  //
752  // template <typename T>
753  // inline EA_CONSTEXPR typename eastl::enable_if<eastl::is_scalar<T>::value, eastl::pair<T, T> >::type
754  // minmax(T a, T b)
755  // {
756  // return (b < a) ? eastl::make_pair(b, a) : eastl::make_pair(a, b);
757  // }
758  //
759  // template <typename T>
760  // inline typename eastl::enable_if<!eastl::is_scalar<T>::value, eastl::pair<const T&, const T&> >::type
761  // minmax(const T& a, const T& b)
762  // {
763  // return (b < a) ? eastl::make_pair(b, a) : eastl::make_pair(a, b);
764  // }
765 
766  // It turns out that the following conforming definition of minmax generates a warning when used with VC++ up
767  // to at least VS2012. The VS2012 version of minmax is a broken and non-conforming definition, and we don't
768  // want to do that. We could do it for scalars alone, though we'd have to decide if we are going to do that
769  // for all compilers, because it changes the return value from a pair of references to a pair of values.
770  template <typename T>
772  minmax(const T& a, const T& b)
773  {
774  return (b < a) ? eastl::make_pair(b, a) : eastl::make_pair(a, b);
775  }
776 
777 
778  template <typename T, typename Compare>
780  minmax(const T& a, const T& b, Compare compare)
781  {
782  return compare(b, a) ? eastl::make_pair(b, a) : eastl::make_pair(a, b);
783  }
784 
785 
786 
787  template <typename T>
790  {
791  typedef typename std::initializer_list<T>::iterator iterator_type;
792  eastl::pair<iterator_type, iterator_type> iteratorPair = eastl::minmax_element(ilist.begin(), ilist.end());
793  return eastl::make_pair(*iteratorPair.first, *iteratorPair.second);
794  }
795 
796  template <typename T, class Compare>
798  minmax(std::initializer_list<T> ilist, Compare compare)
799  {
800  typedef typename std::initializer_list<T>::iterator iterator_type;
801  eastl::pair<iterator_type, iterator_type> iteratorPair = eastl::minmax_element(ilist.begin(), ilist.end(), compare);
802  return eastl::make_pair(*iteratorPair.first, *iteratorPair.second);
803  }
804 
805  template <typename T>
806  inline T&& median_impl(T&& a, T&& b, T&& c)
807  {
808  if(eastl::less<T>()(a, b))
809  {
810  if(eastl::less<T>()(b, c))
811  return eastl::forward<T>(b);
812  else if(eastl::less<T>()(a, c))
813  return eastl::forward<T>(c);
814  else
815  return eastl::forward<T>(a);
816  }
817  else if(eastl::less<T>()(a, c))
818  return eastl::forward<T>(a);
819  else if(eastl::less<T>()(b, c))
820  return eastl::forward<T>(c);
821  return eastl::forward<T>(b);
822  }
823 
832  template <typename T>
833  inline const T& median(const T& a, const T& b, const T& c)
834  {
835  return median_impl(a, b, c);
836  }
837 
846  template <typename T>
847  inline T&& median(T&& a, T&& b, T&& c)
848  {
849  return eastl::forward<T>(median_impl(eastl::forward<T>(a), eastl::forward<T>(b), eastl::forward<T>(c)));
850  }
851 
852 
853  template <typename T, typename Compare>
854  inline T&& median_impl(T&& a, T&& b, T&& c, Compare compare)
855  {
856  if(compare(a, b))
857  {
858  if(compare(b, c))
859  return eastl::forward<T>(b);
860  else if(compare(a, c))
861  return eastl::forward<T>(c);
862  else
863  return eastl::forward<T>(a);
864  }
865  else if(compare(a, c))
866  return eastl::forward<T>(a);
867  else if(compare(b, c))
868  return eastl::forward<T>(c);
869  return eastl::forward<T>(b);
870  }
871 
872 
881  template <typename T, typename Compare>
882  inline const T& median(const T& a, const T& b, const T& c, Compare compare)
883  {
884  return median_impl<const T&, Compare>(a, b, c, compare);
885  }
886 
895  template <typename T, typename Compare>
896  inline T&& median(T&& a, T&& b, T&& c, Compare compare)
897  {
898  return eastl::forward<T>(median_impl<T&&, Compare>(eastl::forward<T>(a), eastl::forward<T>(b), eastl::forward<T>(c), compare));
899  }
900 
901 
902 
903 
908  template <typename InputIterator, typename Predicate>
909  inline bool all_of(InputIterator first, InputIterator last, Predicate p)
910  {
911  for(; first != last; ++first)
912  {
913  if(!p(*first))
914  return false;
915  }
916  return true;
917  }
918 
919 
924  template <typename InputIterator, typename Predicate>
925  inline bool any_of(InputIterator first, InputIterator last, Predicate p)
926  {
927  for(; first != last; ++first)
928  {
929  if(p(*first))
930  return true;
931  }
932  return false;
933  }
934 
935 
940  template <typename InputIterator, typename Predicate>
941  inline bool none_of(InputIterator first, InputIterator last, Predicate p)
942  {
943  for(; first != last; ++first)
944  {
945  if(p(*first))
946  return false;
947  }
948  return true;
949  }
950 
951 
960  template <typename ForwardIterator>
961  inline ForwardIterator
962  adjacent_find(ForwardIterator first, ForwardIterator last)
963  {
964  if(first != last)
965  {
966  ForwardIterator i = first;
967 
968  for(++i; i != last; ++i)
969  {
970  if(*first == *i)
971  return first;
972  first = i;
973  }
974  }
975  return last;
976  }
977 
978 
979 
988  template <typename ForwardIterator, typename BinaryPredicate>
989  inline ForwardIterator
990  adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate predicate)
991  {
992  if(first != last)
993  {
994  ForwardIterator i = first;
995 
996  for(++i; i != last; ++i)
997  {
998  if(predicate(*first, *i))
999  return first;
1000  first = i;
1001  }
1002  }
1003  return last;
1004  }
1005 
1006 
1024  // See the C++11 Standard, 26.5.1.3, Uniform random number generator requirements.
1025  // Also http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
1026 
1027  template <typename RandomAccessIterator, typename UniformRandomNumberGenerator>
1028  void shuffle(RandomAccessIterator first, RandomAccessIterator last, UniformRandomNumberGenerator&& urng)
1029  {
1030  if(first != last)
1031  {
1032  typedef typename eastl::iterator_traits<RandomAccessIterator>::difference_type difference_type;
1033  typedef typename eastl::make_unsigned<difference_type>::type unsigned_difference_type;
1035  typedef typename uniform_int_distribution::param_type uniform_int_distribution_param_type;
1036 
1038 
1039  for(RandomAccessIterator i = first + 1; i != last; ++i)
1040  iter_swap(i, first + uid(urng, uniform_int_distribution_param_type(0, i - first)));
1041  }
1042  }
1043 
1044 
1063  template <typename RandomAccessIterator, typename RandomNumberGenerator>
1064  inline void random_shuffle(RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator&& rng)
1065  {
1066  typedef typename eastl::iterator_traits<RandomAccessIterator>::difference_type difference_type;
1067 
1068  // We must do 'rand((i - first) + 1)' here and cannot do 'rand(last - first)',
1069  // as it turns out that the latter results in unequal distribution probabilities.
1070  // http://www.cigital.com/papers/download/developer_gambling.php
1071 
1072  for(RandomAccessIterator i = first + 1; i < last; ++i)
1073  iter_swap(i, first + (difference_type)rng((eastl_size_t)((i - first) + 1)));
1074  }
1075 
1076 
1096 
1097 
1098 
1099 
1100 
1101 
1106  template <typename InputIterator, typename Size, typename OutputIterator>
1107  inline OutputIterator
1108  move_n_impl(InputIterator first, Size n, OutputIterator result, EASTL_ITC_NS::input_iterator_tag)
1109  {
1110  for(; n > 0; --n)
1111  *result++ = eastl::move(*first++);
1112  return result;
1113  }
1114 
1115  template <typename RandomAccessIterator, typename Size, typename OutputIterator>
1116  inline OutputIterator
1117  move_n_impl(RandomAccessIterator first, Size n, OutputIterator result, EASTL_ITC_NS::random_access_iterator_tag)
1118  {
1119  return eastl::move(first, first + n, result); // Take advantage of the optimizations present in the move algorithm.
1120  }
1121 
1122 
1123  template <typename InputIterator, typename Size, typename OutputIterator>
1124  inline OutputIterator
1125  move_n(InputIterator first, Size n, OutputIterator result)
1126  {
1127  typedef typename eastl::iterator_traits<InputIterator>::iterator_category IC;
1128  return eastl::move_n_impl(first, n, result, IC());
1129  }
1130 
1131 
1132 
1140  template <typename InputIterator, typename Size, typename OutputIterator>
1141  inline OutputIterator
1142  copy_n_impl(InputIterator first, Size n, OutputIterator result, EASTL_ITC_NS::input_iterator_tag)
1143  {
1144  for(; n > 0; --n)
1145  *result++ = *first++;
1146  return result;
1147  }
1148 
1149  template <typename RandomAccessIterator, typename Size, typename OutputIterator>
1150  inline OutputIterator
1151  copy_n_impl(RandomAccessIterator first, Size n, OutputIterator result, EASTL_ITC_NS::random_access_iterator_tag)
1152  {
1153  return eastl::copy(first, first + n, result); // Take advantage of the optimizations present in the copy algorithm.
1154  }
1155 
1156 
1157  template <typename InputIterator, typename Size, typename OutputIterator>
1158  inline OutputIterator
1159  copy_n(InputIterator first, Size n, OutputIterator result)
1160  {
1161  typedef typename eastl::iterator_traits<InputIterator>::iterator_category IC;
1162  return eastl::copy_n_impl(first, n, result, IC());
1163  }
1164 
1165 
1170  template <typename InputIterator, typename OutputIterator, typename Predicate>
1171  inline OutputIterator
1172  copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate predicate)
1173  {
1174  // This implementation's performance could be improved by taking a more complicated approach like with the copy algorithm.
1175  for(; first != last; ++first)
1176  {
1177  if(predicate(*first))
1178  *result++ = *first;
1179  }
1180 
1181  return result;
1182  }
1183 
1184 
1185 
1186 
1187  // Implementation moving copying both trivial and non-trivial data via a lesser iterator than random-access.
1188  template <typename /*BidirectionalIterator1Category*/, bool /*isMove*/, bool /*canMemmove*/>
1190  {
1191  template <typename BidirectionalIterator1, typename BidirectionalIterator2>
1192  static BidirectionalIterator2 move_or_copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 resultEnd)
1193  {
1194  while(first != last)
1195  *--resultEnd = *--last;
1196  return resultEnd; // resultEnd now points to the beginning of the destination sequence instead of the end.
1197  }
1198  };
1199 
1200  // Specialization for moving non-trivial data via a lesser iterator than random-access.
1201  template <typename BidirectionalIterator1Category>
1202  struct move_and_copy_backward_helper<BidirectionalIterator1Category, true, false>
1203  {
1204  template <typename BidirectionalIterator1, typename BidirectionalIterator2>
1205  static BidirectionalIterator2 move_or_copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 resultEnd)
1206  {
1207  while(first != last)
1208  *--resultEnd = eastl::move(*--last);
1209  return resultEnd; // resultEnd now points to the beginning of the destination sequence instead of the end.
1210  }
1211  };
1212 
1213  // Specialization for moving non-trivial data via a random-access iterator. It's theoretically faster because the compiler can see the count when its a compile-time const.
1214  template<>
1216  {
1217  template<typename BidirectionalIterator1, typename BidirectionalIterator2>
1218  static BidirectionalIterator2 move_or_copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 resultEnd)
1219  {
1220  typedef typename eastl::iterator_traits<BidirectionalIterator1>::difference_type difference_type;
1221 
1222  for(difference_type n = (last - first); n > 0; --n)
1223  *--resultEnd = eastl::move(*--last);
1224  return resultEnd; // resultEnd now points to the beginning of the destination sequence instead of the end.
1225  }
1226  };
1227 
1228  // Specialization for copying non-trivial data via a random-access iterator. It's theoretically faster because the compiler can see the count when its a compile-time const.
1229  // This specialization converts the random access BidirectionalIterator1 last-first to an integral type. There's simple way for us to take advantage of a random access output iterator,
1230  // as the range is specified by the input instead of the output, and distance(first, last) for a non-random-access iterator is potentially slow.
1231  template <>
1232  struct move_and_copy_backward_helper<EASTL_ITC_NS::random_access_iterator_tag, false, false>
1233  {
1234  template <typename BidirectionalIterator1, typename BidirectionalIterator2>
1235  static BidirectionalIterator2 move_or_copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 resultEnd)
1236  {
1237  typedef typename eastl::iterator_traits<BidirectionalIterator1>::difference_type difference_type;
1238 
1239  for(difference_type n = (last - first); n > 0; --n)
1240  *--resultEnd = *--last;
1241  return resultEnd; // resultEnd now points to the beginning of the destination sequence instead of the end.
1242  }
1243  };
1244 
1245  // Specialization for when we can use memmove/memcpy. See the notes above for what conditions allow this.
1246  template <bool isMove>
1247  struct move_and_copy_backward_helper<EASTL_ITC_NS::random_access_iterator_tag, isMove, true>
1248  {
1249  template <typename T>
1250  static T* move_or_copy_backward(const T* first, const T* last, T* resultEnd)
1251  {
1252  return (T*)__builtin_memmove(resultEnd - (last - first), first, (size_t)((uintptr_t)last - (uintptr_t)first));
1253  // We could use memcpy here if there's no range overlap, but memcpy is rarely much faster than memmove.
1254  }
1255  };
1256 
1257  template <bool isMove, typename BidirectionalIterator1, typename BidirectionalIterator2>
1258  inline BidirectionalIterator2 move_and_copy_backward_chooser(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 resultEnd)
1259  {
1260  typedef typename eastl::iterator_traits<BidirectionalIterator1>::iterator_category IIC;
1261  typedef typename eastl::iterator_traits<BidirectionalIterator2>::iterator_category OIC;
1262  typedef typename eastl::iterator_traits<BidirectionalIterator1>::value_type value_type_input;
1263  typedef typename eastl::iterator_traits<BidirectionalIterator2>::value_type value_type_output;
1264 
1265  const bool canBeMemmoved = eastl::is_trivially_copyable<value_type_output>::value &&
1269 
1270  return eastl::move_and_copy_backward_helper<IIC, isMove, canBeMemmoved>::move_or_copy_backward(first, last, resultEnd); // Need to chose based on the input iterator tag and not the output iterator tag, because containers accept input ranges of iterator types different than self.
1271  }
1272 
1273 
1274  // We have a second layer of unwrap_iterator calls because the original iterator might be something like move_iterator<generic_iterator<int*> > (i.e. doubly-wrapped).
1275  template <bool isMove, typename BidirectionalIterator1, typename BidirectionalIterator2>
1276  inline BidirectionalIterator2 move_and_copy_backward_unwrapper(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 resultEnd)
1277  {
1278  return BidirectionalIterator2(eastl::move_and_copy_backward_chooser<isMove>(eastl::unwrap_iterator(first), eastl::unwrap_iterator(last), eastl::unwrap_iterator(resultEnd))); // Have to convert to BidirectionalIterator2 because result.base() could be a T*
1279  }
1280 
1281 
1303  template <typename BidirectionalIterator1, typename BidirectionalIterator2>
1304  inline BidirectionalIterator2 move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 resultEnd)
1305  {
1306  return eastl::move_and_copy_backward_unwrapper<true>(eastl::unwrap_iterator(first), eastl::unwrap_iterator(last), resultEnd);
1307  }
1308 
1309 
1324  template <typename BidirectionalIterator1, typename BidirectionalIterator2>
1325  inline BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 resultEnd)
1326  {
1327  const bool isMove = eastl::is_move_iterator<BidirectionalIterator1>::value; EA_UNUSED(isMove);
1328 
1329  return eastl::move_and_copy_backward_unwrapper<isMove>(eastl::unwrap_iterator(first), eastl::unwrap_iterator(last), resultEnd);
1330  }
1331 
1332 
1345  template <typename InputIterator, typename T>
1346  inline typename eastl::iterator_traits<InputIterator>::difference_type
1347  count(InputIterator first, InputIterator last, const T& value)
1348  {
1349  typename eastl::iterator_traits<InputIterator>::difference_type result = 0;
1350 
1351  for(; first != last; ++first)
1352  {
1353  if(*first == value)
1354  ++result;
1355  }
1356  return result;
1357  }
1358 
1359 
1360  // C++ doesn't define a count with predicate, as it can effectively be synthesized via count_if
1361  // with an appropriate predicate. However, it's often simpler to just have count with a predicate.
1362  template <typename InputIterator, typename T, typename Predicate>
1363  inline typename eastl::iterator_traits<InputIterator>::difference_type
1364  count(InputIterator first, InputIterator last, const T& value, Predicate predicate)
1365  {
1366  typename eastl::iterator_traits<InputIterator>::difference_type result = 0;
1367 
1368  for(; first != last; ++first)
1369  {
1370  if(predicate(*first, value))
1371  ++result;
1372  }
1373  return result;
1374  }
1375 
1376 
1390  template <typename InputIterator, typename Predicate>
1391  inline typename eastl::iterator_traits<InputIterator>::difference_type
1392  count_if(InputIterator first, InputIterator last, Predicate predicate)
1393  {
1394  typename eastl::iterator_traits<InputIterator>::difference_type result = 0;
1395 
1396  for(; first != last; ++first)
1397  {
1398  if(predicate(*first))
1399  ++result;
1400  }
1401  return result;
1402  }
1403 
1404 
1419  template <typename InputIterator, typename T>
1420  inline InputIterator
1421  find(InputIterator first, InputIterator last, const T& value)
1422  {
1423  while((first != last) && !(*first == value)) // Note that we always express value comparisons in terms of < or ==.
1424  ++first;
1425  return first;
1426  }
1427 
1428 
1429  // C++ doesn't define a find with predicate, as it can effectively be synthesized via find_if
1430  // with an appropriate predicate. However, it's often simpler to just have find with a predicate.
1431  template <typename InputIterator, typename T, typename Predicate>
1432  inline InputIterator
1433  find(InputIterator first, InputIterator last, const T& value, Predicate predicate)
1434  {
1435  while((first != last) && !predicate(*first, value))
1436  ++first;
1437  return first;
1438  }
1439 
1440 
1441 
1457  template <typename InputIterator, typename Predicate>
1458  inline InputIterator
1459  find_if(InputIterator first, InputIterator last, Predicate predicate)
1460  {
1461  while((first != last) && !predicate(*first))
1462  ++first;
1463  return first;
1464  }
1465 
1466 
1467 
1473  template <typename InputIterator, typename Predicate>
1474  inline InputIterator
1475  find_if_not(InputIterator first, InputIterator last, Predicate predicate)
1476  {
1477  for(; first != last; ++first)
1478  {
1479  if(!predicate(*first))
1480  return first;
1481  }
1482  return last;
1483  }
1484 
1485 
1486 
1487 
1508  template <typename ForwardIterator1, typename ForwardIterator2>
1509  ForwardIterator1
1510  find_first_of(ForwardIterator1 first1, ForwardIterator1 last1,
1511  ForwardIterator2 first2, ForwardIterator2 last2)
1512  {
1513  for(; first1 != last1; ++first1)
1514  {
1515  for(ForwardIterator2 i = first2; i != last2; ++i)
1516  {
1517  if(*first1 == *i)
1518  return first1;
1519  }
1520  }
1521  return last1;
1522  }
1523 
1524 
1543  template <typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
1544  ForwardIterator1
1545  find_first_of(ForwardIterator1 first1, ForwardIterator1 last1,
1546  ForwardIterator2 first2, ForwardIterator2 last2,
1547  BinaryPredicate predicate)
1548  {
1549  for(; first1 != last1; ++first1)
1550  {
1551  for(ForwardIterator2 i = first2; i != last2; ++i)
1552  {
1553  if(predicate(*first1, *i))
1554  return first1;
1555  }
1556  }
1557  return last1;
1558  }
1559 
1560 
1573  template <class ForwardIterator1, class ForwardIterator2>
1574  ForwardIterator1
1575  find_first_not_of(ForwardIterator1 first1, ForwardIterator1 last1,
1576  ForwardIterator2 first2, ForwardIterator2 last2)
1577  {
1578  for(; first1 != last1; ++first1)
1579  {
1580  if(eastl::find(first2, last2, *first1) == last2)
1581  break;
1582  }
1583 
1584  return first1;
1585  }
1586 
1587 
1588 
1601  template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
1602  inline ForwardIterator1
1603  find_first_not_of(ForwardIterator1 first1, ForwardIterator1 last1,
1604  ForwardIterator2 first2, ForwardIterator2 last2,
1605  BinaryPredicate predicate)
1606  {
1607  typedef typename eastl::iterator_traits<ForwardIterator1>::value_type value_type;
1608 
1609  for(; first1 != last1; ++first1)
1610  {
1611  if(eastl::find_if(first2, last2, eastl::bind1st<BinaryPredicate, value_type>(predicate, *first1)) == last2)
1612  break;
1613  }
1614 
1615  return first1;
1616  }
1617 
1618 
1619  template <class BidirectionalIterator1, class ForwardIterator2>
1620  inline BidirectionalIterator1
1621  find_last_of(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
1622  ForwardIterator2 first2, ForwardIterator2 last2)
1623  {
1624  if((first1 != last1) && (first2 != last2))
1625  {
1626  BidirectionalIterator1 it1(last1);
1627 
1628  while((--it1 != first1) && (eastl::find(first2, last2, *it1) == last2))
1629  ; // Do nothing
1630 
1631  if((it1 != first1) || (eastl::find(first2, last2, *it1) != last2))
1632  return it1;
1633  }
1634 
1635  return last1;
1636  }
1637 
1638 
1639  template <class BidirectionalIterator1, class ForwardIterator2, class BinaryPredicate>
1640  BidirectionalIterator1
1641  find_last_of(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
1642  ForwardIterator2 first2, ForwardIterator2 last2,
1643  BinaryPredicate predicate)
1644  {
1645  typedef typename eastl::iterator_traits<BidirectionalIterator1>::value_type value_type;
1646 
1647  if((first1 != last1) && (first2 != last2))
1648  {
1649  BidirectionalIterator1 it1(last1);
1650 
1651  while((--it1 != first1) && (eastl::find_if(first2, last2, eastl::bind1st<BinaryPredicate, value_type>(predicate, *it1)) == last2))
1652  ; // Do nothing
1653 
1654  if((it1 != first1) || (eastl::find_if(first2, last2, eastl::bind1st<BinaryPredicate, value_type>(predicate, *it1)) != last2))
1655  return it1;
1656  }
1657 
1658  return last1;
1659  }
1660 
1661 
1662  template <class BidirectionalIterator1, class ForwardIterator2>
1663  inline BidirectionalIterator1
1664  find_last_not_of(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
1665  ForwardIterator2 first2, ForwardIterator2 last2)
1666  {
1667  if((first1 != last1) && (first2 != last2))
1668  {
1669  BidirectionalIterator1 it1(last1);
1670 
1671  while((--it1 != first1) && (eastl::find(first2, last2, *it1) != last2))
1672  ; // Do nothing
1673 
1674  if((it1 != first1) || (eastl::find( first2, last2, *it1) == last2))
1675  return it1;
1676  }
1677 
1678  return last1;
1679  }
1680 
1681 
1682  template <class BidirectionalIterator1, class ForwardIterator2, class BinaryPredicate>
1683  inline BidirectionalIterator1
1684  find_last_not_of(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
1685  ForwardIterator2 first2, ForwardIterator2 last2,
1686  BinaryPredicate predicate)
1687  {
1688  typedef typename eastl::iterator_traits<BidirectionalIterator1>::value_type value_type;
1689 
1690  if((first1 != last1) && (first2 != last2))
1691  {
1692  BidirectionalIterator1 it1(last1);
1693 
1694  while((--it1 != first1) && (eastl::find_if(first2, last2, eastl::bind1st<BinaryPredicate, value_type>(predicate, *it1)) != last2))
1695  ; // Do nothing
1696 
1697  if((it1 != first1) || (eastl::find_if(first2, last2, eastl::bind1st<BinaryPredicate, value_type>(predicate, *it1))) != last2)
1698  return it1;
1699  }
1700 
1701  return last1;
1702  }
1703 
1704 
1705 
1706 
1721  template <typename InputIterator, typename Function>
1722  inline Function
1723  for_each(InputIterator first, InputIterator last, Function function)
1724  {
1725  for(; first != last; ++first)
1726  function(*first);
1727  return function;
1728  }
1729 
1746  template <typename InputIterator, typename Size, typename Function>
1747  EA_CPP14_CONSTEXPR inline InputIterator
1748  for_each_n(InputIterator first, Size n, Function function)
1749  {
1750  for (Size i = 0; i < n; ++first, i++)
1751  function(*first);
1752  return first;
1753  }
1754 
1755 
1764  template <typename ForwardIterator, typename Generator>
1765  inline void
1766  generate(ForwardIterator first, ForwardIterator last, Generator generator)
1767  {
1768  for(; first != last; ++first) // We cannot call generate_n(first, last-first, generator)
1769  *first = generator(); // because the 'last-first' might not be supported by the
1770  } // given iterator.
1771 
1772 
1781  template <typename OutputIterator, typename Size, typename Generator>
1782  inline OutputIterator
1783  generate_n(OutputIterator first, Size n, Generator generator)
1784  {
1785  for(; n > 0; --n, ++first)
1786  *first = generator();
1787  return first;
1788  }
1789 
1790 
1807  template <typename InputIterator, typename OutputIterator, typename UnaryOperation>
1808  inline OutputIterator
1809  transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation unaryOperation)
1810  {
1811  for(; first != last; ++first, ++result)
1812  *result = unaryOperation(*first);
1813  return result;
1814  }
1815 
1816 
1833  template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename BinaryOperation>
1834  inline OutputIterator
1835  transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binaryOperation)
1836  {
1837  for(; first1 != last1; ++first1, ++first2, ++result)
1838  *result = binaryOperation(*first1, *first2);
1839  return result;
1840  }
1841 
1842 
1855  template <typename InputIterator1, typename InputIterator2>
1856  EA_CPP14_CONSTEXPR inline bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
1857  {
1858  for(; first1 != last1; ++first1, ++first2)
1859  {
1860  if(!(*first1 == *first2)) // Note that we always express value comparisons in terms of < or ==.
1861  return false;
1862  }
1863  return true;
1864  }
1865 
1866  /* Enable the following if there was shown to be some benefit. A glance and Microsoft VC++ memcmp
1867  shows that it is not optimized in any way, much less one that would benefit us here.
1868 
1869  inline bool equal(const bool* first1, const bool* last1, const bool* first2)
1870  { return (memcmp(first1, first2, (size_t)((uintptr_t)last1 - (uintptr_t)first1)) == 0); }
1871 
1872  inline bool equal(const char* first1, const char* last1, const char* first2)
1873  { return (memcmp(first1, first2, (size_t)((uintptr_t)last1 - (uintptr_t)first1)) == 0); }
1874 
1875  inline bool equal(const unsigned char* first1, const unsigned char* last1, const unsigned char* first2)
1876  { return (memcmp(first1, first2, (size_t)((uintptr_t)last1 - (uintptr_t)first1)) == 0); }
1877 
1878  inline bool equal(const signed char* first1, const signed char* last1, const signed char* first2)
1879  { return (memcmp(first1, first2, (size_t)((uintptr_t)last1 - (uintptr_t)first1)) == 0); }
1880 
1881  #ifndef EA_WCHAR_T_NON_NATIVE
1882  inline bool equal(const wchar_t* first1, const wchar_t* last1, const wchar_t* first2)
1883  { return (memcmp(first1, first2, (size_t)((uintptr_t)last1 - (uintptr_t)first1)) == 0); }
1884  #endif
1885 
1886  inline bool equal(const int16_t* first1, const int16_t* last1, const int16_t* first2)
1887  { return (memcmp(first1, first2, (size_t)((uintptr_t)last1 - (uintptr_t)first1)) == 0); }
1888 
1889  inline bool equal(const uint16_t* first1, const uint16_t* last1, const uint16_t* first2)
1890  { return (memcmp(first1, first2, (size_t)((uintptr_t)last1 - (uintptr_t)first1)) == 0); }
1891 
1892  inline bool equal(const int32_t* first1, const int32_t* last1, const int32_t* first2)
1893  { return (memcmp(first1, first2, (size_t)((uintptr_t)last1 - (uintptr_t)first1)) == 0); }
1894 
1895  inline bool equal(const uint32_t* first1, const uint32_t* last1, const uint32_t* first2)
1896  { return (memcmp(first1, first2, (size_t)((uintptr_t)last1 - (uintptr_t)first1)) == 0); }
1897 
1898  inline bool equal(const int64_t* first1, const int64_t* last1, const int64_t* first2)
1899  { return (memcmp(first1, first2, (size_t)((uintptr_t)last1 - (uintptr_t)first1)) == 0); }
1900 
1901  inline bool equal(const uint64_t* first1, const uint64_t* last1, const uint64_t* first2)
1902  { return (memcmp(first1, first2, (size_t)((uintptr_t)last1 - (uintptr_t)first1)) == 0); }
1903  */
1904 
1905 
1906 
1915  template <typename InputIterator1, typename InputIterator2, typename BinaryPredicate>
1916  inline bool
1917  equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate predicate)
1918  {
1919  for(; first1 != last1; ++first1, ++first2)
1920  {
1921  if(!predicate(*first1, *first2))
1922  return false;
1923  }
1924  return true;
1925  }
1926 
1927 
1928 
1948  template <typename InputIterator1, typename InputIterator2>
1949  bool identical(InputIterator1 first1, InputIterator1 last1,
1950  InputIterator2 first2, InputIterator2 last2)
1951  {
1952  while((first1 != last1) && (first2 != last2) && (*first1 == *first2))
1953  {
1954  ++first1;
1955  ++first2;
1956  }
1957  return (first1 == last1) && (first2 == last2);
1958  }
1959 
1960 
1963  template <typename InputIterator1, typename InputIterator2, typename BinaryPredicate>
1964  bool identical(InputIterator1 first1, InputIterator1 last1,
1965  InputIterator2 first2, InputIterator2 last2, BinaryPredicate predicate)
1966  {
1967  while((first1 != last1) && (first2 != last2) && predicate(*first1, *first2))
1968  {
1969  ++first1;
1970  ++first2;
1971  }
1972  return (first1 == last1) && (first2 == last2);
1973  }
1974 
1975 
1976 
1994  template <typename InputIterator1, typename InputIterator2>
1995  inline bool
1996  lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2)
1997  {
1998  for(; (first1 != last1) && (first2 != last2); ++first1, ++first2)
1999  {
2000  if(*first1 < *first2)
2001  return true;
2002  if(*first2 < *first1)
2003  return false;
2004  }
2005  return (first1 == last1) && (first2 != last2);
2006  }
2007 
2008  inline bool // Specialization for const char*.
2009  lexicographical_compare(const char* first1, const char* last1, const char* first2, const char* last2)
2010  {
2011  const ptrdiff_t n1(last1 - first1), n2(last2 - first2);
2012  const int result = __builtin_memcmp(first1, first2, (size_t)eastl::min_alt(n1, n2));
2013  return result ? (result < 0) : (n1 < n2);
2014  }
2015 
2016  inline bool // Specialization for char*.
2017  lexicographical_compare(char* first1, char* last1, char* first2, char* last2)
2018  {
2019  const ptrdiff_t n1(last1 - first1), n2(last2 - first2);
2020  const int result = __builtin_memcmp(first1, first2, (size_t)eastl::min_alt(n1, n2));
2021  return result ? (result < 0) : (n1 < n2);
2022  }
2023 
2024  inline bool // Specialization for const unsigned char*.
2025  lexicographical_compare(const unsigned char* first1, const unsigned char* last1, const unsigned char* first2, const unsigned char* last2)
2026  {
2027  const ptrdiff_t n1(last1 - first1), n2(last2 - first2);
2028  const int result = __builtin_memcmp(first1, first2, (size_t)eastl::min_alt(n1, n2));
2029  return result ? (result < 0) : (n1 < n2);
2030  }
2031 
2032  inline bool // Specialization for unsigned char*.
2033  lexicographical_compare(unsigned char* first1, unsigned char* last1, unsigned char* first2, unsigned char* last2)
2034  {
2035  const ptrdiff_t n1(last1 - first1), n2(last2 - first2);
2036  const int result = __builtin_memcmp(first1, first2, (size_t)eastl::min_alt(n1, n2));
2037  return result ? (result < 0) : (n1 < n2);
2038  }
2039 
2040  inline bool // Specialization for const signed char*.
2041  lexicographical_compare(const signed char* first1, const signed char* last1, const signed char* first2, const signed char* last2)
2042  {
2043  const ptrdiff_t n1(last1 - first1), n2(last2 - first2);
2044  const int result = __builtin_memcmp(first1, first2, (size_t)eastl::min_alt(n1, n2));
2045  return result ? (result < 0) : (n1 < n2);
2046  }
2047 
2048  inline bool // Specialization for signed char*.
2049  lexicographical_compare(signed char* first1, signed char* last1, signed char* first2, signed char* last2)
2050  {
2051  const ptrdiff_t n1(last1 - first1), n2(last2 - first2);
2052  const int result = __builtin_memcmp(first1, first2, (size_t)eastl::min_alt(n1, n2));
2053  return result ? (result < 0) : (n1 < n2);
2054  }
2055 
2056  #if defined(_MSC_VER) // If using the VC++ compiler (and thus bool is known to be a single byte)...
2057  //Not sure if this is a good idea.
2058  //inline bool // Specialization for const bool*.
2059  //lexicographical_compare(const bool* first1, const bool* last1, const bool* first2, const bool* last2)
2060  //{
2061  // const ptrdiff_t n1(last1 - first1), n2(last2 - first2);
2062  // const int result = memcmp(first1, first2, (size_t)eastl::min_alt(n1, n2));
2063  // return result ? (result < 0) : (n1 < n2);
2064  //}
2065  //
2066  //inline bool // Specialization for bool*.
2067  //lexicographical_compare(bool* first1, bool* last1, bool* first2, bool* last2)
2068  //{
2069  // const ptrdiff_t n1(last1 - first1), n2(last2 - first2);
2070  // const int result = memcmp(first1, first2, (size_t)eastl::min_alt(n1, n2));
2071  // return result ? (result < 0) : (n1 < n2);
2072  //}
2073  #endif
2074 
2075 
2076 
2100  template <typename InputIterator1, typename InputIterator2, typename Compare>
2101  inline bool
2102  lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
2103  InputIterator2 first2, InputIterator2 last2, Compare compare)
2104  {
2105  for(; (first1 != last1) && (first2 != last2); ++first1, ++first2)
2106  {
2107  if(compare(*first1, *first2))
2108  return true;
2109  if(compare(*first2, *first1))
2110  return false;
2111  }
2112  return (first1 == last1) && (first2 != last2);
2113  }
2114 
2115 
2130  template <class InputIterator1, class InputIterator2>
2132  mismatch(InputIterator1 first1, InputIterator1 last1,
2133  InputIterator2 first2) // , InputIterator2 last2)
2134  {
2135  while((first1 != last1) && (*first1 == *first2)) // && (first2 != last2) <- C++ standard mismatch function doesn't check first2/last2.
2136  {
2137  ++first1;
2138  ++first2;
2139  }
2140 
2141  return eastl::pair<InputIterator1, InputIterator2>(first1, first2);
2142  }
2143 
2144 
2159  template <class InputIterator1, class InputIterator2, class BinaryPredicate>
2161  mismatch(InputIterator1 first1, InputIterator1 last1,
2162  InputIterator2 first2, // InputIterator2 last2,
2163  BinaryPredicate predicate)
2164  {
2165  while((first1 != last1) && predicate(*first1, *first2)) // && (first2 != last2) <- C++ standard mismatch function doesn't check first2/last2.
2166  {
2167  ++first1;
2168  ++first2;
2169  }
2170 
2171  return eastl::pair<InputIterator1, InputIterator2>(first1, first2);
2172  }
2173 
2174 
2193  template <typename ForwardIterator, typename T>
2194  ForwardIterator
2195  lower_bound(ForwardIterator first, ForwardIterator last, const T& value)
2196  {
2197  typedef typename eastl::iterator_traits<ForwardIterator>::difference_type DifferenceType;
2198 
2199  DifferenceType d = eastl::distance(first, last); // This will be efficient for a random access iterator such as an array.
2200 
2201  while(d > 0)
2202  {
2203  ForwardIterator i = first;
2204  DifferenceType d2 = d >> 1; // We use '>>1' here instead of '/2' because MSVC++ for some reason generates significantly worse code for '/2'. Go figure.
2205 
2206  eastl::advance(i, d2); // This will be efficient for a random access iterator such as an array.
2207 
2208  if(*i < value)
2209  {
2210  // Disabled because std::lower_bound doesn't specify (23.3.3.3, p3) this can be done: EASTL_VALIDATE_COMPARE(!(value < *i)); // Validate that the compare function is sane.
2211  first = ++i;
2212  d -= d2 + 1;
2213  }
2214  else
2215  d = d2;
2216  }
2217  return first;
2218  }
2219 
2220 
2241  template <typename ForwardIterator, typename T, typename Compare>
2242  ForwardIterator
2243  lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare compare)
2244  {
2245  typedef typename eastl::iterator_traits<ForwardIterator>::difference_type DifferenceType;
2246 
2247  DifferenceType d = eastl::distance(first, last); // This will be efficient for a random access iterator such as an array.
2248 
2249  while(d > 0)
2250  {
2251  ForwardIterator i = first;
2252  DifferenceType d2 = d >> 1; // We use '>>1' here instead of '/2' because MSVC++ for some reason generates significantly worse code for '/2'. Go figure.
2253 
2254  eastl::advance(i, d2); // This will be efficient for a random access iterator such as an array.
2255 
2256  if(compare(*i, value))
2257  {
2258  // Disabled because std::lower_bound doesn't specify (23.3.3.1, p3) this can be done: EASTL_VALIDATE_COMPARE(!compare(value, *i)); // Validate that the compare function is sane.
2259  first = ++i;
2260  d -= d2 + 1;
2261  }
2262  else
2263  d = d2;
2264  }
2265  return first;
2266  }
2267 
2268 
2269 
2284  template <typename ForwardIterator, typename T>
2285  ForwardIterator
2286  upper_bound(ForwardIterator first, ForwardIterator last, const T& value)
2287  {
2288  typedef typename eastl::iterator_traits<ForwardIterator>::difference_type DifferenceType;
2289 
2290  DifferenceType len = eastl::distance(first, last);
2291 
2292  while(len > 0)
2293  {
2294  ForwardIterator i = first;
2295  DifferenceType len2 = len >> 1; // We use '>>1' here instead of '/2' because MSVC++ for some reason generates significantly worse code for '/2'. Go figure.
2296 
2297  eastl::advance(i, len2);
2298 
2299  if(!(value < *i)) // Note that we always express value comparisons in terms of < or ==.
2300  {
2301  first = ++i;
2302  len -= len2 + 1;
2303  }
2304  else
2305  {
2306  // Disabled because std::upper_bound doesn't specify (23.3.3.2, p3) this can be done: EASTL_VALIDATE_COMPARE(!(*i < value)); // Validate that the compare function is sane.
2307  len = len2;
2308  }
2309  }
2310  return first;
2311  }
2312 
2313 
2330  template <typename ForwardIterator, typename T, typename Compare>
2331  ForwardIterator
2332  upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare compare)
2333  {
2334  typedef typename eastl::iterator_traits<ForwardIterator>::difference_type DifferenceType;
2335 
2336  DifferenceType len = eastl::distance(first, last);
2337 
2338  while(len > 0)
2339  {
2340  ForwardIterator i = first;
2341  DifferenceType len2 = len >> 1; // We use '>>1' here instead of '/2' because MSVC++ for some reason generates significantly worse code for '/2'. Go figure.
2342 
2343  eastl::advance(i, len2);
2344 
2345  if(!compare(value, *i))
2346  {
2347  first = ++i;
2348  len -= len2 + 1;
2349  }
2350  else
2351  {
2352  // Disabled because std::upper_bound doesn't specify (23.3.3.2, p3) this can be done: EASTL_VALIDATE_COMPARE(!compare(*i, value)); // Validate that the compare function is sane.
2353  len = len2;
2354  }
2355  }
2356  return first;
2357  }
2358 
2359 
2368  template <typename ForwardIterator, typename T>
2369  pair<ForwardIterator, ForwardIterator>
2370  equal_range(ForwardIterator first, ForwardIterator last, const T& value)
2371  {
2372  typedef pair<ForwardIterator, ForwardIterator> ResultType;
2373  typedef typename eastl::iterator_traits<ForwardIterator>::difference_type DifferenceType;
2374 
2375  DifferenceType d = eastl::distance(first, last);
2376 
2377  while(d > 0)
2378  {
2379  ForwardIterator i(first);
2380  DifferenceType d2 = d >> 1; // We use '>>1' here instead of '/2' because MSVC++ for some reason generates significantly worse code for '/2'. Go figure.
2381 
2382  eastl::advance(i, d2);
2383 
2384  if(*i < value)
2385  {
2386  EASTL_VALIDATE_COMPARE(!(value < *i)); // Validate that the compare function is sane.
2387  first = ++i;
2388  d -= d2 + 1;
2389  }
2390  else if(value < *i)
2391  {
2392  EASTL_VALIDATE_COMPARE(!(*i < value)); // Validate that the compare function is sane.
2393  d = d2;
2394  last = i;
2395  }
2396  else
2397  {
2398  ForwardIterator j(i);
2399 
2400  return ResultType(eastl::lower_bound(first, i, value),
2401  eastl::upper_bound(++j, last, value));
2402  }
2403  }
2404  return ResultType(first, first);
2405  }
2406 
2407 
2416  template <typename ForwardIterator, typename T, typename Compare>
2417  pair<ForwardIterator, ForwardIterator>
2418  equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare compare)
2419  {
2420  typedef pair<ForwardIterator, ForwardIterator> ResultType;
2421  typedef typename eastl::iterator_traits<ForwardIterator>::difference_type DifferenceType;
2422 
2423  DifferenceType d = eastl::distance(first, last);
2424 
2425  while(d > 0)
2426  {
2427  ForwardIterator i(first);
2428  DifferenceType d2 = d >> 1; // We use '>>1' here instead of '/2' because MSVC++ for some reason generates significantly worse code for '/2'. Go figure.
2429 
2430  eastl::advance(i, d2);
2431 
2432  if(compare(*i, value))
2433  {
2434  EASTL_VALIDATE_COMPARE(!compare(value, *i)); // Validate that the compare function is sane.
2435  first = ++i;
2436  d -= d2 + 1;
2437  }
2438  else if(compare(value, *i))
2439  {
2440  EASTL_VALIDATE_COMPARE(!compare(*i, value)); // Validate that the compare function is sane.
2441  d = d2;
2442  last = i;
2443  }
2444  else
2445  {
2446  ForwardIterator j(i);
2447 
2448  return ResultType(eastl::lower_bound(first, i, value, compare),
2449  eastl::upper_bound(++j, last, value, compare));
2450  }
2451  }
2452  return ResultType(first, first);
2453  }
2454 
2455 
2466  template <typename ForwardIterator, typename T>
2467  inline void
2468  replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value)
2469  {
2470  for(; first != last; ++first)
2471  {
2472  if(*first == old_value)
2473  *first = new_value;
2474  }
2475  }
2476 
2477 
2488  template <typename ForwardIterator, typename Predicate, typename T>
2489  inline void
2490  replace_if(ForwardIterator first, ForwardIterator last, Predicate predicate, const T& new_value)
2491  {
2492  for(; first != last; ++first)
2493  {
2494  if(predicate(*first))
2495  *first = new_value;
2496  }
2497  }
2498 
2499 
2512  template <typename InputIterator, typename OutputIterator, typename T>
2513  inline OutputIterator
2514  remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value)
2515  {
2516  for(; first != last; ++first)
2517  {
2518  if(!(*first == value)) // Note that we always express value comparisons in terms of < or ==.
2519  {
2520  *result = eastl::move(*first);
2521  ++result;
2522  }
2523  }
2524  return result;
2525  }
2526 
2527 
2540  template <typename InputIterator, typename OutputIterator, typename Predicate>
2541  inline OutputIterator
2542  remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate predicate)
2543  {
2544  for(; first != last; ++first)
2545  {
2546  if(!predicate(*first))
2547  {
2548  *result = eastl::move(*first);
2549  ++result;
2550  }
2551  }
2552  return result;
2553  }
2554 
2555 
2579  template <typename ForwardIterator, typename T>
2580  inline ForwardIterator
2581  remove(ForwardIterator first, ForwardIterator last, const T& value)
2582  {
2583  first = eastl::find(first, last, value);
2584  if(first != last)
2585  {
2586  ForwardIterator i(first);
2587  return eastl::remove_copy(++i, last, first, value);
2588  }
2589  return first;
2590  }
2591 
2592 
2616  template <typename ForwardIterator, typename Predicate>
2617  inline ForwardIterator
2618  remove_if(ForwardIterator first, ForwardIterator last, Predicate predicate)
2619  {
2620  first = eastl::find_if(first, last, predicate);
2621  if(first != last)
2622  {
2623  ForwardIterator i(first);
2624  return eastl::remove_copy_if<ForwardIterator, ForwardIterator, Predicate>(++i, last, first, predicate);
2625  }
2626  return first;
2627  }
2628 
2629 
2645  template <typename InputIterator, typename OutputIterator, typename T>
2646  inline OutputIterator
2647  replace_copy(InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value)
2648  {
2649  for(; first != last; ++first, ++result)
2650  *result = (*first == old_value) ? new_value : *first;
2651  return result;
2652  }
2653 
2654 
2670  template <typename InputIterator, typename OutputIterator, typename Predicate, typename T>
2671  inline OutputIterator
2672  replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate predicate, const T& new_value)
2673  {
2674  for(; first != last; ++first, ++result)
2675  *result = predicate(*first) ? new_value : *first;
2676  return result;
2677  }
2678 
2679 
2680 
2681 
2682  // reverse
2683  //
2684  // We provide helper functions which allow reverse to be implemented more
2685  // efficiently for some types of iterators and types.
2686  //
2687  template <typename BidirectionalIterator>
2688  inline void reverse_impl(BidirectionalIterator first, BidirectionalIterator last, EASTL_ITC_NS::bidirectional_iterator_tag)
2689  {
2690  for(; (first != last) && (first != --last); ++first) // We are not allowed to use operator <, <=, >, >= with a
2691  eastl::iter_swap(first, last); // generic (bidirectional or otherwise) iterator.
2692  }
2693 
2694  template <typename RandomAccessIterator>
2695  inline void reverse_impl(RandomAccessIterator first, RandomAccessIterator last, EASTL_ITC_NS::random_access_iterator_tag)
2696  {
2697  if(first != last)
2698  {
2699  for(; first < --last; ++first) // With a random access iterator, we can use operator < to more efficiently implement
2700  eastl::iter_swap(first, last); // this algorithm. A generic iterator doesn't necessarily have an operator < defined.
2701  }
2702  }
2703 
2713  template <typename BidirectionalIterator>
2714  inline void reverse(BidirectionalIterator first, BidirectionalIterator last)
2715  {
2716  typedef typename eastl::iterator_traits<BidirectionalIterator>::iterator_category IC;
2717  eastl::reverse_impl(first, last, IC());
2718  }
2719 
2720 
2721 
2738  template <typename BidirectionalIterator, typename OutputIterator>
2739  inline OutputIterator
2740  reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result)
2741  {
2742  for(; first != last; ++result)
2743  *result = *--last;
2744  return result;
2745  }
2746 
2747 
2748 
2763  template <typename ForwardIterator1, typename ForwardIterator2>
2764  ForwardIterator1
2765  search(ForwardIterator1 first1, ForwardIterator1 last1,
2766  ForwardIterator2 first2, ForwardIterator2 last2)
2767  {
2768  if(first2 != last2) // If there is anything to search for...
2769  {
2770  // We need to make a special case for a pattern of one element,
2771  // as the logic below prevents one element patterns from working.
2772  ForwardIterator2 temp2(first2);
2773  ++temp2;
2774 
2775  if(temp2 != last2) // If what we are searching for has a length > 1...
2776  {
2777  ForwardIterator1 cur1(first1);
2778  ForwardIterator2 p2;
2779 
2780  while(first1 != last1)
2781  {
2782  // The following loop is the equivalent of eastl::find(first1, last1, *first2)
2783  while((first1 != last1) && !(*first1 == *first2))
2784  ++first1;
2785 
2786  if(first1 != last1)
2787  {
2788  p2 = temp2;
2789  cur1 = first1;
2790 
2791  if(++cur1 != last1)
2792  {
2793  while(*cur1 == *p2)
2794  {
2795  if(++p2 == last2)
2796  return first1;
2797 
2798  if(++cur1 == last1)
2799  return last1;
2800  }
2801 
2802  ++first1;
2803  continue;
2804  }
2805  }
2806  return last1;
2807  }
2808 
2809  // Fall through to the end.
2810  }
2811  else
2812  return eastl::find(first1, last1, *first2);
2813  }
2814 
2815  return first1;
2816 
2817 
2818  #if 0
2819  /* Another implementation which is a little more simpler but executes a little slower on average.
2820  typedef typename eastl::iterator_traits<ForwardIterator1>::difference_type difference_type_1;
2821  typedef typename eastl::iterator_traits<ForwardIterator2>::difference_type difference_type_2;
2822 
2823  const difference_type_2 d2 = eastl::distance(first2, last2);
2824 
2825  for(difference_type_1 d1 = eastl::distance(first1, last1); d1 >= d2; ++first1, --d1)
2826  {
2827  ForwardIterator1 temp1 = first1;
2828 
2829  for(ForwardIterator2 temp2 = first2; ; ++temp1, ++temp2)
2830  {
2831  if(temp2 == last2)
2832  return first1;
2833  if(!(*temp1 == *temp2))
2834  break;
2835  }
2836  }
2837 
2838  return last1;
2839  */
2840  #endif
2841  }
2842 
2843 
2858  template <typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
2859  ForwardIterator1
2860  search(ForwardIterator1 first1, ForwardIterator1 last1,
2861  ForwardIterator2 first2, ForwardIterator2 last2,
2862  BinaryPredicate predicate)
2863  {
2864  typedef typename eastl::iterator_traits<ForwardIterator1>::difference_type difference_type_1;
2865  typedef typename eastl::iterator_traits<ForwardIterator2>::difference_type difference_type_2;
2866 
2867  difference_type_2 d2 = eastl::distance(first2, last2);
2868 
2869  if(d2 != 0)
2870  {
2871  ForwardIterator1 i(first1);
2872  eastl::advance(i, d2);
2873 
2874  for(difference_type_1 d1 = eastl::distance(first1, last1); d1 >= d2; --d1)
2875  {
2876  if(eastl::equal<ForwardIterator1, ForwardIterator2, BinaryPredicate>(first1, i, first2, predicate))
2877  return first1;
2878  if(d1 > d2) // To do: Find a way to make the algorithm more elegant.
2879  {
2880  ++first1;
2881  ++i;
2882  }
2883  }
2884  return last1;
2885  }
2886  return first1; // Just like with strstr, we return first1 if the match string is empty.
2887  }
2888 
2889 
2890 
2891  // search_n helper functions
2892  //
2893  template <typename ForwardIterator, typename Size, typename T>
2894  ForwardIterator // Generic implementation.
2895  search_n_impl(ForwardIterator first, ForwardIterator last, Size count, const T& value, EASTL_ITC_NS::forward_iterator_tag)
2896  {
2897  if(count <= 0)
2898  return first;
2899 
2900  Size d1 = (Size)eastl::distance(first, last); // Should d1 be of type Size, ptrdiff_t, or iterator_traits<ForwardIterator>::difference_type?
2901  // The problem with using iterator_traits<ForwardIterator>::difference_type is that
2902  if(count > d1) // ForwardIterator may not be a true iterator but instead something like a pointer.
2903  return last;
2904 
2905  for(; d1 >= count; ++first, --d1)
2906  {
2907  ForwardIterator i(first);
2908 
2909  for(Size n = 0; n < count; ++n, ++i, --d1)
2910  {
2911  if(!(*i == value)) // Note that we always express value comparisons in terms of < or ==.
2912  goto not_found;
2913  }
2914  return first;
2915 
2916  not_found:
2917  first = i;
2918  }
2919  return last;
2920  }
2921 
2922  template <typename RandomAccessIterator, typename Size, typename T> inline
2923  RandomAccessIterator // Random access iterator implementation. Much faster than generic implementation.
2924  search_n_impl(RandomAccessIterator first, RandomAccessIterator last, Size count, const T& value, EASTL_ITC_NS::random_access_iterator_tag)
2925  {
2926  if(count <= 0)
2927  return first;
2928  else if(count == 1)
2929  return eastl::find(first, last, value);
2930  else if(last > first)
2931  {
2932  RandomAccessIterator lookAhead;
2933  RandomAccessIterator backTrack;
2934 
2935  Size skipOffset = (count - 1);
2936  Size tailSize = (Size)(last - first);
2937  Size remainder;
2938  Size prevRemainder;
2939 
2940  for(lookAhead = first + skipOffset; tailSize >= count; lookAhead += count)
2941  {
2942  tailSize -= count;
2943 
2944  if(*lookAhead == value)
2945  {
2946  remainder = skipOffset;
2947 
2948  for(backTrack = lookAhead - 1; *backTrack == value; --backTrack)
2949  {
2950  if(--remainder == 0)
2951  return (lookAhead - skipOffset); // success
2952  }
2953 
2954  if(remainder <= tailSize)
2955  {
2956  prevRemainder = remainder;
2957 
2958  while(*(++lookAhead) == value)
2959  {
2960  if(--remainder == 0)
2961  return (backTrack + 1); // success
2962  }
2963  tailSize -= (prevRemainder - remainder);
2964  }
2965  else
2966  return last; // failure
2967  }
2968 
2969  // lookAhead here is always pointing to the element of the last mismatch.
2970  }
2971  }
2972 
2973  return last; // failure
2974  }
2975 
2976 
2986  template <typename ForwardIterator, typename Size, typename T>
2987  ForwardIterator
2988  search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value)
2989  {
2990  typedef typename eastl::iterator_traits<ForwardIterator>::iterator_category IC;
2991  return eastl::search_n_impl(first, last, count, value, IC());
2992  }
2993 
2994 
3016  template <typename ForwardIterator, typename T>
3017  inline bool
3018  binary_search(ForwardIterator first, ForwardIterator last, const T& value)
3019  {
3020  // To do: This can be made slightly faster by not using lower_bound.
3021  ForwardIterator i(eastl::lower_bound<ForwardIterator, T>(first, last, value));
3022  return ((i != last) && !(value < *i)); // Note that we always express value comparisons in terms of < or ==.
3023  }
3024 
3025 
3036  template <typename ForwardIterator, typename T, typename Compare>
3037  inline bool
3038  binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare compare)
3039  {
3040  // To do: This can be made slightly faster by not using lower_bound.
3041  ForwardIterator i(eastl::lower_bound<ForwardIterator, T, Compare>(first, last, value, compare));
3042  return ((i != last) && !compare(value, *i));
3043  }
3044 
3045 
3054  template <typename ForwardIterator, typename T>
3055  inline ForwardIterator
3056  binary_search_i(ForwardIterator first, ForwardIterator last, const T& value)
3057  {
3058  // To do: This can be made slightly faster by not using lower_bound.
3059  ForwardIterator i(eastl::lower_bound<ForwardIterator, T>(first, last, value));
3060  if((i != last) && !(value < *i)) // Note that we always express value comparisons in terms of < or ==.
3061  return i;
3062  return last;
3063  }
3064 
3065 
3074  template <typename ForwardIterator, typename T, typename Compare>
3075  inline ForwardIterator
3076  binary_search_i(ForwardIterator first, ForwardIterator last, const T& value, Compare compare)
3077  {
3078  // To do: This can be made slightly faster by not using lower_bound.
3079  ForwardIterator i(eastl::lower_bound<ForwardIterator, T, Compare>(first, last, value, compare));
3080  if((i != last) && !compare(value, *i))
3081  return i;
3082  return last;
3083  }
3084 
3085 
3108  template <typename ForwardIterator>
3109  ForwardIterator unique(ForwardIterator first, ForwardIterator last)
3110  {
3111  first = eastl::adjacent_find<ForwardIterator>(first, last);
3112 
3113  if(first != last) // We expect that there are duplicated items, else the user wouldn't be calling this function.
3114  {
3115  ForwardIterator dest(first);
3116 
3117  for(++first; first != last; ++first)
3118  {
3119  if(!(*dest == *first)) // Note that we always express value comparisons in terms of < or ==.
3120  *++dest = *first;
3121  }
3122  return ++dest;
3123  }
3124  return last;
3125  }
3126 
3127 
3145  template <typename ForwardIterator, typename BinaryPredicate>
3146  ForwardIterator unique(ForwardIterator first, ForwardIterator last, BinaryPredicate predicate)
3147  {
3148  first = eastl::adjacent_find<ForwardIterator, BinaryPredicate>(first, last, predicate);
3149 
3150  if(first != last) // We expect that there are duplicated items, else the user wouldn't be calling this function.
3151  {
3152  ForwardIterator dest(first);
3153 
3154  for(++first; first != last; ++first)
3155  {
3156  if(!predicate(*dest, *first))
3157  *++dest = *first;
3158  }
3159  return ++dest;
3160  }
3161  return last;
3162  }
3163 
3164 
3165 
3166  // find_end
3167  //
3168  // We provide two versions here, one for a bidirectional iterators and one for
3169  // regular forward iterators. Given that we are searching backward, it's a bit
3170  // more efficient if we can use backwards iteration to implement our search,
3171  // though this requires an iterator that can be reversed.
3172  //
3173  template <typename ForwardIterator1, typename ForwardIterator2>
3174  ForwardIterator1
3175  find_end_impl(ForwardIterator1 first1, ForwardIterator1 last1,
3176  ForwardIterator2 first2, ForwardIterator2 last2,
3177  EASTL_ITC_NS::forward_iterator_tag, EASTL_ITC_NS::forward_iterator_tag)
3178  {
3179  if(first2 != last2) // We have to do this check because the search algorithm below will return first1 (and not last1) if the first2/last2 range is empty.
3180  {
3181  for(ForwardIterator1 result(last1); ; )
3182  {
3183  const ForwardIterator1 resultNext(eastl::search(first1, last1, first2, last2));
3184 
3185  if(resultNext != last1) // If another sequence was found...
3186  {
3187  first1 = result = resultNext;
3188  ++first1;
3189  }
3190  else
3191  return result;
3192  }
3193  }
3194  return last1;
3195  }
3196 
3197  template <typename BidirectionalIterator1, typename BidirectionalIterator2>
3198  BidirectionalIterator1
3199  find_end_impl(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
3200  BidirectionalIterator2 first2, BidirectionalIterator2 last2,
3201  EASTL_ITC_NS::bidirectional_iterator_tag, EASTL_ITC_NS::bidirectional_iterator_tag)
3202  {
3203  typedef eastl::reverse_iterator<BidirectionalIterator1> reverse_iterator1;
3204  typedef eastl::reverse_iterator<BidirectionalIterator2> reverse_iterator2;
3205 
3206  reverse_iterator1 rresult(eastl::search(reverse_iterator1(last1), reverse_iterator1(first1),
3207  reverse_iterator2(last2), reverse_iterator2(first2)));
3208  if(rresult.base() != first1) // If we found something...
3209  {
3210  BidirectionalIterator1 result(rresult.base());
3211 
3212  eastl::advance(result, -eastl::distance(first2, last2)); // We have an opportunity to optimize this, as the
3213  return result; // search function already calculates this distance.
3214  }
3215  return last1;
3216  }
3217 
3229  template <typename ForwardIterator1, typename ForwardIterator2>
3230  inline ForwardIterator1
3231  find_end(ForwardIterator1 first1, ForwardIterator1 last1,
3232  ForwardIterator2 first2, ForwardIterator2 last2)
3233  {
3234  typedef typename eastl::iterator_traits<ForwardIterator1>::iterator_category IC1;
3235  typedef typename eastl::iterator_traits<ForwardIterator2>::iterator_category IC2;
3236 
3237  return eastl::find_end_impl(first1, last1, first2, last2, IC1(), IC2());
3238  }
3239 
3240 
3241 
3242 
3243  // To consider: Fold the predicate and non-predicate versions of
3244  // this algorithm into a single function.
3245  template <typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
3246  ForwardIterator1
3247  find_end_impl(ForwardIterator1 first1, ForwardIterator1 last1,
3248  ForwardIterator2 first2, ForwardIterator2 last2,
3249  BinaryPredicate predicate,
3250  EASTL_ITC_NS::forward_iterator_tag, EASTL_ITC_NS::forward_iterator_tag)
3251  {
3252  if(first2 != last2) // We have to do this check because the search algorithm below will return first1 (and not last1) if the first2/last2 range is empty.
3253  {
3254  for(ForwardIterator1 result = last1; ; )
3255  {
3256  const ForwardIterator1 resultNext(eastl::search<ForwardIterator1, ForwardIterator2, BinaryPredicate>(first1, last1, first2, last2, predicate));
3257 
3258  if(resultNext != last1) // If another sequence was found...
3259  {
3260  first1 = result = resultNext;
3261  ++first1;
3262  }
3263  else
3264  return result;
3265  }
3266  }
3267  return last1;
3268  }
3269 
3270  template <typename BidirectionalIterator1, typename BidirectionalIterator2, typename BinaryPredicate>
3271  BidirectionalIterator1
3272  find_end_impl(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
3273  BidirectionalIterator2 first2, BidirectionalIterator2 last2,
3274  BinaryPredicate predicate,
3275  EASTL_ITC_NS::bidirectional_iterator_tag, EASTL_ITC_NS::bidirectional_iterator_tag)
3276  {
3277  typedef eastl::reverse_iterator<BidirectionalIterator1> reverse_iterator1;
3278  typedef eastl::reverse_iterator<BidirectionalIterator2> reverse_iterator2;
3279 
3280  reverse_iterator1 rresult(eastl::search<reverse_iterator1, reverse_iterator2, BinaryPredicate>
3281  (reverse_iterator1(last1), reverse_iterator1(first1),
3282  reverse_iterator2(last2), reverse_iterator2(first2),
3283  predicate));
3284  if(rresult.base() != first1) // If we found something...
3285  {
3286  BidirectionalIterator1 result(rresult.base());
3287  eastl::advance(result, -eastl::distance(first2, last2));
3288  return result;
3289  }
3290  return last1;
3291  }
3292 
3293 
3306  template <typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
3307  inline ForwardIterator1
3308  find_end(ForwardIterator1 first1, ForwardIterator1 last1,
3309  ForwardIterator2 first2, ForwardIterator2 last2,
3310  BinaryPredicate predicate)
3311  {
3312  typedef typename eastl::iterator_traits<ForwardIterator1>::iterator_category IC1;
3313  typedef typename eastl::iterator_traits<ForwardIterator2>::iterator_category IC2;
3314 
3315  return eastl::find_end_impl<ForwardIterator1, ForwardIterator2, BinaryPredicate>
3316  (first1, last1, first2, last2, predicate, IC1(), IC2());
3317  }
3318 
3319 
3336  template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
3337  OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
3338  InputIterator2 first2, InputIterator2 last2,
3339  OutputIterator result)
3340  {
3341  while((first1 != last1) && (first2 != last2))
3342  {
3343  if(*first1 < *first2)
3344  {
3345  *result = *first1;
3346  ++first1;
3347  ++result;
3348  }
3349  else if(*first2 < *first1)
3350  ++first2;
3351  else
3352  {
3353  ++first1;
3354  ++first2;
3355  }
3356  }
3357 
3358  return eastl::copy(first1, last1, result);
3359  }
3360 
3361 
3362  template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare>
3363  OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
3364  InputIterator2 first2, InputIterator2 last2,
3365  OutputIterator result, Compare compare)
3366  {
3367  while((first1 != last1) && (first2 != last2))
3368  {
3369  if(compare(*first1, *first2))
3370  {
3371  EASTL_VALIDATE_COMPARE(!compare(*first2, *first1)); // Validate that the compare function is sane.
3372  *result = *first1;
3373  ++first1;
3374  ++result;
3375  }
3376  else if(compare(*first2, *first1))
3377  {
3378  EASTL_VALIDATE_COMPARE(!compare(*first1, *first2)); // Validate that the compare function is sane.
3379  ++first2;
3380  }
3381  else
3382  {
3383  ++first1;
3384  ++first2;
3385  }
3386  }
3387 
3388  return eastl::copy(first1, last1, result);
3389  }
3390 
3391 
3412  template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare>
3413  void set_difference_2(InputIterator1 first1, InputIterator1 last1,
3414  InputIterator2 first2, InputIterator2 last2,
3415  OutputIterator result1, OutputIterator result2, Compare compare)
3416  {
3417  while ((first1 != last1) && (first2 != last2))
3418  {
3419  if (compare(*first1, *first2))
3420  {
3421  EASTL_VALIDATE_COMPARE(!compare(*first2, *first1)); // Validate that the compare function is sane.
3422  *result1++ = *first1++;
3423  }
3424  else if (compare(*first2, *first1))
3425  {
3426  EASTL_VALIDATE_COMPARE(!compare(*first1, *first2)); // Validate that the compare function is sane.
3427  *result2++ = *first2++;
3428  }
3429  else
3430  {
3431  ++first1;
3432  ++first2;
3433  }
3434  }
3435 
3436  eastl::copy(first2, last2, result2);
3437  eastl::copy(first1, last1, result1);
3438  }
3439 
3444  template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
3445  void set_difference_2(InputIterator1 first1, InputIterator1 last1,
3446  InputIterator2 first2, InputIterator2 last2,
3447  OutputIterator result1, OutputIterator result2)
3448  {
3449  eastl::set_difference_2(first1, last1, first2, last2, result1, result2, eastl::less<>{});
3450  }
3451 
3452 
3470  template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
3471  OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1,
3472  InputIterator2 first2, InputIterator2 last2,
3473  OutputIterator result)
3474  {
3475  while((first1 != last1) && (first2 != last2))
3476  {
3477  if(*first1 < *first2)
3478  {
3479  *result = *first1;
3480  ++first1;
3481  ++result;
3482  }
3483  else if(*first2 < *first1)
3484  {
3485  *result = *first2;
3486  ++first2;
3487  ++result;
3488  }
3489  else
3490  {
3491  ++first1;
3492  ++first2;
3493  }
3494  }
3495 
3496  return eastl::copy(first2, last2, eastl::copy(first1, last1, result));
3497  }
3498 
3499 
3500  template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare>
3501  OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1,
3502  InputIterator2 first2, InputIterator2 last2,
3503  OutputIterator result, Compare compare)
3504  {
3505  while((first1 != last1) && (first2 != last2))
3506  {
3507  if(compare(*first1, *first2))
3508  {
3509  EASTL_VALIDATE_COMPARE(!compare(*first2, *first1)); // Validate that the compare function is sane.
3510  *result = *first1;
3511  ++first1;
3512  ++result;
3513  }
3514  else if(compare(*first2, *first1))
3515  {
3516  EASTL_VALIDATE_COMPARE(!compare(*first1, *first2)); // Validate that the compare function is sane.
3517  *result = *first2;
3518  ++first2;
3519  ++result;
3520  }
3521  else
3522  {
3523  ++first1;
3524  ++first2;
3525  }
3526  }
3527 
3528  return eastl::copy(first2, last2, eastl::copy(first1, last1, result));
3529  }
3530 
3531 
3550  template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
3551  OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
3552  InputIterator2 first2, InputIterator2 last2,
3553  OutputIterator result)
3554  {
3555  while((first1 != last1) && (first2 != last2))
3556  {
3557  if(*first1 < *first2)
3558  ++first1;
3559  else if(*first2 < *first1)
3560  ++first2;
3561  else
3562  {
3563  *result = *first1;
3564  ++first1;
3565  ++first2;
3566  ++result;
3567  }
3568  }
3569 
3570  return result;
3571  }
3572 
3573 
3574  template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare>
3575  OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
3576  InputIterator2 first2, InputIterator2 last2,
3577  OutputIterator result, Compare compare)
3578  {
3579  while((first1 != last1) && (first2 != last2))
3580  {
3581  if(compare(*first1, *first2))
3582  {
3583  EASTL_VALIDATE_COMPARE(!compare(*first2, *first1)); // Validate that the compare function is sane.
3584  ++first1;
3585  }
3586  else if(compare(*first2, *first1))
3587  {
3588  EASTL_VALIDATE_COMPARE(!compare(*first1, *first2)); // Validate that the compare function is sane.
3589  ++first2;
3590  }
3591  else
3592  {
3593  *result = *first1;
3594  ++first1;
3595  ++first2;
3596  ++result;
3597  }
3598  }
3599 
3600  return result;
3601  }
3602 
3603 
3604 
3623  template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
3624  OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
3625  InputIterator2 first2, InputIterator2 last2,
3626  OutputIterator result)
3627  {
3628  while((first1 != last1) && (first2 != last2))
3629  {
3630  if(*first1 < *first2)
3631  {
3632  *result = *first1;
3633  ++first1;
3634  }
3635  else if(*first2 < *first1)
3636  {
3637  *result = *first2;
3638  ++first2;
3639  }
3640  else
3641  {
3642  *result = *first1;
3643  ++first1;
3644  ++first2;
3645  }
3646  ++result;
3647  }
3648 
3649  return eastl::copy(first2, last2, eastl::copy(first1, last1, result));
3650  }
3651 
3652 
3653  template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare>
3654  OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
3655  InputIterator2 first2, InputIterator2 last2,
3656  OutputIterator result, Compare compare)
3657  {
3658  while((first1 != last1) && (first2 != last2))
3659  {
3660  if(compare(*first1, *first2))
3661  {
3662  EASTL_VALIDATE_COMPARE(!compare(*first2, *first1)); // Validate that the compare function is sane.
3663  *result = *first1;
3664  ++first1;
3665  }
3666  else if(compare(*first2, *first1))
3667  {
3668  EASTL_VALIDATE_COMPARE(!compare(*first1, *first2)); // Validate that the compare function is sane.
3669  *result = *first2;
3670  ++first2;
3671  }
3672  else
3673  {
3674  *result = *first1;
3675  ++first1;
3676  ++first2;
3677  }
3678  ++result;
3679  }
3680 
3681  return eastl::copy(first2, last2, eastl::copy(first1, last1, result));
3682  }
3683 
3684 
3702  template <typename InputIterator1, typename InputIterator2,
3703  typename OutputIterator1, typename OutputIterator2, typename OutputIterator3, typename Compare>
3704  OutputIterator3 set_decomposition(InputIterator1 first1, InputIterator1 last1,
3705  InputIterator2 first2, InputIterator2 last2,
3706  OutputIterator1 result1, OutputIterator2 result2, OutputIterator3 result3, Compare compare)
3707  {
3708  while ((first1 != last1) && (first2 != last2))
3709  {
3710  if (compare(*first1, *first2))
3711  {
3712  EASTL_VALIDATE_COMPARE(!compare(*first2, *first1)); // Validate that the compare function is sane.
3713  *result1++ = *first1++;
3714  }
3715  else if (compare(*first2, *first1))
3716  {
3717  EASTL_VALIDATE_COMPARE(!compare(*first1, *first2)); // Validate that the compare function is sane.
3718  *result2++ = *first2++;
3719  }
3720  else
3721  {
3722  *result3++ = *first1++;
3723  ++first2;
3724  }
3725  }
3726 
3727  eastl::copy(first1, last1, result1);
3728  eastl::copy(first2, last2, result2);
3729 
3730  return result3;
3731  }
3732 
3737  template <typename InputIterator1, typename InputIterator2,
3738  typename OutputIterator1, typename OutputIterator2, typename OutputIterator3>
3739  OutputIterator3 set_decomposition(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,
3740  OutputIterator1 result1, OutputIterator2 result2, OutputIterator3 result3)
3741  {
3742  return eastl::set_decomposition(first1, last1, first2, last2, result1, result2, result3, eastl::less<>{});
3743  }
3744 
3745 
3748  template<typename ForwardIterator1, typename ForwardIterator2>
3749  bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2)
3750  {
3751  typedef typename eastl::iterator_traits<ForwardIterator1>::difference_type difference_type;
3752 
3753  // Skip past any equivalent initial elements.
3754  while((first1 != last1) && (*first1 == *first2))
3755  {
3756  ++first1;
3757  ++first2;
3758  }
3759 
3760  if(first1 != last1)
3761  {
3762  const difference_type first1Size = eastl::distance(first1, last1);
3763  ForwardIterator2 last2 = first2;
3764  eastl::advance(last2, first1Size);
3765 
3766  for(ForwardIterator1 i = first1; i != last1; ++i)
3767  {
3768  if(i == eastl::find(first1, i, *i))
3769  {
3770  const difference_type c = eastl::count(first2, last2, *i);
3771 
3772  if((c == 0) || (c != eastl::count(i, last1, *i)))
3773  return false;
3774  }
3775  }
3776  }
3777 
3778  return true;
3779  }
3780 
3783  template<typename ForwardIterator1, typename ForwardIterator2, class BinaryPredicate>
3784  bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate predicate)
3785  {
3786  typedef typename eastl::iterator_traits<ForwardIterator1>::difference_type difference_type;
3787 
3788  // Skip past any equivalent initial elements.
3789  while((first1 != last1) && predicate(*first1, *first2))
3790  {
3791  ++first1;
3792  ++first2;
3793  }
3794 
3795  if(first1 != last1)
3796  {
3797  const difference_type first1Size = eastl::distance(first1, last1);
3798  ForwardIterator2 last2 = first2;
3799  eastl::advance(last2, first1Size);
3800 
3801  for(ForwardIterator1 i = first1; i != last1; ++i)
3802  {
3803  if(i == eastl::find(first1, i, *i, predicate))
3804  {
3805  const difference_type c = eastl::count(first2, last2, *i, predicate);
3806 
3807  if((c == 0) || (c != eastl::count(i, last1, *i, predicate)))
3808  return false;
3809  }
3810  }
3811  }
3812 
3813  return true;
3814  }
3815 
3816 
3842 
3843  template<typename BidirectionalIterator, typename Compare>
3844  bool next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare compare)
3845  {
3846  if(first != last) // If there is anything in the range...
3847  {
3848  BidirectionalIterator i = last;
3849 
3850  if(first != --i) // If the range has more than one item...
3851  {
3852  for(;;)
3853  {
3854  BidirectionalIterator ii(i), j;
3855 
3856  if(compare(*--i, *ii)) // Find two consecutive values where the first is less than the second.
3857  {
3858  j = last;
3859  while(!compare(*i, *--j)) // Find the final value that's greater than the first (it may be equal to the second).
3860  {}
3861  eastl::iter_swap(i, j); // Swap the first and the final.
3862  eastl::reverse(ii, last); // Reverse the ranget from second to last.
3863  return true;
3864  }
3865 
3866  if(i == first) // There are no two consecutive values where the first is less than the second, meaning the range is in reverse order. The reverse ordered range is always the last permutation.
3867  {
3868  eastl::reverse(first, last);
3869  break; // We are done.
3870  }
3871  }
3872  }
3873  }
3874 
3875  return false;
3876  }
3877 
3878  template<typename BidirectionalIterator>
3879  bool next_permutation(BidirectionalIterator first, BidirectionalIterator last)
3880  {
3881  typedef typename eastl::iterator_traits<BidirectionalIterator>::value_type value_type;
3882 
3883  return eastl::next_permutation(first, last, eastl::less<value_type>());
3884  }
3885 
3886 
3887 
3924  namespace Internal
3925  {
3926  template<typename ForwardIterator>
3927  ForwardIterator rotate_general_impl(ForwardIterator first, ForwardIterator middle, ForwardIterator last)
3928  {
3929  using eastl::swap;
3930 
3931  ForwardIterator current = middle;
3932 
3933  do {
3934  swap(*first++, *current++);
3935 
3936  if(first == middle)
3937  middle = current;
3938  } while(current != last);
3939 
3940  ForwardIterator result = first;
3941  current = middle;
3942 
3943  while(current != last)
3944  {
3945  swap(*first++, *current++);
3946 
3947  if(first == middle)
3948  middle = current;
3949  else if(current == last)
3950  current = middle;
3951  }
3952 
3953  return result; // result points to first + (last - middle).
3954  }
3955 
3956 
3957  template <typename ForwardIterator>
3958  ForwardIterator move_rotate_left_by_one(ForwardIterator first, ForwardIterator last)
3959  {
3960  typedef typename eastl::iterator_traits<ForwardIterator>::value_type value_type;
3961 
3962  value_type temp(eastl::move(*first));
3963  ForwardIterator result = eastl::move(eastl::next(first), last, first); // Note that while our template type is BidirectionalIterator, if the actual
3964  *result = eastl::move(temp); // iterator is a RandomAccessIterator then this move will be a memmove for trivial types.
3965 
3966  return result; // result points to the final element in the range.
3967  }
3968 
3969 
3970  template <typename BidirectionalIterator>
3971  BidirectionalIterator move_rotate_right_by_one(BidirectionalIterator first, BidirectionalIterator last)
3972  {
3973  typedef typename eastl::iterator_traits<BidirectionalIterator>::value_type value_type;
3974 
3975  BidirectionalIterator beforeLast = eastl::prev(last);
3976  value_type temp(eastl::move(*beforeLast));
3977  BidirectionalIterator result = eastl::move_backward(first, beforeLast, last); // Note that while our template type is BidirectionalIterator, if the actual
3978  *first = eastl::move(temp); // iterator is a RandomAccessIterator then this move will be a memmove for trivial types.
3979 
3980  return result; // result points to the first element in the range.
3981  }
3982 
3983  template <typename /*IteratorCategory*/, bool /*is_trivially_move_assignable*/>
3985  {
3986  template <typename ForwardIterator>
3987  static ForwardIterator rotate_impl(ForwardIterator first, ForwardIterator middle, ForwardIterator last)
3988  { return Internal::rotate_general_impl(first, middle, last); }
3989  };
3990 
3991  template <>
3992  struct rotate_helper<EASTL_ITC_NS::forward_iterator_tag, true>
3993  {
3994  template <typename ForwardIterator>
3995  static ForwardIterator rotate_impl(ForwardIterator first, ForwardIterator middle, ForwardIterator last)
3996  {
3997  if(eastl::next(first) == middle) // If moving trivial types by a single element, memcpy is fast for that case.
3998  return Internal::move_rotate_left_by_one(first, last);
3999  return Internal::rotate_general_impl(first, middle, last);
4000  }
4001  };
4002 
4003  template <>
4004  struct rotate_helper<EASTL_ITC_NS::bidirectional_iterator_tag, false>
4005  {
4006  template <typename BidirectionalIterator>
4007  static BidirectionalIterator rotate_impl(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last)
4008  { return Internal::rotate_general_impl(first, middle, last); } // rotate_general_impl outperforms the flipping hands algorithm.
4009 
4010  /*
4011  // Simplest "flipping hands" implementation. Disabled because it's slower on average than rotate_general_impl.
4012  template <typename BidirectionalIterator>
4013  static BidirectionalIterator rotate_impl(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last)
4014  {
4015  eastl::reverse(first, middle);
4016  eastl::reverse(middle, last);
4017  eastl::reverse(first, last);
4018  return first + (last - middle); // This can be slow for large ranges because operator + and - are O(n).
4019  }
4020 
4021  // Smarter "flipping hands" implementation, but still disabled because benchmarks are showing it to be slower than rotate_general_impl.
4022  template <typename BidirectionalIterator>
4023  static BidirectionalIterator rotate_impl(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last)
4024  {
4025  // This is the "flipping hands" algorithm.
4026  eastl::reverse_impl(first, middle, EASTL_ITC_NS::bidirectional_iterator_tag()); // Reverse the left side.
4027  eastl::reverse_impl(middle, last, EASTL_ITC_NS::bidirectional_iterator_tag()); // Reverse the right side.
4028 
4029  // Reverse the entire range.
4030  while((first != middle) && (middle != last))
4031  {
4032  eastl::iter_swap(first, --last);
4033  ++first;
4034  }
4035 
4036  if(first == middle) // Finish reversing the entire range.
4037  {
4038  eastl::reverse_impl(middle, last, bidirectional_iterator_tag());
4039  return last;
4040  }
4041  else
4042  {
4043  eastl::reverse_impl(first, middle, bidirectional_iterator_tag());
4044  return first;
4045  }
4046  }
4047  */
4048  };
4049 
4050  template <>
4051  struct rotate_helper<EASTL_ITC_NS::bidirectional_iterator_tag, true>
4052  {
4053  template <typename BidirectionalIterator>
4054  static BidirectionalIterator rotate_impl(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last)
4055  {
4056  if(eastl::next(first) == middle) // If moving trivial types by a single element, memcpy is fast for that case.
4057  return Internal::move_rotate_left_by_one(first, last);
4058  if(eastl::next(middle) == last)
4059  return Internal::move_rotate_right_by_one(first, last);
4060  return Internal::rotate_general_impl(first, middle, last);
4061  }
4062  };
4063 
4064  template <typename Integer>
4065  inline Integer greatest_common_divisor(Integer x, Integer y)
4066  {
4067  do {
4068  Integer t = (x % y);
4069  x = y;
4070  y = t;
4071  } while(y);
4072 
4073  return x;
4074  }
4075 
4076  template <>
4077  struct rotate_helper<EASTL_ITC_NS::random_access_iterator_tag, false>
4078  {
4079  // This is the juggling algorithm, using move operations.
4080  // In practice this implementation is about 25% faster than rotate_general_impl. We may want to
4081  // consider sticking with just rotate_general_impl and avoid the code generation of this function.
4082  template <typename RandomAccessIterator>
4083  static RandomAccessIterator rotate_impl(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last)
4084  {
4085  typedef typename iterator_traits<RandomAccessIterator>::difference_type difference_type;
4086  typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
4087 
4088  const difference_type m1 = (middle - first);
4089  const difference_type m2 = (last - middle);
4090  const difference_type g = Internal::greatest_common_divisor(m1, m2);
4091  value_type temp;
4092 
4093  for(RandomAccessIterator p = first + g; p != first;)
4094  {
4095  temp = eastl::move(*--p);
4096  RandomAccessIterator p1 = p;
4097  RandomAccessIterator p2 = p + m1;
4098  do
4099  {
4100  *p1 = eastl::move(*p2);
4101  p1 = p2;
4102  const difference_type d = (last - p2);
4103 
4104  if(m1 < d)
4105  p2 += m1;
4106  else
4107  p2 = first + (m1 - d);
4108  } while(p2 != p);
4109 
4110  *p1 = eastl::move(temp);
4111  }
4112 
4113  return first + m2;
4114  }
4115  };
4116 
4117  template <>
4118  struct rotate_helper<EASTL_ITC_NS::random_access_iterator_tag, true>
4119  {
4120  // Experiments were done which tested the performance of using an intermediate buffer
4121  // to do memcpy's to as opposed to executing a swapping algorithm. It turns out this is
4122  // actually slower than even rotate_general_impl, partly because the average case involves
4123  // memcpy'ing a quarter of the element range twice. Experiments were done with various kinds
4124  // of PODs with various element counts.
4125 
4126  template <typename RandomAccessIterator>
4127  static RandomAccessIterator rotate_impl(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last)
4128  {
4129  if(eastl::next(first) == middle) // If moving trivial types by a single element, memcpy is fast for that case.
4130  return Internal::move_rotate_left_by_one(first, last);
4131  if(eastl::next(middle) == last)
4132  return Internal::move_rotate_right_by_one(first, last);
4133  if((last - first) < 32) // For small ranges rotate_general_impl is faster.
4134  return Internal::rotate_general_impl(first, middle, last);
4136  }
4137  };
4138 
4139  } // namespace Internal
4140 
4141 
4142  template <typename ForwardIterator>
4143  ForwardIterator rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last)
4144  {
4145  if(middle != first)
4146  {
4147  if(middle != last)
4148  {
4149  typedef typename eastl::iterator_traits<ForwardIterator>::iterator_category IC;
4150  typedef typename eastl::iterator_traits<ForwardIterator>::value_type value_type;
4151 
4152  return Internal::rotate_helper<IC, eastl::is_trivially_move_assignable<value_type>::value || // This is the best way of telling if we can move types via memmove, but without a conforming C++11 compiler it usually returns false.
4153  eastl::is_pod<value_type>::value || // This is a more conservative way of telling if we can move types via memmove, and most compilers support it, but it doesn't have as full of coverage as is_trivially_move_assignable.
4154  eastl::is_scalar<value_type>::value> // This is the most conservative means and works with all compilers, but works only for scalars.
4155  ::rotate_impl(first, middle, last);
4156  }
4157 
4158  return first;
4159  }
4160 
4161  return last;
4162  }
4163 
4164 
4165 
4172  template <typename ForwardIterator, typename OutputIterator>
4173  OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result)
4174  {
4175  return eastl::copy(first, middle, eastl::copy(middle, last, result));
4176  }
4177 
4178 
4179 
4186  template <class T, class Compare>
4187  EA_CONSTEXPR const T& clamp(const T& v, const T& lo, const T& hi, Compare comp)
4188  {
4189  // code collapsed to a single line due to constexpr requirements
4190  return [&] { EASTL_ASSERT(!comp(hi, lo)); }(),
4191  comp(v, lo) ? lo : comp(hi, v) ? hi : v;
4192  }
4193 
4194  template <class T>
4195  EA_CONSTEXPR const T& clamp(const T& v, const T& lo, const T& hi)
4196  {
4197  return eastl::clamp(v, lo, hi, eastl::less<>());
4198  }
4199 
4200 
4201 
4202 } // namespace eastl
4203 
4204 
4205 #endif // Header include guard
4206 
4207 
4208 
4209 
4210 
4211 
4212 
4213 
4214 
4215 
4216 
4217 
4218 
4219 
4220 
Definition: iterator.h:224
Definition: random.h:52
Definition: initializer_list.h:38
EA Standard Template Library.
Definition: algorithm.h:288
eastl::iterator_traits< InputIterator >::difference_type count(InputIterator first, InputIterator last, const T &value)
Definition: algorithm.h:1347
void random_shuffle(RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator &&rng)
Definition: algorithm.h:1064
void replace_if(ForwardIterator first, ForwardIterator last, Predicate predicate, const T &new_value)
Definition: algorithm.h:2490
bool identical(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2)
Definition: algorithm.h:1949
OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result)
Definition: algorithm.h:4173
ForwardIterator remove(ForwardIterator first, ForwardIterator last, const T &value)
Definition: algorithm.h:2581
OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result)
Definition: algorithm.h:3337
bool all_of(InputIterator first, InputIterator last, Predicate p)
Definition: algorithm.h:909
OutputIterator copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate predicate)
Definition: algorithm.h:1172
InputIterator find(InputIterator first, InputIterator last, const T &value)
Definition: algorithm.h:1421
ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, const T &value)
Definition: algorithm.h:2286
T max(std::initializer_list< T > ilist)
Definition: algorithm.h:652
OutputIterator3 set_decomposition(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator1 result1, OutputIterator2 result2, OutputIterator3 result3, Compare compare)
Definition: algorithm.h:3704
pair< ForwardIterator, ForwardIterator > equal_range(ForwardIterator first, ForwardIterator last, const T &value)
Definition: algorithm.h:2370
OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result)
Definition: copy_help.h:191
eastl::iterator_traits< InputIterator >::difference_type count_if(InputIterator first, InputIterator last, Predicate predicate)
Definition: algorithm.h:1392
bool next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare compare)
Definition: algorithm.h:3844
bool binary_search(ForwardIterator first, ForwardIterator last, const T &value)
Definition: algorithm.h:3018
eastl::pair< ForwardIterator, ForwardIterator > minmax_element(ForwardIterator first, ForwardIterator last, Compare compare)
Definition: algorithm.h:678
OutputIterator remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T &value)
Definition: algorithm.h:2514
OutputIterator replace_copy(InputIterator first, InputIterator last, OutputIterator result, const T &old_value, const T &new_value)
Definition: algorithm.h:2647
eastl::pair< const T &, const T & > minmax(const T &a, const T &b)
Definition: algorithm.h:772
InputIterator find_if(InputIterator first, InputIterator last, Predicate predicate)
Definition: algorithm.h:1459
OutputIterator move(InputIterator first, InputIterator last, OutputIterator result)
Definition: copy_help.h:170
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last)
Definition: algorithm.h:962
OutputIterator transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation unaryOperation)
Definition: algorithm.h:1809
void reverse(BidirectionalIterator first, BidirectionalIterator last)
Definition: algorithm.h:2714
OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result)
Definition: algorithm.h:3624
OutputIterator remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate predicate)
Definition: algorithm.h:2542
ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, Predicate predicate)
Definition: algorithm.h:2618
ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T &value)
Definition: algorithm.h:2195
void iter_swap(ForwardIterator1 a, ForwardIterator2 b)
Definition: utility.h:237
ForwardIterator max_element(ForwardIterator first, ForwardIterator last)
Definition: algorithm.h:368
ForwardIterator1 find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2)
Definition: algorithm.h:1510
OutputIterator replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate predicate, const T &new_value)
Definition: algorithm.h:2672
void shuffle(RandomAccessIterator first, RandomAccessIterator last, UniformRandomNumberGenerator &&urng)
Definition: algorithm.h:1028
ForwardIterator binary_search_i(ForwardIterator first, ForwardIterator last, const T &value)
Definition: algorithm.h:3056
OutputIterator reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result)
Definition: algorithm.h:2740
EA_CPP14_CONSTEXPR bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
Definition: algorithm.h:1856
void generate(ForwardIterator first, ForwardIterator last, Generator generator)
Definition: algorithm.h:1766
void set_difference_2(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result1, OutputIterator result2, Compare compare)
Definition: algorithm.h:3413
EA_CPP14_CONSTEXPR InputIterator for_each_n(InputIterator first, Size n, Function function)
Definition: algorithm.h:1748
EA_CONSTEXPR eastl::enable_if< eastl::is_scalar< T >::value, T >::type max_alt(T a, T b)
Definition: algorithm.h:584
EA_CONSTEXPR const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
Definition: algorithm.h:4187
bool none_of(InputIterator first, InputIterator last, Predicate p)
Definition: algorithm.h:941
ForwardIterator unique(ForwardIterator first, ForwardIterator last)
Definition: algorithm.h:3109
void replace(ForwardIterator first, ForwardIterator last, const T &old_value, const T &new_value)
Definition: algorithm.h:2468
InputIterator find_if_not(InputIterator first, InputIterator last, Predicate predicate)
Definition: algorithm.h:1475
bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2)
Definition: algorithm.h:3749
ForwardIterator1 find_first_not_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2)
Definition: algorithm.h:1575
eastl::pair< InputIterator1, InputIterator2 > mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
Definition: algorithm.h:2132
EA_CPP14_CONSTEXPR pair< typename eastl::remove_reference_wrapper< typename eastl::decay< T1 >::type >::type, typename eastl::remove_reference_wrapper< typename eastl::decay< T2 >::type >::type > make_pair(T1 &&a, T2 &&b)
Definition: utility.h:694
OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result)
Definition: algorithm.h:3471
ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2)
Definition: algorithm.h:3231
bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2)
Definition: algorithm.h:1996
T min(std::initializer_list< T > ilist)
Definition: algorithm.h:635
BidirectionalIterator2 move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 resultEnd)
Definition: algorithm.h:1304
OutputIterator move_n_impl(InputIterator first, Size n, OutputIterator result, EASTL_ITC_NS::input_iterator_tag)
Definition: algorithm.h:1108
OutputIterator copy_n_impl(InputIterator first, Size n, OutputIterator result, EASTL_ITC_NS::input_iterator_tag)
Definition: algorithm.h:1142
Function for_each(InputIterator first, InputIterator last, Function function)
Definition: algorithm.h:1723
ForwardIterator min_element(ForwardIterator first, ForwardIterator last)
Definition: algorithm.h:304
ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2)
Definition: algorithm.h:2765
ForwardIterator search_n(ForwardIterator first, ForwardIterator last, Size count, const T &value)
Definition: algorithm.h:2988
bool any_of(InputIterator first, InputIterator last, Predicate p)
Definition: algorithm.h:925
EA_CONSTEXPR eastl::enable_if< eastl::is_scalar< T >::value, T >::type min_alt(T a, T b)
Definition: algorithm.h:472
OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result)
Definition: algorithm.h:3551
BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 resultEnd)
Definition: algorithm.h:1325
const T & median(const T &a, const T &b, const T &c)
Definition: algorithm.h:833
OutputIterator generate_n(OutputIterator first, Size n, Generator generator)
Definition: algorithm.h:1783
Definition: algorithm.h:3985
Definition: iterator.h:76
Definition: type_traits.h:442
Definition: iterator.h:75
Definition: iterator.h:583
Definition: type_pod.h:102
Definition: type_compound.h:258
Definition: type_traits.h:604
Definition: type_compound.h:562
Definition: type_pod.h:708
less<T>
Definition: functional_base.h:202
Definition: algorithm.h:1190
Definition: utility.h:371
Definition: iterator.h:77