59 lines
1.2 KiB
C++
59 lines
1.2 KiB
C++
#pragma once
|
|
|
|
#define EXERCISM_RUN_ALL_TESTS
|
|
|
|
|
|
#include <limits>
|
|
#include <stdexcept>
|
|
|
|
|
|
template <size_t number_of_squares = 64,
|
|
typename ulong_t = unsigned long long>
|
|
class custom_grains
|
|
{
|
|
typedef typename std::numeric_limits<ulong_t> limits_t;
|
|
|
|
static_assert(std::is_unsigned<ulong_t>::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;
|