No double-to-int
// Copyright 2015 Andrzej Krzemienski.
//
// This shows how to use an auxiliary type to prevent implicit
// conversions from double to int
#include <type_traits>
#include <iostream>
# define ENABLE_IF(...) \
typename std::enable_if<__VA_ARGS__::value, bool>::type \
= false \
template <typename T>
using is_signed_integral = typename std::conditional<
std::is_signed<T>::value && std::is_integral<T>::value,
std::true_type,
std::false_type
>::type;
class only_int
{
long long val_;
public:
only_int (int v = 0) : val_(v) {}
template <typename I, ENABLE_IF(is_signed_integral<I>)>
only_int (I v) : val_(v)
{
static_assert(sizeof(I) <= sizeof(int),
"too big int");
}
template <typename T, ENABLE_IF(!is_signed_integral<T>)>
only_int (T) = delete;
int get() const { return val_; }
};
constexpr int pow(int base, int exp)
{
return exp == 0 ? 1 : base * pow(base, exp - 1);
}
template <int Dec>
class FixedDecimal
{
long long v_ = 0;
public:
FixedDecimal (only_int i)
: v_ (i.get() * pow(10, Dec)) {}
FixedDecimal& operator *= (only_int s)
{ v_ *= s.get(); return *this; }
FixedDecimal& operator /= (only_int s)
{ v_ /= s.get(); return *this; }
};
int main()
{
FixedDecimal<2> d(5);
// FixedDecimal<2> d(5.0); // will not compile
d *= 5;
// d *= 5.0; // will not compile
}
Like this:
Like Loading...