I have the data structure:
template struct index {};
template struct data {};
template struct X
{
When you are facing something complex in C++ template programming, it mostly helps to try to break it into several smaller steps (like with most programming problems). Here is a possible path:
And here is the corresponding code. I am using std::conditional
, but that is easy to replace of course. I am using std::is_same
in the tests, you do not really need that of course (and it would be trivial to implement otherwise).
Your stuff + utility header for std::conditional and std::is_same
#include
template
struct index
{
};
template
struct data
{
};
template
struct X
{
static constexpr int i = I;
static constexpr int j = J;
};
typedef data, X<1, 2>, X<2, 1>, X<1, 6>, X<1, 3>> data_t;
Extract the X
s that match the I
we are looking for and replace the i
s with the position.
template
struct ExtractImpl;
template
struct ExtractImpl, data<>>
{
using type = data;
};
template
struct ExtractImpl, data>
{
using type = typename std::conditional<
(T::i == I),
typename ExtractImpl>,
data>::type,
typename ExtractImpl, data>::
type>::type;
};
template
struct Extract
{
using type = typename ExtractImpl<0, I, data<>, Data>::type;
};
using extracted = typename Extract<1, data_t>::type;
static_assert(std::is_same, X<3, 6>, X<4, 3>>>::value, "");
Sort by J. This is done by incrementally inserting elements into a sorted list. There might be more elegant ways to do it.
template
struct insert_impl;
template
struct insert_impl, data<>>
{
using type = data;
};
template
struct insert_impl, data>
{
using type = typename std::conditional<
(T::j < Next::j),
data,
typename insert_impl, data>::type>::
type;
};
template
struct insert
{
using type = typename insert_impl, SortedList>::type;
};
template
struct SortImpl;
template
struct SortImpl>
{
using type = SortedList;
};
template
struct SortImpl>
{
using type = typename SortImpl::type,
data>::type;
};
template
struct Sort
{
using type = typename SortImpl, UnsortedList>::type;
};
using sorted = typename Sort::type;
static_assert(std::is_same, X<4, 3>, X<3, 6>>>::value, "");
Finally, extract the indexes you are looking for:
template
struct Indexes;
template
struct Indexes>
{
using type = index;
};
using result = typename Indexes::type;
static_assert(std::is_same>::value, "");
Word of warning: While I don't see any problems in the code, I have not tested it beyond your example...