#pragma once #define EXERCISM_RUN_ALL_TESTS #include #include 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;