| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- /*
- This file is part of Telegram Desktop,
- the official desktop application for the Telegram messaging service.
- For license and copyright information please follow this link:
- https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
- */
- #pragma once
- #include "base/basic_types.h"
- inline constexpr auto kOneStarInNano = int64(1'000'000'000);
- class StarsAmount {
- public:
- StarsAmount() = default;
- explicit StarsAmount(int64 whole) : _whole(whole) {}
- StarsAmount(int64 whole, int64 nano) : _whole(whole), _nano(nano) {
- normalize();
- }
- [[nodiscard]] int64 whole() const {
- return _whole;
- }
- [[nodiscard]] int64 nano() const {
- return _nano;
- }
- [[nodiscard]] double value() const {
- return double(_whole) + double(_nano) / kOneStarInNano;
- }
- [[nodiscard]] bool empty() const {
- return !_whole && !_nano;
- }
- [[nodiscard]] inline bool operator!() const {
- return empty();
- }
- [[nodiscard]] inline explicit operator bool() const {
- return !empty();
- }
- inline StarsAmount &operator+=(StarsAmount other) {
- _whole += other._whole;
- _nano += other._nano;
- normalize();
- return *this;
- }
- inline StarsAmount &operator-=(StarsAmount other) {
- _whole -= other._whole;
- _nano -= other._nano;
- normalize();
- return *this;
- }
- inline StarsAmount &operator*=(int64 multiplier) {
- _whole *= multiplier;
- _nano *= multiplier;
- normalize();
- return *this;
- }
- inline StarsAmount operator-() const {
- auto result = *this;
- result *= -1;
- return result;
- }
- friend inline auto operator<=>(StarsAmount, StarsAmount) = default;
- friend inline bool operator==(StarsAmount, StarsAmount) = default;
- [[nodiscard]] StarsAmount abs() const {
- return (_whole < 0) ? StarsAmount(-_whole, -_nano) : *this;
- }
- private:
- int64 _whole = 0;
- int64 _nano = 0;
- void normalize() {
- if (_nano < 0) {
- const auto shifts = (-_nano + kOneStarInNano - 1)
- / kOneStarInNano;
- _nano += shifts * kOneStarInNano;
- _whole -= shifts;
- } else if (_nano >= kOneStarInNano) {
- const auto shifts = _nano / kOneStarInNano;
- _nano -= shifts * kOneStarInNano;
- _whole += shifts;
- }
- }
- };
- [[nodiscard]] inline StarsAmount operator+(StarsAmount a, StarsAmount b) {
- return a += b;
- }
- [[nodiscard]] inline StarsAmount operator-(StarsAmount a, StarsAmount b) {
- return a -= b;
- }
- [[nodiscard]] inline StarsAmount operator*(StarsAmount a, int64 b) {
- return a *= b;
- }
- [[nodiscard]] inline StarsAmount operator*(int64 a, StarsAmount b) {
- return b *= a;
- }
|