lemon/radix_sort.h
author deba
Wed, 01 Mar 2006 10:25:30 +0000
changeset 1991 d7442141d9ef
parent 1956 a055123339d5
child 2033 7bf1f64962c2
permissions -rw-r--r--
The graph adadptors can be alteration observed.
In most cases it uses the adapted graph alteration notifiers.
Only special case is now the UndirGraphAdaptor, where
we have to proxy the signals from the graph.

The SubBidirGraphAdaptor is removed, because it doest not
gives more feature than the EdgeSubGraphAdaptor<UndirGraphAdaptor<Graph>>.

The ResGraphAdaptor is based on this composition.
deba@1833
     1
/* -*- C++ -*-
deba@1833
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@1956
     5
 * Copyright (C) 2003-2006
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@1833
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@1833
     8
 *
deba@1833
     9
 * Permission to use, modify and distribute this software is granted
deba@1833
    10
 * provided that this copyright notice appears in all copies. For
deba@1833
    11
 * precise terms see the accompanying LICENSE file.
deba@1833
    12
 *
deba@1833
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@1833
    14
 * express or implied, and with no claim as to its suitability for any
deba@1833
    15
 * purpose.
deba@1833
    16
 *
deba@1833
    17
 */
deba@1833
    18
deba@1833
    19
#ifndef RADIX_SORT_H
deba@1833
    20
#define RADIX_SORT_H
deba@1833
    21
deba@1833
    22
/// \ingroup auxdat
deba@1833
    23
/// \file
deba@1833
    24
/// \brief Radix sort
deba@1833
    25
///
deba@1833
    26
deba@1833
    27
#include <vector>
deba@1833
    28
#include <limits>
deba@1833
    29
#include <iterator>
deba@1833
    30
#include <algorithm>
deba@1833
    31
deba@1833
    32
#include <lemon/error.h>
deba@1833
    33
deba@1833
    34
namespace lemon {
deba@1833
    35
deba@1833
    36
  namespace _radix_sort_bits {
deba@1833
    37
deba@1833
    38
    template <typename Value>
deba@1833
    39
    struct Identity {
deba@1833
    40
      const Value& operator()(const Value& val) {
deba@1833
    41
	return val;
deba@1833
    42
      }
deba@1833
    43
    };
deba@1833
    44
deba@1833
    45
  }
deba@1833
    46
deba@1833
    47
  template <typename Value, typename Iterator, typename Functor>
deba@1833
    48
  Iterator radixSortPartition(Iterator first, Iterator last, 
deba@1833
    49
			      Functor functor, Value mask) {
deba@1833
    50
    while (first != last && !(functor(*first) & mask)) {
deba@1833
    51
      ++first;
deba@1833
    52
    }
deba@1833
    53
    if (first == last) {
deba@1833
    54
      return first;
deba@1833
    55
    }
deba@1833
    56
    --last;
deba@1833
    57
    while (first != last && (functor(*last) & mask)) {
deba@1833
    58
      --last;
deba@1833
    59
    }
deba@1833
    60
    if (first == last) {
deba@1833
    61
      return first;
deba@1833
    62
    }
deba@1833
    63
    std::iter_swap(first, last);
deba@1833
    64
    ++first;
deba@1833
    65
    if (!(first < last)) {
deba@1833
    66
      return first;
deba@1833
    67
    }
deba@1833
    68
    while (true) {
deba@1833
    69
      while (!(functor(*first) & mask)) {
deba@1833
    70
	++first;
deba@1833
    71
      }
deba@1833
    72
      --last;
deba@1833
    73
      while (functor(*last) & mask) {
deba@1833
    74
	--last;
deba@1833
    75
      }
deba@1833
    76
      if (!(first < last)) {
deba@1833
    77
	return first;
deba@1833
    78
      }
deba@1833
    79
      std::iter_swap(first, last);
deba@1833
    80
      ++first;
deba@1833
    81
    }
deba@1833
    82
  }
deba@1833
    83
deba@1833
    84
  template <typename Iterator, typename Functor>
deba@1833
    85
  Iterator radixSortSignPartition(Iterator first, Iterator last, 
deba@1833
    86
				  Functor functor) {
deba@1833
    87
    while (first != last && functor(*first) < 0) {
deba@1833
    88
      ++first;
deba@1833
    89
    }
deba@1833
    90
    if (first == last) {
deba@1833
    91
      return first;
deba@1833
    92
    }
deba@1833
    93
    --last;
deba@1833
    94
    while (first != last && functor(*last) >= 0) {
deba@1833
    95
      --last;
deba@1833
    96
    }
deba@1833
    97
    if (first == last) {
deba@1833
    98
      return first;
deba@1833
    99
    }
deba@1833
   100
    std::iter_swap(first, last);
deba@1833
   101
    ++first;
deba@1833
   102
    if (!(first < last)) {
deba@1833
   103
      return first;
deba@1833
   104
    }
deba@1833
   105
    while (true) {
deba@1833
   106
      while (functor(*first) < 0) {
deba@1833
   107
	++first;
deba@1833
   108
      }
deba@1833
   109
      --last;
deba@1833
   110
      while (functor(*last) >= 0) {
deba@1833
   111
	--last;
deba@1833
   112
      }
deba@1833
   113
      if (!(first < last)) {
deba@1833
   114
	return first;
deba@1833
   115
      }
deba@1833
   116
      std::iter_swap(first, last);
deba@1833
   117
      ++first;
deba@1833
   118
    }
deba@1833
   119
  }
deba@1833
   120
deba@1833
   121
  template <typename Value, typename Iterator, typename Functor>
deba@1833
   122
  void radixIntroSort(Iterator first, Iterator last, 
deba@1833
   123
		      Functor functor, Value mask) {
deba@1833
   124
    while (mask != 0 && last - first > 1) {
deba@1833
   125
      Iterator cut = radixSortPartition(first, last, functor, mask);
deba@1833
   126
      mask >>= 1;
deba@1833
   127
      radixIntroSort(first, cut, functor, mask);
deba@1833
   128
      first = cut;
deba@1833
   129
    }
deba@1833
   130
  }
deba@1833
   131
deba@1833
   132
  template <typename Value, typename Iterator, typename Functor>
deba@1833
   133
  void radixSignedSort(Iterator first, Iterator last, Functor functor) {
deba@1833
   134
    Iterator cut = radixSortSignPartition(first, last, functor);
deba@1833
   135
deba@1833
   136
    Value mask;
deba@1833
   137
    int max_digit;
deba@1833
   138
    Iterator it;
deba@1833
   139
deba@1833
   140
    mask = 0; max_digit = 0;
deba@1833
   141
    for (it = first; it != cut; ++it) {
deba@1833
   142
      if ((mask | functor(*it)) != ~0) {
deba@1833
   143
	++max_digit;
deba@1833
   144
	mask <<= 1; 
deba@1833
   145
	mask |= 1;
deba@1833
   146
      }
deba@1833
   147
    }
deba@1833
   148
    radixIntroSort(first, cut, functor, 1 << max_digit);
deba@1833
   149
deba@1833
   150
    mask = ~0; max_digit = 0;
deba@1833
   151
    for (it = cut; it != last; ++it) {
deba@1833
   152
      if (mask & functor(*it)) {
deba@1833
   153
	++max_digit;
deba@1833
   154
	mask <<= 1;
deba@1833
   155
      }
deba@1833
   156
    }
deba@1833
   157
    radixIntroSort(cut, last, functor, 1 << max_digit);
deba@1833
   158
  }
deba@1833
   159
deba@1833
   160
  template <typename Value, typename Iterator, typename Functor>
deba@1833
   161
  void radixUnsignedSort(Iterator first, Iterator last, Functor functor) {
deba@1833
   162
deba@1833
   163
    Value mask = ~0;
deba@1833
   164
    int max_digit = 0;
deba@1833
   165
deba@1833
   166
    Iterator it;
deba@1833
   167
    for (it = first; it != last; ++it) {
deba@1833
   168
      if (mask & functor(*it)) {
deba@1833
   169
	++max_digit;
deba@1833
   170
	mask <<= 1;
deba@1833
   171
      }
deba@1833
   172
    }
deba@1833
   173
    radixIntroSort(first, last, functor, 1 << max_digit);
deba@1833
   174
  }
deba@1833
   175
deba@1833
   176
  namespace _radix_sort_bits {
deba@1833
   177
deba@1833
   178
    template <typename Value, 
deba@1833
   179
	      bool sign = std::numeric_limits<Value>::is_signed >
deba@1833
   180
    struct RadixSortSelector {
deba@1833
   181
      template <typename Iterator, typename Functor>
deba@1833
   182
      static void sort(Iterator first, Iterator last, Functor functor) {
deba@1833
   183
	radixSignedSort<Value>(first, last, functor);
deba@1833
   184
      }
deba@1833
   185
    };
deba@1833
   186
deba@1833
   187
    template <typename Value>
deba@1833
   188
    struct RadixSortSelector<Value, false> {
deba@1833
   189
      template <typename Iterator, typename Functor>
deba@1833
   190
      static void sort(Iterator first, Iterator last, Functor functor) {
deba@1833
   191
	radixUnsignedSort<Value>(first, last, functor);
deba@1833
   192
      }
deba@1833
   193
    };
deba@1833
   194
deba@1833
   195
  }
deba@1833
   196
deba@1833
   197
  /// \ingroup auxdat
deba@1833
   198
  ///
deba@1833
   199
  /// \brief Sorts the stl compatible range into ascending order.
deba@1833
   200
  ///
deba@1833
   201
  /// The \c radixSort sorts the stl compatible range into ascending order.
deba@1833
   202
  /// The radix sort algorithm can sort the items which mapped to an
deba@1833
   203
  /// integer by the adaptable unary function \c functor and the order
deba@1833
   204
  /// will be ascending by these mapped values. As function specialization
deba@1833
   205
  /// there is possible to use a normal function as the functor object
deba@1833
   206
  /// or if the functor is not given it will use an identity function instead.
deba@1833
   207
  ///
deba@1833
   208
  /// This implemented radix sort is a special quick sort which pivot value
deba@1833
   209
  /// is choosen to partite the items on the next bit. This way, let be
deba@1833
   210
  /// \c c the maximal capacity and \c n the number of the items in
deba@1833
   211
  /// the container, the time complexity of the algorithm \c O(log(c)*n)
deba@1833
   212
  /// and the additional space complexity is \c O(log(c)).
deba@1833
   213
  ///
deba@1833
   214
  /// \param first The begin of the given range.
deba@1833
   215
  /// \param last The end of the given range.
deba@1833
   216
  /// \param functor An adaptible unary function or a normal function which
deba@1833
   217
  /// maps the items to any integer type which can be wheter signed or 
deba@1833
   218
  /// unsigned.
deba@1833
   219
  template <typename Iterator, typename Functor>
deba@1833
   220
  void radixSort(Iterator first, Iterator last, Functor functor) {
deba@1833
   221
    using namespace _radix_sort_bits;
deba@1833
   222
    typedef typename Functor::result_type Value;
deba@1833
   223
    RadixSortSelector<Value>::sort(first, last, functor);
deba@1833
   224
  }
deba@1833
   225
deba@1833
   226
  template <typename Iterator, typename Value, typename Key>
deba@1833
   227
  void radixSort(Iterator first, Iterator last, Value (*functor)(Key)) {
deba@1833
   228
    using namespace _radix_sort_bits;
deba@1833
   229
    RadixSortSelector<Value>::sort(first, last, functor);
deba@1833
   230
  }
deba@1833
   231
deba@1833
   232
  template <typename Iterator, typename Value, typename Key>
deba@1833
   233
  void radixSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
deba@1833
   234
    using namespace _radix_sort_bits;
deba@1833
   235
    RadixSortSelector<Value>::sort(first, last, functor);
deba@1833
   236
  }
deba@1833
   237
deba@1833
   238
  template <typename Iterator, typename Value, typename Key>
deba@1833
   239
  void radixSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
deba@1833
   240
    using namespace _radix_sort_bits;
deba@1833
   241
    RadixSortSelector<Value>::sort(first, last, functor);
deba@1833
   242
  }
deba@1833
   243
deba@1833
   244
  template <typename Iterator, typename Value, typename Key>
deba@1833
   245
  void radixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
deba@1833
   246
    using namespace _radix_sort_bits;
deba@1833
   247
    RadixSortSelector<Value>::sort(first, last, functor);
deba@1833
   248
  }
deba@1833
   249
deba@1833
   250
  template <typename Iterator>
deba@1833
   251
  void radixSort(Iterator first, Iterator last) {
deba@1833
   252
    using namespace _radix_sort_bits;
deba@1833
   253
    typedef typename std::iterator_traits<Iterator>::value_type Value;
deba@1833
   254
    RadixSortSelector<Value>::sort(first, last, Identity<Value>());
deba@1833
   255
  }
deba@1833
   256
deba@1833
   257
  template <typename Value>
deba@1833
   258
  unsigned char valueByte(Value value, int byte) {
deba@1844
   259
    return value >> (std::numeric_limits<unsigned char>::digits * byte);
deba@1833
   260
  }
deba@1833
   261
deba@1833
   262
  template <typename Functor, typename Key>
deba@1833
   263
  void counterIntroSort(Key *first, Key *last, Key *target, 
deba@1833
   264
		       int byte, Functor functor) {
deba@1833
   265
    const int size = 
deba@1833
   266
      (unsigned int)std::numeric_limits<unsigned char>::max() + 1;
deba@1979
   267
    std::vector<int> counter(size);
deba@1833
   268
    for (int i = 0; i < size; ++i) {
deba@1833
   269
      counter[i] = 0;
deba@1833
   270
    }
deba@1833
   271
    Key *it = first;
deba@1833
   272
    while (first != last) {
deba@1833
   273
      ++counter[valueByte(functor(*first), byte)]; 
deba@1833
   274
      ++first;
deba@1833
   275
    }
deba@1833
   276
    int prev, num = 0;
deba@1833
   277
    for (int i = 0; i < size; ++i) {
deba@1833
   278
      prev = num;
deba@1833
   279
      num += counter[i];
deba@1833
   280
      counter[i] = prev;
deba@1833
   281
    }
deba@1833
   282
    while (it != last) {
deba@1833
   283
      target[counter[valueByte(functor(*it), byte)]++] = *it;
deba@1833
   284
      ++it;
deba@1833
   285
    }
deba@1833
   286
  }
deba@1833
   287
deba@1833
   288
  template <typename Functor, typename Key>
deba@1833
   289
  void signedCounterIntroSort(Key *first, Key *last, Key *target, 
deba@1833
   290
			     int byte, Functor functor) {
deba@1833
   291
    const int size = 
deba@1833
   292
      (unsigned int)std::numeric_limits<unsigned char>::max() + 1;
deba@1979
   293
    std::vector<int> counter(size);
deba@1833
   294
    for (int i = 0; i < size; ++i) {
deba@1833
   295
      counter[i] = 0;
deba@1833
   296
    }
deba@1833
   297
    Key *it = first;
deba@1833
   298
    while (first != last) {
deba@1833
   299
      counter[valueByte(functor(*first), byte)]++;
deba@1833
   300
      ++first;
deba@1833
   301
    }
deba@1833
   302
    int prev, num = 0;
deba@1833
   303
    for (int i = size / 2; i < size; ++i) {
deba@1833
   304
      prev = num;
deba@1833
   305
      num += counter[i];
deba@1833
   306
      counter[i] = prev;
deba@1833
   307
    }
deba@1833
   308
    for (int i = 0; i < size / 2; ++i) {
deba@1833
   309
      prev = num;
deba@1833
   310
      num += counter[i];
deba@1833
   311
      counter[i] = prev;
deba@1833
   312
    }
deba@1833
   313
    while (it != last) {
deba@1833
   314
      target[counter[valueByte(functor(*it), byte)]++] = *it;
deba@1833
   315
      ++it;
deba@1833
   316
    }
deba@1833
   317
  }
deba@1833
   318
deba@1833
   319
  
deba@1833
   320
  template <typename Value, typename Iterator, typename Functor>
deba@1833
   321
  void counterSignedSort(Iterator first, Iterator last, Functor functor) {
deba@1904
   322
    if (first == last) return;
deba@1833
   323
    typedef typename std::iterator_traits<Iterator>::value_type Key;
deba@1833
   324
    typedef std::allocator<Key> Allocator;
deba@1833
   325
    Allocator allocator;
deba@1833
   326
deba@1833
   327
    int length = std::distance(first, last);
deba@1833
   328
    Key* buffer;
deba@1833
   329
    buffer = allocator.allocate(2 * length);
deba@1833
   330
    try {
deba@1833
   331
      bool dir = true;
deba@1833
   332
      std::copy(first, last, buffer);
deba@1833
   333
      for (int i = 0; i < (int)sizeof(Value) - 1; ++i) {
deba@1833
   334
	if (dir) {
deba@1833
   335
	  counterIntroSort(buffer, buffer + length, buffer + length, 
deba@1833
   336
			   i, functor);
deba@1833
   337
	} else {
deba@1833
   338
	  counterIntroSort(buffer + length, buffer + 2 * length, buffer, 
deba@1833
   339
			   i, functor);
deba@1833
   340
	}
deba@1833
   341
	dir = !dir;
deba@1833
   342
      }
deba@1833
   343
      if (dir) {
deba@1833
   344
	signedCounterIntroSort(buffer, buffer + length, buffer + length, 
deba@1833
   345
			       sizeof(Value) - 1, functor);
deba@1833
   346
	std::copy(buffer + length, buffer + 2 * length, first);
deba@1833
   347
      }	else {
deba@1833
   348
	signedCounterIntroSort(buffer + length, buffer + 2 * length, buffer, 
deba@1833
   349
			       sizeof(Value) - 1, functor);
deba@1833
   350
	std::copy(buffer, buffer + length, first);
deba@1833
   351
      }
deba@1833
   352
    } catch (...) {
deba@1833
   353
      allocator.deallocate(buffer, 2 * length);
deba@1833
   354
      throw;
deba@1833
   355
    }
deba@1833
   356
    allocator.deallocate(buffer, 2 * length);
deba@1833
   357
  }
deba@1833
   358
deba@1833
   359
  template <typename Value, typename Iterator, typename Functor>
deba@1833
   360
  void counterUnsignedSort(Iterator first, Iterator last, Functor functor) {
deba@1904
   361
    if (first == last) return;
deba@1833
   362
    typedef typename std::iterator_traits<Iterator>::value_type Key;
deba@1833
   363
    typedef std::allocator<Key> Allocator;
deba@1833
   364
    Allocator allocator;
deba@1833
   365
deba@1833
   366
    int length = std::distance(first, last);
deba@1833
   367
    Key *buffer;
deba@1833
   368
    buffer = allocator.allocate(2 * length);
deba@1833
   369
    try {
deba@1833
   370
      bool dir = true;
deba@1833
   371
      std::copy(first, last, buffer);
deba@1844
   372
      for (int i = 0; i < (int)sizeof(Value); ++i) {
deba@1833
   373
	if (dir) {
deba@1844
   374
	  counterIntroSort(buffer, buffer + length, buffer + length, i, functor);
deba@1833
   375
	} else {
deba@1844
   376
	  counterIntroSort(buffer + length, buffer + 2 * length, buffer, i, functor);
deba@1833
   377
	}
deba@1833
   378
	dir = !dir;
deba@1833
   379
      }
deba@1833
   380
      if (dir) {
deba@1833
   381
	std::copy(buffer, buffer + length, first);
deba@1833
   382
      }	else {
deba@1833
   383
	std::copy(buffer + length, buffer + 2 * length, first);
deba@1833
   384
      }
deba@1833
   385
    } catch (...) {
deba@1833
   386
      allocator.deallocate(buffer, 2 * length);
deba@1833
   387
      throw;
deba@1833
   388
    }
deba@1833
   389
    allocator.deallocate(buffer, 2 * length);
deba@1833
   390
  }
deba@1833
   391
deba@1833
   392
  namespace _radix_sort_bits {
deba@1833
   393
deba@1833
   394
    template <typename Value, 
deba@1833
   395
	      bool sign = std::numeric_limits<Value>::is_signed >
deba@1833
   396
    struct CounterSortSelector {
deba@1833
   397
      template <typename Iterator, typename Functor>
deba@1833
   398
      static void sort(Iterator first, Iterator last, Functor functor) {
deba@1833
   399
	counterSignedSort<Value>(first, last, functor);
deba@1833
   400
      }
deba@1833
   401
    };
deba@1833
   402
deba@1833
   403
    template <typename Value>
deba@1833
   404
    struct CounterSortSelector<Value, false> {
deba@1833
   405
      template <typename Iterator, typename Functor>
deba@1833
   406
      static void sort(Iterator first, Iterator last, Functor functor) {
deba@1833
   407
	counterUnsignedSort<Value>(first, last, functor);
deba@1833
   408
      }
deba@1833
   409
    };
deba@1833
   410
deba@1833
   411
  }
deba@1833
   412
deba@1833
   413
  /// \ingroup auxdat
deba@1833
   414
  ///
deba@1833
   415
  /// \brief Sorts stable the stl compatible range into ascending order.
deba@1833
   416
  ///
deba@1833
   417
  /// The \c counterSort sorts the stl compatible range into ascending order.
deba@1833
   418
  /// The counter sort algorithm can sort the items which mapped to an
deba@1833
   419
  /// integer by the adaptable unary function \c functor and the order
deba@1833
   420
  /// will be ascending by these mapped values. As function specialization
deba@1833
   421
  /// there is possible to use a normal function as the functor object
deba@1833
   422
  /// or if the functor is not given it will use an identity function instead.
deba@1833
   423
  ///
deba@1833
   424
  /// This implemented counter sort use a radix forward sort on the bytes of
deba@1833
   425
  /// the integer. The algorithm can sort the items on a given byte. 
deba@1833
   426
  /// First time it counts how many times occurs a byte value in the container.
deba@1833
   427
  /// By the occurence number it is possible to copy the container
deba@1833
   428
  /// in the right order in \c O(n) time. The algorithm sorts the container
deba@1833
   429
  /// by each bytes in forward direction which sorts the container by the
deba@1844
   430
  /// whole value. This way, let be \c c the maximal capacity of the integer 
deba@1844
   431
  /// type and \c n the number of the items in
deba@1833
   432
  /// the container, the time complexity of the algorithm \c O(log(c)*n)
deba@1833
   433
  /// and the additional space complexity is \c O(n).
deba@1833
   434
  ///
deba@1833
   435
  /// This sorting algorithm is stable so the order of two equal element
deba@1833
   436
  /// stay in the same order.
deba@1833
   437
  ///
deba@1833
   438
  /// \param first The begin of the given range.
deba@1833
   439
  /// \param last The end of the given range.
deba@1833
   440
  /// \param functor An adaptible unary function or a normal function which
deba@1833
   441
  /// maps the items to any integer type which can be wheter signed or 
deba@1833
   442
  /// unsigned.
deba@1833
   443
  template <typename Iterator, typename Functor>
deba@1833
   444
  void counterSort(Iterator first, Iterator last, Functor functor) {
deba@1833
   445
    using namespace _radix_sort_bits;
deba@1833
   446
    typedef typename Functor::result_type Value;
deba@1833
   447
    CounterSortSelector<Value>::sort(first, last, functor);
deba@1833
   448
  }
deba@1833
   449
deba@1833
   450
  template <typename Iterator, typename Value, typename Key>
deba@1833
   451
  void counterSort(Iterator first, Iterator last, Value (*functor)(Key)) {
deba@1833
   452
    using namespace _radix_sort_bits;
deba@1833
   453
    CounterSortSelector<Value>::sort(first, last, functor);
deba@1833
   454
  }
deba@1833
   455
deba@1833
   456
  template <typename Iterator, typename Value, typename Key>
deba@1833
   457
  void counterSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
deba@1833
   458
    using namespace _radix_sort_bits;
deba@1833
   459
    CounterSortSelector<Value>::sort(first, last, functor);
deba@1833
   460
  }
deba@1833
   461
deba@1833
   462
  template <typename Iterator, typename Value, typename Key>
deba@1833
   463
  void counterSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
deba@1833
   464
    using namespace _radix_sort_bits;
deba@1833
   465
    CounterSortSelector<Value>::sort(first, last, functor);
deba@1833
   466
  }
deba@1833
   467
deba@1833
   468
  template <typename Iterator, typename Value, typename Key>
deba@1833
   469
  void counterSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
deba@1833
   470
    using namespace _radix_sort_bits;
deba@1833
   471
    CounterSortSelector<Value>::sort(first, last, functor);
deba@1833
   472
  }
deba@1833
   473
deba@1833
   474
  template <typename Iterator>
deba@1833
   475
  void counterSort(Iterator first, Iterator last) {
deba@1833
   476
    using namespace _radix_sort_bits;
deba@1833
   477
    typedef typename std::iterator_traits<Iterator>::value_type Value;
deba@1833
   478
    CounterSortSelector<Value>::sort(first, last, Identity<Value>());
deba@1833
   479
  }
deba@1833
   480
deba@1833
   481
}
deba@1833
   482
deba@1833
   483
deba@1833
   484
deba@1833
   485
#endif