diff --git a/cpp/grains/grains.cpp b/cpp/grains/grains.cpp index d213d8f..b7646ff 100644 --- a/cpp/grains/grains.cpp +++ b/cpp/grains/grains.cpp @@ -1,18 +1,56 @@ #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) { - return 1ULL << (index - 1); + if (index < 1 || index > number_of_squares) + throw domain_error("invalid square number"); + + return ulong_t(1) << (index - 1); } ulong_t total() { - return (1ULL << number_of_squares) - 1; + return total_policy_t::total(); } }