Re: помогите изменить чужой код
От: Chorkov Россия  
Дата: 10.10.17 15:49
Оценка: 10 (2) +1
Здравствуйте, niXman, Вы писали:

X>снова драсте.


X>нагуглил на SO такой код, сортирующий интегралы в компайтайм, и пытаюсь переделать его для std::pair (value->position), чтоб сортировалось по first, но что-то как-то все непросто %)


X>помогите, плиз, у кого желание есть.


X>т.е. использовать предполагается так:

X>
X>SortMyElements<5> se({1,0},{4,1},{2,2},{5,3},{3,4});

X>// test
X>assert(se.data[0].first == 1 && se.data[0].second == 0);
X>assert(se.data[1].first == 2 && se.data[1].second == 2);
X>assert(se.data[2].first == 3 && se.data[2].second == 4);
X>assert(se.data[3].first == 4 && se.data[3].second == 1);
X>assert(se.data[4].first == 5 && se.data[4].second == 3);
X>



X>спасибо)


Поправить просто, :
  исправленное
#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, "");


Только стоит ли такой код отправлять в продакшен, если даже ты не разобрался?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.