2012-08-23 01:33:52 +04:00
|
|
|
#ifndef units_hh_INCLUDED
|
|
|
|
#define units_hh_INCLUDED
|
|
|
|
|
2016-04-22 22:48:42 +03:00
|
|
|
#include "assert.hh"
|
2014-12-16 21:57:19 +03:00
|
|
|
#include "hash.hh"
|
|
|
|
|
2013-01-14 21:51:45 +04:00
|
|
|
#include <type_traits>
|
|
|
|
|
2012-08-23 01:33:52 +04:00
|
|
|
namespace Kakoune
|
|
|
|
{
|
|
|
|
|
|
|
|
template<typename RealType, typename ValueType = int>
|
2013-01-14 21:51:45 +04:00
|
|
|
class StronglyTypedNumber
|
2012-08-23 01:33:52 +04:00
|
|
|
{
|
|
|
|
public:
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2013-01-14 21:51:45 +04: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-23 01:33:52 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2015-05-13 23:30:23 +03:00
|
|
|
constexpr friend RealType operator+(RealType lhs, RealType rhs)
|
|
|
|
{ return RealType(lhs.m_value + rhs.m_value); }
|
2012-08-23 01:33:52 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2015-05-13 23:30:23 +03:00
|
|
|
constexpr friend RealType operator-(RealType lhs, RealType rhs)
|
|
|
|
{ return RealType(lhs.m_value - rhs.m_value); }
|
2012-08-23 01:33:52 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2015-05-13 23:30:23 +03:00
|
|
|
constexpr friend RealType operator*(RealType lhs, RealType rhs)
|
|
|
|
{ return RealType(lhs.m_value * rhs.m_value); }
|
2012-08-23 01:33:52 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2015-05-13 23:30:23 +03:00
|
|
|
constexpr friend RealType operator/(RealType lhs, RealType rhs)
|
|
|
|
{ return RealType(lhs.m_value / rhs.m_value); }
|
2012-08-23 01:33:52 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2013-07-26 02:49:04 +04:00
|
|
|
RealType& operator+=(RealType other)
|
2012-08-23 01:33:52 +04:00
|
|
|
{ m_value += other.m_value; return static_cast<RealType&>(*this); }
|
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2013-07-26 02:49:04 +04:00
|
|
|
RealType& operator-=(RealType other)
|
2012-08-23 01:33:52 +04:00
|
|
|
{ m_value -= other.m_value; return static_cast<RealType&>(*this); }
|
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2013-07-26 02:49:04 +04:00
|
|
|
RealType& operator*=(RealType other)
|
2012-08-23 01:33:52 +04:00
|
|
|
{ m_value *= other.m_value; return static_cast<RealType&>(*this); }
|
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2013-07-26 02:49:04 +04:00
|
|
|
RealType& operator/=(RealType other)
|
2012-08-23 01:33:52 +04:00
|
|
|
{ m_value /= other.m_value; return static_cast<RealType&>(*this); }
|
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2012-08-23 01:33:52 +04:00
|
|
|
RealType& operator++()
|
|
|
|
{ ++m_value; return static_cast<RealType&>(*this); }
|
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2012-08-23 01:33:52 +04:00
|
|
|
RealType& operator--()
|
|
|
|
{ --m_value; return static_cast<RealType&>(*this); }
|
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2012-08-23 01:33:52 +04:00
|
|
|
RealType operator++(int)
|
2012-10-02 16:19:45 +04:00
|
|
|
{ RealType backup(static_cast<RealType&>(*this)); ++m_value; return backup; }
|
2012-08-23 01:33:52 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2012-08-23 01:33:52 +04:00
|
|
|
RealType operator--(int)
|
2012-10-02 16:19:45 +04:00
|
|
|
{ RealType backup(static_cast<RealType&>(*this)); --m_value; return backup; }
|
2012-08-23 01:33:52 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2013-11-11 23:11:17 +04:00
|
|
|
constexpr RealType operator-() const { return RealType(-m_value); }
|
2012-08-23 01:33:52 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2015-05-13 23:30:23 +03:00
|
|
|
constexpr friend RealType operator%(RealType lhs, RealType rhs)
|
|
|
|
{ return RealType(lhs.m_value % rhs.m_value); }
|
2013-11-06 23:10:15 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2013-11-11 23:11:17 +04:00
|
|
|
RealType& operator%=(RealType other)
|
2013-11-06 23:10:15 +04:00
|
|
|
{ m_value %= other.m_value; return static_cast<RealType&>(*this); }
|
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2015-05-13 23:30:23 +03:00
|
|
|
constexpr friend bool operator==(RealType lhs, RealType rhs)
|
|
|
|
{ return lhs.m_value == rhs.m_value; }
|
2012-08-23 01:33:52 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2015-05-13 23:30:23 +03:00
|
|
|
constexpr friend bool operator!=(RealType lhs, RealType rhs)
|
|
|
|
{ return lhs.m_value != rhs.m_value; }
|
2012-08-23 01:33:52 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2015-05-13 23:30:23 +03:00
|
|
|
constexpr friend bool operator<(RealType lhs, RealType rhs)
|
|
|
|
{ return lhs.m_value < rhs.m_value; }
|
2012-08-23 01:33:52 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2015-05-13 23:30:23 +03:00
|
|
|
constexpr friend bool operator<=(RealType lhs, RealType rhs)
|
|
|
|
{ return lhs.m_value <= rhs.m_value; }
|
2012-08-23 01:33:52 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2015-05-13 23:30:23 +03:00
|
|
|
constexpr friend bool operator>(RealType lhs, RealType rhs)
|
|
|
|
{ return lhs.m_value > rhs.m_value; }
|
2012-08-23 01:33:52 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2015-05-13 23:30:23 +03:00
|
|
|
constexpr friend bool operator>=(RealType lhs, RealType rhs)
|
|
|
|
{ return lhs.m_value >= rhs.m_value; }
|
2012-08-23 01:33:52 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2012-09-05 01:54:10 +04:00
|
|
|
constexpr bool operator!() const
|
2015-12-28 02:28:34 +03:00
|
|
|
{ return not m_value; }
|
2012-08-24 01:56:35 +04:00
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2012-09-05 01:54:10 +04:00
|
|
|
explicit constexpr operator ValueType() const { return m_value; }
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2012-10-02 16:18:34 +04:00
|
|
|
explicit constexpr operator bool() const { return m_value; }
|
2015-03-11 16:59:25 +03:00
|
|
|
|
|
|
|
friend size_t hash_value(RealType val) { return hash_value(val.m_value); }
|
2015-04-17 03:01:58 +03:00
|
|
|
friend size_t abs(RealType val) { return val.m_value < ValueType(0) ? -val.m_value : val.m_value; }
|
2015-03-11 16:59:25 +03:00
|
|
|
|
2016-04-22 22:48:42 +03:00
|
|
|
explicit operator size_t() { kak_assert(m_value >= 0); return (size_t)m_value; }
|
|
|
|
|
|
|
|
protected:
|
2013-11-14 04:12:15 +04:00
|
|
|
ValueType m_value;
|
2012-08-23 01:33:52 +04:00
|
|
|
};
|
|
|
|
|
2013-01-14 21:51:45 +04:00
|
|
|
struct LineCount : public StronglyTypedNumber<LineCount, int>
|
2012-08-23 01:33:52 +04:00
|
|
|
{
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2013-03-27 21:42:38 +04:00
|
|
|
constexpr LineCount(int value = 0) : StronglyTypedNumber<LineCount>(value) {}
|
2012-08-23 01:33:52 +04:00
|
|
|
};
|
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2012-09-05 01:54:10 +04:00
|
|
|
inline constexpr LineCount operator"" _line(unsigned long long int value)
|
2012-08-23 01:33:52 +04:00
|
|
|
{
|
|
|
|
return LineCount(value);
|
|
|
|
}
|
|
|
|
|
2013-01-14 21:51:45 +04:00
|
|
|
struct ByteCount : public StronglyTypedNumber<ByteCount, int>
|
2012-10-11 02:13:31 +04:00
|
|
|
{
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2013-03-27 21:42:38 +04:00
|
|
|
constexpr ByteCount(int value = 0) : StronglyTypedNumber<ByteCount>(value) {}
|
2012-10-11 02:13:31 +04:00
|
|
|
};
|
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2012-10-11 02:13:31 +04:00
|
|
|
inline constexpr ByteCount operator"" _byte(unsigned long long int value)
|
|
|
|
{
|
|
|
|
return ByteCount(value);
|
|
|
|
}
|
|
|
|
|
2013-01-14 21:51:45 +04:00
|
|
|
struct CharCount : public StronglyTypedNumber<CharCount, int>
|
2012-08-24 01:56:35 +04:00
|
|
|
{
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2013-03-27 21:42:38 +04:00
|
|
|
constexpr CharCount(int value = 0) : StronglyTypedNumber<CharCount>(value) {}
|
2012-08-24 01:56:35 +04:00
|
|
|
};
|
|
|
|
|
2014-05-17 13:17:28 +04:00
|
|
|
[[gnu::always_inline]]
|
2012-09-05 01:54:10 +04:00
|
|
|
inline constexpr CharCount operator"" _char(unsigned long long int value)
|
2012-08-24 01:56:35 +04:00
|
|
|
{
|
|
|
|
return CharCount(value);
|
|
|
|
}
|
|
|
|
|
2012-08-23 01:33:52 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif // units_hh_INCLUDED
|