Created
April 26, 2015 02:56
-
-
Save christophercrouzet/2d915020e24a189f4962 to your computer and use it in GitHub Desktop.
Compile-time multidimensional indices incrementer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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