2012-08-22 23:33:52 +02:00
|
|
|
#ifndef units_hh_INCLUDED
|
|
|
|
#define units_hh_INCLUDED
|
|
|
|
|
2013-01-14 18:51:45 +01:00
|
|
|
#include <type_traits>
|
|
|
|
|
2012-08-22 23:33:52 +02:00
|
|
|
namespace Kakoune
|
|
|
|
{
|
|
|
|
|
|
|
|
template<typename RealType, typename ValueType = int>
|
2013-01-14 18:51:45 +01:00
|
|
|
class StronglyTypedNumber
|
2012-08-22 23:33:52 +02:00
|
|
|
{
|
|
|
|
public:
|
2013-01-14 18:51:45 +01:00
|
|
|
explicit constexpr StronglyTypedNumber(ValueType value)
|
|
|
|
: m_value(value)
|
|
|
|
{
|
|
|
|
static_assert(std::is_base_of<StronglyTypedNumber, RealType>::value,
|
|
|
|
"RealType is not derived from StronglyTypedNumber");
|
|
|
|
}
|
2012-08-22 23:33:52 +02:00
|
|
|
|
2012-09-04 23:54:10 +02:00
|
|
|
constexpr RealType operator+(const RealType& other) const
|
2012-08-22 23:33:52 +02:00
|
|
|
{ return RealType(m_value + other.m_value); }
|
|
|
|
|
2012-09-04 23:54:10 +02:00
|
|
|
constexpr RealType operator-(const RealType& other) const
|
2012-08-22 23:33:52 +02:00
|
|
|
{ return RealType(m_value - other.m_value); }
|
|
|
|
|
2012-09-04 23:54:10 +02:00
|
|
|
constexpr RealType operator*(const RealType& other) const
|
2012-08-22 23:33:52 +02:00
|
|
|
{ return RealType(m_value * other.m_value); }
|
|
|
|
|
2012-09-04 23:54:10 +02:00
|
|
|
constexpr RealType operator/(const RealType& other) const
|
2012-08-22 23:33:52 +02:00
|
|
|
{ return RealType(m_value / other.m_value); }
|
|
|
|
|
|
|
|
RealType& operator+=(const RealType& other)
|
|
|
|
{ m_value += other.m_value; return static_cast<RealType&>(*this); }
|
|
|
|
|
|
|
|
RealType& operator-=(const RealType& other)
|
|
|
|
{ m_value -= other.m_value; return static_cast<RealType&>(*this); }
|
|
|
|
|
|
|
|
RealType& operator*=(const RealType& other)
|
|
|
|
{ m_value *= other.m_value; return static_cast<RealType&>(*this); }
|
|
|
|
|
|
|
|
RealType& operator/=(const RealType& other)
|
|
|
|
{ m_value /= other.m_value; return static_cast<RealType&>(*this); }
|
|
|
|
|
|
|
|
RealType& operator++()
|
|
|
|
{ ++m_value; return static_cast<RealType&>(*this); }
|
|
|
|
|
|
|
|
RealType& operator--()
|
|
|
|
{ --m_value; return static_cast<RealType&>(*this); }
|
|
|
|
|
|
|
|
RealType operator++(int)
|
2012-10-02 14:19:45 +02:00
|
|
|
{ RealType backup(static_cast<RealType&>(*this)); ++m_value; return backup; }
|
2012-08-22 23:33:52 +02:00
|
|
|
|
|
|
|
RealType operator--(int)
|
2012-10-02 14:19:45 +02:00
|
|
|
{ RealType backup(static_cast<RealType&>(*this)); --m_value; return backup; }
|
2012-08-22 23:33:52 +02:00
|
|
|
|
2012-09-04 23:54:10 +02:00
|
|
|
constexpr RealType operator-() { return RealType(-m_value); }
|
2012-08-22 23:33:52 +02:00
|
|
|
|
2012-09-04 23:54:10 +02:00
|
|
|
constexpr bool operator==(const RealType& other) const
|
2012-08-22 23:33:52 +02:00
|
|
|
{ return m_value == other.m_value; }
|
|
|
|
|
2012-09-04 23:54:10 +02:00
|
|
|
constexpr bool operator!=(const RealType& other) const
|
2012-08-22 23:33:52 +02:00
|
|
|
{ return m_value != other.m_value; }
|
|
|
|
|
2012-09-04 23:54:10 +02:00
|
|
|
constexpr bool operator<(const RealType& other) const
|
2012-08-22 23:33:52 +02:00
|
|
|
{ return m_value < other.m_value; }
|
|
|
|
|
2012-09-04 23:54:10 +02:00
|
|
|
constexpr bool operator<=(const RealType& other) const
|
2012-08-22 23:33:52 +02:00
|
|
|
{ return m_value <= other.m_value; }
|
|
|
|
|
2012-09-04 23:54:10 +02:00
|
|
|
constexpr bool operator>(const RealType& other) const
|
2012-08-22 23:33:52 +02:00
|
|
|
{ return m_value > other.m_value; }
|
|
|
|
|
2012-09-04 23:54:10 +02:00
|
|
|
constexpr bool operator>=(const RealType& other) const
|
2012-08-22 23:33:52 +02:00
|
|
|
{ return m_value >= other.m_value; }
|
|
|
|
|
2012-09-04 23:54:10 +02:00
|
|
|
constexpr bool operator!() const
|
2012-08-23 23:56:35 +02:00
|
|
|
{ return !m_value; }
|
|
|
|
|
2012-09-04 23:54:10 +02:00
|
|
|
explicit constexpr operator ValueType() const { return m_value; }
|
2012-10-02 14:18:34 +02:00
|
|
|
explicit constexpr operator bool() const { return m_value; }
|
2012-08-22 23:33:52 +02:00
|
|
|
private:
|
|
|
|
ValueType m_value;
|
|
|
|
};
|
|
|
|
|
2013-01-14 18:51:45 +01:00
|
|
|
struct LineCount : public StronglyTypedNumber<LineCount, int>
|
2012-08-22 23:33:52 +02:00
|
|
|
{
|
2013-03-26 00:04:03 +01:00
|
|
|
LineCount() : LineCount(0) {}
|
2013-01-14 18:51:45 +01:00
|
|
|
constexpr LineCount(int value) : StronglyTypedNumber<LineCount>(value) {}
|
2012-08-22 23:33:52 +02:00
|
|
|
};
|
|
|
|
|
2012-09-04 23:54:10 +02:00
|
|
|
inline constexpr LineCount operator"" _line(unsigned long long int value)
|
2012-08-22 23:33:52 +02:00
|
|
|
{
|
|
|
|
return LineCount(value);
|
|
|
|
}
|
|
|
|
|
2013-01-14 18:51:45 +01:00
|
|
|
struct ByteCount : public StronglyTypedNumber<ByteCount, int>
|
2012-10-11 00:13:31 +02:00
|
|
|
{
|
2013-03-26 00:04:03 +01:00
|
|
|
ByteCount() : ByteCount(0) {}
|
2013-01-14 18:51:45 +01:00
|
|
|
constexpr ByteCount(int value) : StronglyTypedNumber<ByteCount>(value) {}
|
2012-10-11 00:13:31 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
inline constexpr ByteCount operator"" _byte(unsigned long long int value)
|
|
|
|
{
|
|
|
|
return ByteCount(value);
|
|
|
|
}
|
|
|
|
|
2013-01-14 18:51:45 +01:00
|
|
|
struct CharCount : public StronglyTypedNumber<CharCount, int>
|
2012-08-23 23:56:35 +02:00
|
|
|
{
|
2013-03-26 00:04:03 +01:00
|
|
|
CharCount() : CharCount(0) {}
|
2013-01-14 18:51:45 +01:00
|
|
|
constexpr CharCount(int value) : StronglyTypedNumber<CharCount>(value) {}
|
2012-08-23 23:56:35 +02:00
|
|
|
};
|
|
|
|
|
2012-09-04 23:54:10 +02:00
|
|
|
inline constexpr CharCount operator"" _char(unsigned long long int value)
|
2012-08-23 23:56:35 +02:00
|
|
|
{
|
|
|
|
return CharCount(value);
|
|
|
|
}
|
|
|
|
|
2012-08-22 23:33:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif // units_hh_INCLUDED
|
|
|
|
|