Skip to content

Instantly share code, notes, and snippets.

@spott
Forked from albeva/gist:2975962
Created June 23, 2012 02:00
Show Gist options
  • Save spott/2976226 to your computer and use it in GitHub Desktop.
Save spott/2976226 to your computer and use it in GitHub Desktop.
C++11 variadic template based tuple sort
#include <iostream>
#include <utility>
#include <tuple>
using namespace std;
//
// forward declare
//
template<int N1, int N2, int LAST, typename T>
inline typename std::enable_if<N1 + 1 == LAST && N2 == LAST, void>::type
order_helper(T && t);
template<int N1, int N2, int LAST, typename T>
inline typename std::enable_if<N1 + 1 == LAST && N2 < LAST, void>::type
order_helper(T && t);
template<int N1, int N2, int LAST, typename T>
inline typename std::enable_if<N1 + 1 < LAST && N2 == LAST, void>::type
order_helper(T && t);
template<int N1, int N2, int LAST, typename T>
inline typename std::enable_if<N1 + 1 < LAST && N2 < LAST, void>::type
order_helper(T && t);
//
// N + 1 = last, N2 = last
//
template<int N1, int N2, int LAST, typename T>
inline typename std::enable_if<N1 + 1 == LAST && N2 == LAST, void>::type
order_helper(T && t)
{
if (get<N1>(t) > get<N2>(t)) swap(get<N1>(t), get<N2>(t));
}
//
// N + 1 = last, N2 < last
//
template<int N1, int N2, int LAST, typename T>
inline typename std::enable_if<N1 + 1 == LAST && N2 < LAST, void>::type
order_helper(T && t)
{
if (get<N1>(t) > get<N2>(t)) swap(get<N1>(t), get<N2>(t));
order_helper<N1, N2 + 1, LAST>(t);
}
//
// N1 + 1 < last, N2 = last
//
template<int N1, int N2, int LAST, typename T>
inline typename std::enable_if<N1 + 1 < LAST && N2 == LAST, void>::type
order_helper(T && t)
{
if (get<N1>(t) > get<N2>(t)) swap(get<N1>(t), get<N2>(t));
order_helper<N1 + 1, N1 + 2, LAST>(t);
}
//
// N1 + 1 < last, N1 < last
//
template<int N1, int N2, int LAST, typename T>
inline typename std::enable_if<N1 + 1 < LAST && N2 < LAST, void>::type
order_helper(T && t)
{
if (get<N1>(t) > get<N2>(t)) swap(get<N1>(t), get<N2>(t));
order_helper<N1, N2 + 1, LAST>(t);
}
template<typename A, typename B>
tuple<A, B> order(A && a, B && b)
{
if (a > b) return make_tuple(b, a);
return make_tuple(a, b);
}
template<typename A, typename B, typename... Rest>
tuple<A, B, Rest...> order(A && a, B && b, Rest&&... rest)
{
auto t = make_tuple(a, b, rest...);
constexpr auto LAST = tuple_size<decltype(t)>::value - 1;
order_helper<0, 1, LAST>(t);
return t;
}
int main(int argc, const char * argv[])
{
int a, b, c, d, e;
tie(a, b, c, d, e) = order(4, 3, 2, 1, 8);
cout << "a = " << a << '\n'
<< "b = " << b << '\n'
<< "c = " << c << '\n'
<< "d = " << d << '\n'
<< "e = " << e << '\n';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment