基数ソートでは、値が m 未満であるという制限も必要ありません。
以下の実装例は、int 型でテンプレート化されています。m が常に 2^15 未満である場合は、可能であれば int16_t のベクトルを使用する必要があります (符号付き整数を処理するためのオフセットを回避するために、値が常に正の場合は uint16_t を使用することをお勧めします)。これにより、32 ビット整数の場合は 4 つではなく、2 つのソート パスのみが必要になります。入力タイプを変更できない場合は、コードを特別なケースにして、2 つのパスのみを実行し、符号付きオフセットを回避できます。
この実装は O(n) であり、O(n) 余分なスペースを使用します (並べ替えは行われません)。
template<typename I>
void radix_sort(I first, I last) {
using namespace std;
typedef remove_reference_t<decltype(*first)> int_t;
typedef make_unsigned<int_t>::type uint_t;
const uint_t signedOffset = is_signed<int_t>::value ? uint_t(numeric_limits<int_t>::max()) + uint_t(1) : 0;
auto getDigit = [=](uint_t n, int power) -> size_t { return ((n + signedOffset) >> (power * 8)) & 0xff; };
array<size_t, 256> counts;
vector<int_t> sorted(distance(first, last));
for (int power = 0; power < sizeof(int_t); ++power) {
counts.fill(0);
for_each(first, last, [&](int_t i) { ++counts[getDigit(i, power)]; });
partial_sum(begin(counts), end(counts), begin(counts));
for_each(reverse_iterator<I>(last), reverse_iterator<I>(first), [&](int_t i) {
sorted[--counts[getDigit(i, power)]] = i;
});
copy(begin(sorted), end(sorted), first);
}
}