Skip to content

Instantly share code, notes, and snippets.

@goyusia
Last active August 29, 2015 14:19
Show Gist options
  • Select an option

  • Save goyusia/94e98708443bd64e7940 to your computer and use it in GitHub Desktop.

Select an option

Save goyusia/94e98708443bd64e7940 to your computer and use it in GitHub Desktop.
Calculate Average (C++ Template Metaprogramming)
#include <type_traits>
#include <cstdio>
template<int... Items>
struct intlist;
template<typename intlist, int I>
struct push_back;
template<int I, int Head, int... Remainder>
struct push_back<intlist<Head, Remainder...>, I> {
typedef intlist<Head, Remainder..., I> value;
};
template<int I>
struct push_back<intlist<>, I> {
typedef intlist<I> value;
};
typedef push_back<intlist<>, 1>::value push_back_1;
static_assert(std::is_same<push_back_1, intlist<1>>::value == 1, "");
typedef push_back<push_back_1, 2>::value push_back_2;
static_assert(std::is_same<push_back_2, intlist<1, 2>>::value == 1, "");
template<typename intlist>
struct length;
template<int Head, int... Remainder>
struct length< intlist<Head, Remainder...>> {
enum {
value = 1 + length<intlist<Remainder...>>::value
};
};
template<>
struct length < intlist<> > {
enum {
value = 0
};
};
static_assert(length<intlist<>>::value == 0, "");
static_assert(length<intlist<1>>::value == 1, "");
static_assert(length<intlist<1, 2>>::value == 2, "");
template<typename intlist>
struct sum;
template<int Head, int... Remainder>
struct sum < intlist<Head, Remainder...> > {
enum {
value = Head + sum<intlist<Remainder...>>::value
};
};
template<>
struct sum < intlist<> > {
enum {
value = 0
};
};
static_assert(sum<intlist<>>::value == 0, "");
static_assert(sum<intlist<1>>::value == 1, "");
static_assert(sum<intlist<1, 2>>::value == 3, "");
template<int Number, int Size>
struct divide {
enum {
value = Number / Size,
remainder = Number % Size
};
static float get_value() {
float val = value + (float)(remainder) / Size;
return val;
}
};
static_assert(divide<9, 4>::value == 2, "");
static_assert(divide<9, 4>::remainder == 1, "");
namespace AverageFunction {
// 정수 리스트에 값을 집어넣은 다음 평균을 구하는 코드(?)
typedef intlist<> empty;
typedef push_back<empty, 1>::value list_1;
typedef push_back<list_1, 2>::value list_2;
typedef push_back<list_2, 4>::value list_3;
typedef push_back<list_3, 8>::value list_4;
typedef push_back<list_4, 16>::value target_list;
const int list_size = length<target_list>::value;
const int list_sum = sum<target_list>::value;
const float retval = divide<list_sum, list_size>::get_value();
}
int main() {
printf("Average = %f\n", AverageFunction::retval);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment