init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
185
Telegram/SourceFiles/core/credits_amount.h
Normal file
185
Telegram/SourceFiles/core/credits_amount.h
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
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/algorithm.h"
|
||||
#include "base/basic_types.h"
|
||||
|
||||
class MTPstarsAmount;
|
||||
|
||||
namespace tl {
|
||||
template <typename bare>
|
||||
class boxed;
|
||||
} // namespace tl
|
||||
|
||||
using MTPStarsAmount = tl::boxed<MTPstarsAmount>;
|
||||
|
||||
inline constexpr auto kOneStarInNano = int64(1'000'000'000);
|
||||
|
||||
enum class CreditsType {
|
||||
Stars,
|
||||
Ton,
|
||||
};
|
||||
|
||||
class CreditsAmount {
|
||||
public:
|
||||
CreditsAmount() = default;
|
||||
explicit CreditsAmount(
|
||||
int64 whole,
|
||||
CreditsType type = CreditsType::Stars)
|
||||
: _ton((type == CreditsType::Ton) ? 1 : 0)
|
||||
, _whole(whole) {
|
||||
}
|
||||
CreditsAmount(
|
||||
int64 whole,
|
||||
int64 nano,
|
||||
CreditsType type = CreditsType::Stars)
|
||||
: _ton((type == CreditsType::Ton) ? 1 : 0)
|
||||
, _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 ton() const {
|
||||
return (_ton == 1);
|
||||
}
|
||||
[[nodiscard]] bool stars() const {
|
||||
return (_ton == 0);
|
||||
}
|
||||
[[nodiscard]] CreditsType type() const {
|
||||
return !_ton ? CreditsType::Stars : CreditsType::Ton;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool empty() const {
|
||||
return !_whole && !_nano;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool operator!() const {
|
||||
return empty();
|
||||
}
|
||||
[[nodiscard]] inline explicit operator bool() const {
|
||||
return !empty();
|
||||
}
|
||||
|
||||
[[nodiscard]] CreditsAmount multiplied(float64 rate) const {
|
||||
const auto result = value() * rate;
|
||||
const auto abs = std::abs(result);
|
||||
const auto whole = std::floor(abs);
|
||||
const auto nano = base::SafeRound((abs - whole) * kOneStarInNano);
|
||||
return CreditsAmount(
|
||||
(result < 0) ? -whole : whole,
|
||||
(result < 0) ? -nano : nano,
|
||||
type());
|
||||
}
|
||||
|
||||
inline CreditsAmount &operator+=(CreditsAmount other) {
|
||||
_whole += other._whole;
|
||||
_nano += other._nano;
|
||||
normalize();
|
||||
return *this;
|
||||
}
|
||||
inline CreditsAmount &operator-=(CreditsAmount other) {
|
||||
_whole -= other._whole;
|
||||
_nano -= other._nano;
|
||||
normalize();
|
||||
return *this;
|
||||
}
|
||||
inline CreditsAmount &operator*=(int64 multiplier) {
|
||||
_whole *= multiplier;
|
||||
_nano *= multiplier;
|
||||
normalize();
|
||||
return *this;
|
||||
}
|
||||
inline CreditsAmount operator-() const {
|
||||
auto result = *this;
|
||||
result *= -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
// AppleClang :/
|
||||
// friend inline auto operator<=>(CreditsAmount, CreditsAmount)
|
||||
// = default;
|
||||
friend inline constexpr auto operator<=>(
|
||||
CreditsAmount a,
|
||||
CreditsAmount b) {
|
||||
if (const auto r1 = (a._whole <=> b._whole); r1 != 0) {
|
||||
return r1;
|
||||
} else if (const auto r2 = (a._nano <=> b._nano); r2 != 0) {
|
||||
return r2;
|
||||
}
|
||||
return (a._whole || a._nano)
|
||||
? (int(a._ton) <=> int(b._ton))
|
||||
: std::strong_ordering::equal;
|
||||
}
|
||||
|
||||
friend inline bool operator==(CreditsAmount, CreditsAmount)
|
||||
= default;
|
||||
|
||||
[[nodiscard]] CreditsAmount abs() const {
|
||||
return (_whole < 0) ? CreditsAmount(-_whole, -_nano) : *this;
|
||||
}
|
||||
|
||||
private:
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
int64 _ton : 2 = 0;
|
||||
int64 _whole : 62 = 0;
|
||||
int64 _nano = 0;
|
||||
|
||||
};
|
||||
|
||||
[[nodiscard]] inline CreditsAmount operator+(
|
||||
CreditsAmount a,
|
||||
CreditsAmount b) {
|
||||
return a += b;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline CreditsAmount operator-(
|
||||
CreditsAmount a,
|
||||
CreditsAmount b) {
|
||||
return a -= b;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline CreditsAmount operator*(CreditsAmount a, int64 b) {
|
||||
return a *= b;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline CreditsAmount operator*(int64 a, CreditsAmount b) {
|
||||
return b *= a;
|
||||
}
|
||||
|
||||
[[nodiscard]] CreditsAmount CreditsAmountFromTL(
|
||||
const MTPStarsAmount &amount);
|
||||
[[nodiscard]] CreditsAmount CreditsAmountFromTL(
|
||||
const MTPStarsAmount *amount);
|
||||
[[nodiscard]] MTPStarsAmount StarsAmountToTL(CreditsAmount amount);
|
||||
|
||||
[[nodiscard]] QString PrepareCreditsAmountText(CreditsAmount amount);
|
||||
Reference in New Issue
Block a user