| #include <cstring>
#include <cassert>
#include <utility>
template<int...>
struct IntHolder {};
// Now let's make a consecutive range of ints from [A to B).
template<int A, int B, int... Accum>
struct IntRange_ : IntRange_<A+1, B, Accum..., A> {};
template<int A, int... Accum>
struct IntRange_<A, A, Accum...> {
using type = IntHolder<Accum...>;
};
template<int A, int B>
using IntRange = typename IntRange_<A,B>::type;
// And a helper function to do what std::min should be doing for us.
template<typename... TT> constexpr int min(TT...);
template<typename T> constexpr T min(T i) { return i; }
template<typename T, typename... TT> constexpr T min(T i, TT... tt) { return i < min(tt...) ? i : min(tt...); }
template<typename T, int N>
struct SortMyElements {
T data[N];
template<int... II, typename... TT>
constexpr SortMyElements(IntHolder<II...> ii, T minval, T a, TT... tt)
:data{
( a==minval ? a : SortMyElements<T,N>(ii, minval, tt..., a).data[0] ),
( a==minval ? SortMyElements<T,N-1>(tt...).data[II] : SortMyElements<T,N>(ii, minval, tt..., a).data[II+1] )...
}
{}
template<typename... TT>
constexpr SortMyElements(TT... tt)
:SortMyElements(IntRange<0,sizeof...(tt)-1>(), min(tt...), tt...)
{}
};
template<typename T>
struct SortMyElements<T,1> {
T data[1];
constexpr SortMyElements(T x)
:data{x}
{}
constexpr SortMyElements(IntHolder<>, T minval, T x)
:SortMyElements(x)
{}
};
constexpr auto gsorted = SortMyElements<int,5>(5,2,1,3,1);
static_assert(gsorted.data[0] == 1, "");
static_assert(gsorted.data[1] == 1, "");
static_assert(gsorted.data[2] == 2, "");
static_assert(gsorted.data[3] == 3, "");
static_assert(gsorted.data[4] == 5, "");
enum { gval = SortMyElements<int,5>(1,4,2,5,3).data[2] };
static_assert(gval == 3, "");
typedef std::pair<int,int> t_pair;
constexpr auto gsorted_2 = SortMyElements< t_pair ,5>(t_pair{5,1},t_pair{2,2},t_pair{1,3},t_pair{3,4},t_pair{1,5});
static_assert(gsorted_2.data[0].first == 1, "");
static_assert(gsorted_2.data[1].first == 1, "");
static_assert(gsorted_2.data[2].first == 2, "");
static_assert(gsorted_2.data[3].first == 3, "");
static_assert(gsorted_2.data[4].first == 5, "");
static_assert(gsorted_2.data[0].second == 3, "");
static_assert(gsorted_2.data[1].second == 5, "");
static_assert(gsorted_2.data[2].second == 2, "");
static_assert(gsorted_2.data[3].second == 4, "");
static_assert(gsorted_2.data[4].second == 1, "");
|