stars_amount.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "base/basic_types.h"
  9. inline constexpr auto kOneStarInNano = int64(1'000'000'000);
  10. class StarsAmount {
  11. public:
  12. StarsAmount() = default;
  13. explicit StarsAmount(int64 whole) : _whole(whole) {}
  14. StarsAmount(int64 whole, int64 nano) : _whole(whole), _nano(nano) {
  15. normalize();
  16. }
  17. [[nodiscard]] int64 whole() const {
  18. return _whole;
  19. }
  20. [[nodiscard]] int64 nano() const {
  21. return _nano;
  22. }
  23. [[nodiscard]] double value() const {
  24. return double(_whole) + double(_nano) / kOneStarInNano;
  25. }
  26. [[nodiscard]] bool empty() const {
  27. return !_whole && !_nano;
  28. }
  29. [[nodiscard]] inline bool operator!() const {
  30. return empty();
  31. }
  32. [[nodiscard]] inline explicit operator bool() const {
  33. return !empty();
  34. }
  35. inline StarsAmount &operator+=(StarsAmount other) {
  36. _whole += other._whole;
  37. _nano += other._nano;
  38. normalize();
  39. return *this;
  40. }
  41. inline StarsAmount &operator-=(StarsAmount other) {
  42. _whole -= other._whole;
  43. _nano -= other._nano;
  44. normalize();
  45. return *this;
  46. }
  47. inline StarsAmount &operator*=(int64 multiplier) {
  48. _whole *= multiplier;
  49. _nano *= multiplier;
  50. normalize();
  51. return *this;
  52. }
  53. inline StarsAmount operator-() const {
  54. auto result = *this;
  55. result *= -1;
  56. return result;
  57. }
  58. friend inline auto operator<=>(StarsAmount, StarsAmount) = default;
  59. friend inline bool operator==(StarsAmount, StarsAmount) = default;
  60. [[nodiscard]] StarsAmount abs() const {
  61. return (_whole < 0) ? StarsAmount(-_whole, -_nano) : *this;
  62. }
  63. private:
  64. int64 _whole = 0;
  65. int64 _nano = 0;
  66. void normalize() {
  67. if (_nano < 0) {
  68. const auto shifts = (-_nano + kOneStarInNano - 1)
  69. / kOneStarInNano;
  70. _nano += shifts * kOneStarInNano;
  71. _whole -= shifts;
  72. } else if (_nano >= kOneStarInNano) {
  73. const auto shifts = _nano / kOneStarInNano;
  74. _nano -= shifts * kOneStarInNano;
  75. _whole += shifts;
  76. }
  77. }
  78. };
  79. [[nodiscard]] inline StarsAmount operator+(StarsAmount a, StarsAmount b) {
  80. return a += b;
  81. }
  82. [[nodiscard]] inline StarsAmount operator-(StarsAmount a, StarsAmount b) {
  83. return a -= b;
  84. }
  85. [[nodiscard]] inline StarsAmount operator*(StarsAmount a, int64 b) {
  86. return a *= b;
  87. }
  88. [[nodiscard]] inline StarsAmount operator*(int64 a, StarsAmount b) {
  89. return b *= a;
  90. }