Skip to content

Instantly share code, notes, and snippets.

@christophercrouzet
Created April 26, 2015 02:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christophercrouzet/2d915020e24a189f4962 to your computer and use it in GitHub Desktop.
Save christophercrouzet/2d915020e24a189f4962 to your computer and use it in GitHub Desktop.
Compile-time multidimensional indices incrementer
#ifndef INCREMENTINDICES_H
#define INCREMENTINDICES_H
#include <cstddef>
#include <type_traits>
#include <m3ta/at>
#include <m3ta/concatenate>
#include <m3ta/integersequence>
#include <m3ta/popback>
namespace detail
{
template<std::size_t T_position, typename T_Indices, typename T_Shape>
struct Helper
{
private:
using index = m3ta::AtT<T_position, T_Indices>;
public:
using type = typename std::conditional<
index::value < m3ta::AtT<T_position, T_Shape>::value - 1,
m3ta::ConcatenateT<
m3ta::PopBackT<T_Shape::size() - T_position, T_Indices>,
m3ta::IndexSequence<index::value + 1>
>,
m3ta::ConcatenateT<
typename Helper<T_position - 1, T_Indices, T_Shape>::type,
m3ta::IndexSequence<0>
>
>::type;
};
template<typename T_Indices, typename T_Shape>
struct Helper<0, T_Indices, T_Shape>
{
private:
using index = m3ta::AtT<0, T_Indices>;
public:
using type = m3ta::IndexSequence<index::value + 1>;
};
} // namespace detail.
template<typename T_Indices, typename T_Shape>
struct IncrementIndices
{
static_assert(T_Indices::size() == T_Shape::size(), "Not good!");
using type = typename detail::Helper<
T_Shape::size() - 1, T_Indices, T_Shape
>::type;
};
#endif // INCREMENTINDICES_H
#include <cstddef>
#include <iostream>
#include <type_traits>
#include <m3ta/integersequence>
#include "incrementindices.h"
template<typename T_Indices>
struct PrintIntegerSequence;
template<typename T, T T_first, T ... T_others>
struct PrintIntegerSequence<m3ta::IntegerSequence<T, T_first, T_others ...>>
{
static void run()
{
std::cout << T_first << " ";
PrintIntegerSequence<m3ta::IntegerSequence<T, T_others ...>>::run();
}
};
template<typename T>
struct PrintIntegerSequence<m3ta::IntegerSequence<T>>
{
static void run()
{
std::cout << std::endl;
}
};
//------------------------------------------------------------------------------
template<std::size_t T_count, typename T_Indices, typename T_Shape>
struct Test
{
static void run()
{
PrintIntegerSequence<T_Indices>::run();
Test<
T_count - 1,
typename IncrementIndices<T_Indices, T_Shape>::type,
T_Shape
>::run();
}
};
template<typename T_Indices, typename T_Shape>
struct Test<0, T_Indices, T_Shape>
{
static void run() {}
};
//------------------------------------------------------------------------------
int main(int argc, char **argv)
{
using Shape = m3ta::IndexSequence<2, 4, 3>;
using Indices = m3ta::IndexSequence<0, 0, 0>;
Test<24, Indices, Shape>::run();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment