diff --git a/cpp/grains/grains.cpp b/cpp/grains/grains.cpp deleted file mode 100644 index b7646ff..0000000 --- a/cpp/grains/grains.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "grains.h" - -#include -#include - - -namespace grains { - -using namespace std; - - -namespace { - -static const index_t number_of_squares = 64; - -template -struct total_as_max -{ - static inline T total() - { - return numeric_limits::max(); - } -}; - -template -struct total_by_shift -{ - static inline T total() - { - return T(1) << number_of_squares - 1; - } -}; - -static_assert(number_of_squares <= numeric_limits::digits, - "grains::ulong_t is too small for grains::total"); - -typedef conditional::digits, - total_as_max, - total_by_shift>::type total_policy_t; -} - - -ulong_t square(index_t index) -{ - if (index < 1 || index > number_of_squares) - throw domain_error("invalid square number"); - - return ulong_t(1) << (index - 1); -} - -ulong_t total() -{ - return total_policy_t::total(); -} - -} diff --git a/cpp/grains/grains.h b/cpp/grains/grains.h index 5afadd5..3b9c43b 100644 --- a/cpp/grains/grains.h +++ b/cpp/grains/grains.h @@ -3,12 +3,57 @@ #define EXERCISM_RUN_ALL_TESTS -namespace grains { +#include +#include -typedef unsigned long long ulong_t; -typedef unsigned int index_t; -ulong_t square(index_t index); -ulong_t total(); +template +class custom_grains +{ + typedef typename std::numeric_limits limits_t; -} + static_assert(std::is_unsigned::value, + "ulong_t must be unsigned"); + + static_assert(number_of_squares <= limits_t::digits, + "ulong_t is too short"); + + struct total_as_max + { + static inline ulong_t total() + { + return limits_t::max(); + } + }; + + struct total_by_shift + { + static inline ulong_t total() + { + return ulong_t(1) << number_of_squares - 1; + } + }; + + typedef typename std::conditional< + number_of_squares == limits_t::digits, + total_as_max, + total_by_shift>::type total_policy_t; + +public: + + static ulong_t square(size_t index) + { + if (index < 1 || index > number_of_squares) + throw std::domain_error("invalid square number"); + + return ulong_t(1) << (index - 1); + } + + static ulong_t total() + { + return total_policy_t::total(); + } +}; + +typedef custom_grains<> grains;