grains: template version
This commit is contained in:
parent
1e20c23729
commit
2aa26a8950
2 changed files with 51 additions and 62 deletions
|
|
@ -1,56 +0,0 @@
|
||||||
#include "grains.h"
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
|
|
||||||
namespace grains {
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
static const index_t number_of_squares = 64;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct total_as_max
|
|
||||||
{
|
|
||||||
static inline T total()
|
|
||||||
{
|
|
||||||
return numeric_limits<T>::max();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct total_by_shift
|
|
||||||
{
|
|
||||||
static inline T total()
|
|
||||||
{
|
|
||||||
return T(1) << number_of_squares - 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(number_of_squares <= numeric_limits<ulong_t>::digits,
|
|
||||||
"grains::ulong_t is too small for grains::total");
|
|
||||||
|
|
||||||
typedef conditional<number_of_squares == numeric_limits<ulong_t>::digits,
|
|
||||||
total_as_max<ulong_t>,
|
|
||||||
total_by_shift<ulong_t>>::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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -3,12 +3,57 @@
|
||||||
#define EXERCISM_RUN_ALL_TESTS
|
#define EXERCISM_RUN_ALL_TESTS
|
||||||
|
|
||||||
|
|
||||||
namespace grains {
|
#include <limits>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
typedef unsigned long long ulong_t;
|
|
||||||
typedef unsigned int index_t;
|
|
||||||
|
|
||||||
ulong_t square(index_t index);
|
template <size_t number_of_squares = 64,
|
||||||
ulong_t total();
|
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;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue