Сообщение Re[2]: Простенький компайл-тайм счетчик от 30.03.2017 10:06
Изменено 30.03.2017 10:09 Кодт
Re[2]: Простенький компайл-тайм счетчик
Здравствуйте, jazzer, Вы писали:
J>Я сделал в свое время похожую штуку — и напоролся на ограничение рекурсии инстанцирования для сколько-нибудь больших файлов. Но это было давно, может, сейчас это и не проблема уже...
Вместо линейной рекурсии можно сделать деревянную!
J>Я сделал в свое время похожую штуку — и напоролся на ограничение рекурсии инстанцирования для сколько-нибудь больших файлов. Но это было давно, может, сейчас это и не проблема уже...
Вместо линейной рекурсии можно сделать деревянную!
template<int I> struct int_ { static constexpr int value = I; };
using int_0 = int_<0>;
using int_1 = int_<1>;
template<int I> struct point : int_0 {};
#define TAG_IT() template<> struct point<__COUNTER__> : int_1 {};
template<int L, int N> struct sumpoints;
template<int L, int H, int N> using splitsum = int_< sumpoints<L,H>::value + sumpoints<L+H,N-H>::value >;
template<int L> struct sumpoints<L, 0> : int_0 {};
template<int L> struct sumpoints<L, 1> : point<L> {};
template<int L, int N> struct sumpoints : splitsum<L, N/2, N> {};
// лучше разбивать не пополам, а по старшему биту, - это даст меньше сочетаний <L,N> при массовом использовании
// и, соответственно, меньше воплощений шаблона
// но я сходу не вспомнил формулу для его нахождения
#define GET_IT() (sumpoints<0, __COUNTER__>::value)
constexpr int x = GET_IT(); // __COUNTER__ = 1, x = 0
constexpr int y = GET_IT(); // __COUNTER__ = 2, y = 0
TAG_IT(); // __COUNTER__ = 3
TAG_IT(); // __COUNTER__ = 4
TAG_IT(); // __COUNTER__ = 5
constexpr int z = GET_IT(); // __COUNTER__ = 6, z = 3
Re[2]: Простенький компайл-тайм счетчик
Здравствуйте, jazzer, Вы писали:
J>Я сделал в свое время похожую штуку — и напоролся на ограничение рекурсии инстанцирования для сколько-нибудь больших файлов. Но это было давно, может, сейчас это и не проблема уже...
Вместо линейной рекурсии можно сделать деревянную!
http://ideone.com/E7VreH
J>Я сделал в свое время похожую штуку — и напоролся на ограничение рекурсии инстанцирования для сколько-нибудь больших файлов. Но это было давно, может, сейчас это и не проблема уже...
Вместо линейной рекурсии можно сделать деревянную!
http://ideone.com/E7VreH
template<int I> struct int_ { static constexpr int value = I; };
using int_0 = int_<0>;
using int_1 = int_<1>;
template<int I> struct point : int_0 {};
#define TAG_IT() template<> struct point<__COUNTER__> : int_1 {};
template<int L, int N> struct sumpoints;
template<int L, int H, int N> using splitsum = int_< sumpoints<L,H>::value + sumpoints<L+H,N-H>::value >;
template<int L> struct sumpoints<L, 0> : int_0 {};
template<int L> struct sumpoints<L, 1> : point<L> {};
template<int L, int N> struct sumpoints : splitsum<L, N/2, N> {};
// лучше разбивать не пополам, а по старшему биту, - это даст меньше сочетаний <L,N> при массовом использовании
// и, соответственно, меньше воплощений шаблона
// но я сходу не вспомнил формулу для его нахождения
#define GET_IT() (sumpoints<0, __COUNTER__>::value)
constexpr int x = GET_IT(); // __COUNTER__ = 1, x = 0
constexpr int y = GET_IT(); // __COUNTER__ = 2, y = 0
TAG_IT(); // __COUNTER__ = 3
TAG_IT(); // __COUNTER__ = 4
TAG_IT(); // __COUNTER__ = 5
constexpr int z = GET_IT(); // __COUNTER__ = 6, z = 3