Overte C++ Documentation
Radix2InplaceSort.h
1 //
2 // Radix2InplaceSort.h
3 // libraries/shared/src
4 //
5 // Created by Tobias Schwinger on 3/22/13.
6 // Copyright 2013 High Fidelity, Inc.
7 //
8 // Distributed under the Apache License, Version 2.0.
9 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10 //
11 
12 #ifndef hifi_Radix2InplaceSort_h
13 #define hifi_Radix2InplaceSort_h
14 
15 #include <algorithm>
16 
17 
24 template< class Radix2Scanner, typename BidiIterator >
25 void radix2InplaceSort( BidiIterator from, BidiIterator to,
26  Radix2Scanner const& scanner = Radix2Scanner() );
27 
28 
29 
30 template< class Scanner, typename Iterator >
31 struct radix2InplaceSort_impl : Scanner {
32 
33  radix2InplaceSort_impl(Scanner const& s) : Scanner(s) { }
34 
35  using Scanner::advance;
36  using Scanner::bit;
37 
38  void go(Iterator& from, Iterator& to, typename Scanner::state_type s) {
39 
40  Iterator l(from), r(to);
41  unsigned cl, cr;
42 
43  using std::swap;
44 
45  while (true) {
46  // scan from left for set bit
47  for (cl = cr = 0u; l != r ; ++l, ++cl)
48  if (bit(*l, s)) {
49  // scan from the right for unset bit
50  for (++cr; --r != l ;++cr)
51  if (! bit(*r, s)) {
52  // swap, continue scanning from left
53  swap(*l, *r);
54  break;
55  }
56  if (l == r)
57  break;
58  }
59 
60  // on to the next digit, if any
61  if (! advance(s)) {
62  return;
63  }
64 
65  // recurse into smaller branch and prepare iterative
66  // processing of the other
67  if (cl < cr) {
68 
69  if (cl > 1u) go(from, l, s);
70  else if (cr <= 1u)
71  return;
72 
73  l = from = r;
74  r = to;
75 
76  } else {
77 
78  if (cr > 1u) go(r, to, s);
79  else if (cl <= 1u)
80  return;
81 
82  r = to = l;
83  l = from;
84  }
85  }
86  }
87 };
88 
89 template< class Radix2Scanner, typename BidiIterator >
90 void radix2InplaceSort( BidiIterator from, BidiIterator to,
91  Radix2Scanner const& scanner) {
92 
93  radix2InplaceSort_impl<Radix2Scanner, BidiIterator>(scanner)
94  .go(from, to, scanner.initial_state());
95 }
96 
97 #endif // hifi_Radix2InplaceSort_h