home/src/units.hh

161 lines
4.5 KiB
C++
Raw Normal View History

#ifndef units_hh_INCLUDED
#define units_hh_INCLUDED
#include "hash.hh"
#include <type_traits>
namespace Kakoune
{
template<typename RealType, typename ValueType = int>
class StronglyTypedNumber
{
public:
[[gnu::always_inline]]
explicit constexpr StronglyTypedNumber(ValueType value)
: m_value(value)
{
static_assert(std::is_base_of<StronglyTypedNumber, RealType>::value,
"RealType is not derived from StronglyTypedNumber");
}
[[gnu::always_inline]]
constexpr RealType operator+(RealType other) const
{ return RealType(m_value + other.m_value); }
[[gnu::always_inline]]
constexpr RealType operator-(RealType other) const
{ return RealType(m_value - other.m_value); }
[[gnu::always_inline]]
constexpr RealType operator*(RealType other) const
{ return RealType(m_value * other.m_value); }
[[gnu::always_inline]]
constexpr RealType operator/(RealType other) const
{ return RealType(m_value / other.m_value); }
[[gnu::always_inline]]
RealType& operator+=(RealType other)
{ m_value += other.m_value; return static_cast<RealType&>(*this); }
[[gnu::always_inline]]
RealType& operator-=(RealType other)
{ m_value -= other.m_value; return static_cast<RealType&>(*this); }
[[gnu::always_inline]]
RealType& operator*=(RealType other)
{ m_value *= other.m_value; return static_cast<RealType&>(*this); }
[[gnu::always_inline]]
RealType& operator/=(RealType other)
{ m_value /= other.m_value; return static_cast<RealType&>(*this); }
[[gnu::always_inline]]
RealType& operator++()
{ ++m_value; return static_cast<RealType&>(*this); }
[[gnu::always_inline]]
RealType& operator--()
{ --m_value; return static_cast<RealType&>(*this); }
[[gnu::always_inline]]
RealType operator++(int)
{ RealType backup(static_cast<RealType&>(*this)); ++m_value; return backup; }
[[gnu::always_inline]]
RealType operator--(int)
{ RealType backup(static_cast<RealType&>(*this)); --m_value; return backup; }
[[gnu::always_inline]]
2013-11-11 20:11:17 +01:00
constexpr RealType operator-() const { return RealType(-m_value); }
[[gnu::always_inline]]
constexpr RealType operator%(RealType other) const
{ return RealType(m_value % other.m_value); }
[[gnu::always_inline]]
2013-11-11 20:11:17 +01:00
RealType& operator%=(RealType other)
{ m_value %= other.m_value; return static_cast<RealType&>(*this); }
[[gnu::always_inline]]
constexpr bool operator==(RealType other) const
{ return m_value == other.m_value; }
[[gnu::always_inline]]
constexpr bool operator!=(RealType other) const
{ return m_value != other.m_value; }
[[gnu::always_inline]]
constexpr bool operator<(RealType other) const
{ return m_value < other.m_value; }
[[gnu::always_inline]]
constexpr bool operator<=(RealType other) const
{ return m_value <= other.m_value; }
[[gnu::always_inline]]
constexpr bool operator>(RealType other) const
{ return m_value > other.m_value; }
[[gnu::always_inline]]
constexpr bool operator>=(RealType other) const
{ return m_value >= other.m_value; }
[[gnu::always_inline]]
2012-09-04 23:54:10 +02:00
constexpr bool operator!() const
{ return !m_value; }
[[gnu::always_inline]]
2012-09-04 23:54:10 +02:00
explicit constexpr operator ValueType() const { return m_value; }
[[gnu::always_inline]]
explicit constexpr operator bool() const { return m_value; }
2015-03-11 14:59:25 +01:00
friend size_t hash_value(RealType val) { return hash_value(val.m_value); }
2015-04-17 02:01:58 +02:00
friend size_t abs(RealType val) { return val.m_value < ValueType(0) ? -val.m_value : val.m_value; }
2015-03-11 14:59:25 +01:00
private:
ValueType m_value;
};
struct LineCount : public StronglyTypedNumber<LineCount, int>
{
[[gnu::always_inline]]
constexpr LineCount(int value = 0) : StronglyTypedNumber<LineCount>(value) {}
};
[[gnu::always_inline]]
2012-09-04 23:54:10 +02:00
inline constexpr LineCount operator"" _line(unsigned long long int value)
{
return LineCount(value);
}
struct ByteCount : public StronglyTypedNumber<ByteCount, int>
2012-10-11 00:13:31 +02:00
{
[[gnu::always_inline]]
constexpr ByteCount(int value = 0) : StronglyTypedNumber<ByteCount>(value) {}
2012-10-11 00:13:31 +02:00
};
[[gnu::always_inline]]
2012-10-11 00:13:31 +02:00
inline constexpr ByteCount operator"" _byte(unsigned long long int value)
{
return ByteCount(value);
}
struct CharCount : public StronglyTypedNumber<CharCount, int>
{
[[gnu::always_inline]]
constexpr CharCount(int value = 0) : StronglyTypedNumber<CharCount>(value) {}
};
[[gnu::always_inline]]
2012-09-04 23:54:10 +02:00
inline constexpr CharCount operator"" _char(unsigned long long int value)
{
return CharCount(value);
}
}
#endif // units_hh_INCLUDED