Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MonetaryAmount from std::string_view should be be constructible with … #474

Merged
merged 1 commit into from
Oct 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/api/common/src/ssl_sha.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ inline EVPMDCTXUniquePtr InitEVPMDCTXUniquePtr(ShaType shaType) {
}

inline string EVPBinToHex(const EVPMDCTXUniquePtr& mdctx) {
unsigned int len;
unsigned int len = 0;
unsigned char binData[EVP_MAX_MD_SIZE];
EVP_DigestFinal_ex(mdctx.get(), binData, &len);
return BinToHex(std::span<const unsigned char>(binData, len));
Expand Down
6 changes: 3 additions & 3 deletions src/main/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@

int main(int argc, const char* argv[]) {
try {
auto cmdLineOptionsVector = cct::CoincenterCommands::ParseOptions(argc, argv);
const auto cmdLineOptionsVector = cct::CoincenterCommands::ParseOptions(argc, argv);

if (!cmdLineOptionsVector.empty()) {
cct::CoincenterCommands coincenterCommands(cmdLineOptionsVector);
auto programName = std::filesystem::path(argv[0]).filename().string();
const cct::CoincenterCommands coincenterCommands(cmdLineOptionsVector);
const auto programName = std::filesystem::path(argv[0]).filename().string();

cct::ProcessCommandsFromCLI(programName, coincenterCommands, cmdLineOptionsVector.front(),
cct::settings::RunMode::kProd);
Expand Down
38 changes: 20 additions & 18 deletions src/objects/include/currencycode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,39 +69,40 @@ class CurrencyCodeIterator {
using pointer = const char *;
using reference = const char &;

constexpr auto operator<=>(const CurrencyCodeIterator &) const noexcept = default;
bool operator==(const CurrencyCodeIterator &) const noexcept = default;
constexpr std::strong_ordering operator<=>(const CurrencyCodeIterator &) const noexcept = default;

CurrencyCodeIterator &operator++() noexcept { // Prefix increment
constexpr bool operator==(const CurrencyCodeIterator &) const noexcept = default;

constexpr CurrencyCodeIterator &operator++() noexcept { // Prefix increment
++_pos;
return *this;
}

CurrencyCodeIterator &operator--() noexcept { // Prefix decrement
constexpr CurrencyCodeIterator &operator--() noexcept { // Prefix decrement
--_pos;
return *this;
}

CurrencyCodeIterator operator++(int) noexcept { // Postfix increment
constexpr CurrencyCodeIterator operator++(int) noexcept { // Postfix increment
CurrencyCodeIterator oldSelf = *this;
++*this;
return oldSelf;
}

CurrencyCodeIterator operator--(int) noexcept { // Postfix decrement
constexpr CurrencyCodeIterator operator--(int) noexcept { // Postfix decrement
CurrencyCodeIterator oldSelf = *this;
--*this;
return oldSelf;
}

char operator*() const noexcept { return CurrencyCodeBase::CharAt(_data, static_cast<int>(_pos)); }
constexpr char operator*() const noexcept { return CurrencyCodeBase::CharAt(_data, static_cast<int>(_pos)); }
// operator-> cannot be implemented here - we would need a const char * but it's not possible.

private:
friend class CurrencyCode;

// Default constructor needed for an iterator in C++20
explicit CurrencyCodeIterator(uint64_t data = 0, uint64_t pos = 0) noexcept : _data(data), _pos(pos) {}
constexpr explicit CurrencyCodeIterator(uint64_t data = 0, uint64_t pos = 0) noexcept : _data(data), _pos(pos) {}

uint64_t _data;
uint64_t _pos;
Expand Down Expand Up @@ -137,8 +138,8 @@ class CurrencyCode {
_data = CurrencyCodeBase::StrToBmp(acronym);
}

const_iterator begin() const { return const_iterator(_data); }
const_iterator end() const { return const_iterator(_data, size()); }
constexpr const_iterator begin() const { return const_iterator(_data); }
constexpr const_iterator end() const { return const_iterator(_data, size()); }

constexpr uint64_t size() const {
uint64_t sz = 0;
Expand All @@ -165,7 +166,7 @@ class CurrencyCode {
return false;
}
for (uint32_t charPos = 0; charPos < kMaxLen; ++charPos) {
char ch = (*this)[charPos];
const char ch = (*this)[charPos];
if (ch == CurrencyCodeBase::kFirstAuthorizedLetter) {
return curStr.size() == charPos;
}
Expand All @@ -178,16 +179,16 @@ class CurrencyCode {

/// Append currency string representation to given string.
void appendStrTo(string &str) const {
auto len = size();
const auto len = size();
str.append(len, '\0');
append(str.end() - len);
}

/// Append currency string representation to given output iterator
template <class OutputIt>
OutputIt append(OutputIt it) const {
constexpr OutputIt append(OutputIt it) const {
for (uint32_t charPos = 0; charPos < kMaxLen; ++charPos) {
char ch = (*this)[charPos];
const char ch = (*this)[charPos];
if (ch == CurrencyCodeBase::kFirstAuthorizedLetter) {
break;
}
Expand All @@ -205,13 +206,13 @@ class CurrencyCode {
constexpr char operator[](uint32_t pos) const { return CurrencyCodeBase::CharAt(_data, static_cast<int>(pos)); }

/// Note that this respects the lexicographical order - chars are encoded from the most significant bits first
constexpr auto operator<=>(const CurrencyCode &) const noexcept = default;
constexpr std::strong_ordering operator<=>(const CurrencyCode &) const noexcept = default;

constexpr bool operator==(const CurrencyCode &) const noexcept = default;

friend std::ostream &operator<<(std::ostream &os, const CurrencyCode &cur) {
for (uint32_t charPos = 0; charPos < kMaxLen; ++charPos) {
char ch = cur[charPos];
const char ch = cur[charPos];
if (ch == CurrencyCodeBase::kFirstAuthorizedLetter) {
break;
}
Expand Down Expand Up @@ -257,7 +258,7 @@ class CurrencyCode {

/// Append currency string representation to given string, with a space before (used by MonetaryAmount)
void appendStrWithSpaceTo(string &str) const {
auto len = size();
const auto len = size();
str.append(len + 1UL, ' ');
append(str.end() - len);
}
Expand All @@ -269,7 +270,8 @@ class CurrencyCode {
template <>
struct fmt::formatter<cct::CurrencyCode> {
constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin(), end = ctx.end();
const auto it = ctx.begin();
const auto end = ctx.end();
if (it != end && *it != '}') {
throw format_error("invalid format");
}
Expand Down
4 changes: 2 additions & 2 deletions src/objects/include/currencyexchange.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#pragma once

#include <compare>
#include <cstdint>
#include <ostream>
#include <string_view>

#include "cct_string.hpp"
#include "currencycode.hpp"
Expand Down Expand Up @@ -50,7 +50,7 @@ class CurrencyExchange {
bool isFiat() const { return _isFiat; }

// Compare by standard code first.
constexpr auto operator<=>(const CurrencyExchange &) const noexcept = default;
constexpr std::strong_ordering operator<=>(const CurrencyExchange &) const noexcept = default;

constexpr bool operator==(const CurrencyExchange &) const noexcept = default;

Expand Down
18 changes: 8 additions & 10 deletions src/objects/include/exchangename.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ class ExchangeName {
ExchangeName(std::string_view exchangeName, std::string_view keyName);

std::string_view name() const {
std::size_t underscore = underscorePos();
const std::size_t underscore = underscorePos();
return std::string_view(_nameWithKey.data(), underscore == string::npos ? _nameWithKey.size() : underscore);
}

std::string_view keyName() const {
std::size_t underscore = underscorePos();
return std::string_view(_nameWithKey.begin() + (underscore == string::npos ? _nameWithKey.size() : underscore + 1U),
_nameWithKey.end());
const std::size_t underscore = underscorePos();
return {_nameWithKey.begin() + (underscore == string::npos ? _nameWithKey.size() : underscore + 1U),
_nameWithKey.end()};
}

bool isKeyNameDefined() const { return underscorePos() != string::npos; }
Expand All @@ -45,10 +45,7 @@ class ExchangeName {

bool operator==(const ExchangeName &) const noexcept = default;

friend std::ostream &operator<<(std::ostream &os, const ExchangeName &v) {
os << v.str();
return os;
}
friend std::ostream &operator<<(std::ostream &os, const ExchangeName &rhs) { return os << rhs.str(); }

using trivially_relocatable = is_trivially_relocatable<string>::type;

Expand All @@ -64,7 +61,7 @@ class ExchangeName {
};

using ExchangeNameSpan = std::span<const ExchangeName>;
using ExchangeNames = SmallVector<ExchangeName, kTypicalNbPrivateAccounts>;
using ExchangeNames = SmallVector<ExchangeName, 1>;

inline std::string_view ToString(std::string_view exchangeName) { return exchangeName; }
inline std::string_view ToString(const ExchangeName &exchangeName) { return exchangeName.str(); }
Expand Down Expand Up @@ -95,7 +92,8 @@ struct fmt::formatter<cct::ExchangeName> {
bool printKeyName = false;

constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin(), end = ctx.end();
auto it = ctx.begin();
const auto end = ctx.end();
if (it == end || *it == '}') {
printExchangeName = true;
printKeyName = true;
Expand Down
3 changes: 1 addition & 2 deletions src/objects/include/loadconfiguration.hpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#pragma once

#include <cstdint>
#include <string_view>

#include "cct_const.hpp"

namespace cct {
class LoadConfiguration {
public:
Expand Down
4 changes: 2 additions & 2 deletions src/objects/include/market.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#include <array>
#include <ostream>
#include <utility>

#include "cct_format.hpp"
#include "cct_string.hpp"
Expand Down Expand Up @@ -70,7 +69,8 @@ class Market {
template <>
struct fmt::formatter<cct::Market> {
constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin(), end = ctx.end();
auto it = ctx.begin();
const auto end = ctx.end();
if (it != end && *it != '}') {
throw format_error("invalid format");
}
Expand Down
1 change: 0 additions & 1 deletion src/objects/include/marketorderbook.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#pragma once

#include <limits>
#include <optional>
#include <span>
#include <string_view>
Expand Down
1 change: 1 addition & 0 deletions src/objects/include/monetaryamount.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class MonetaryAmount {
/// Constructs a new MonetaryAmount from a string, containing an optional CurrencyCode.
/// - If a currency is not present, assume default CurrencyCode
/// - If the currency is too long to fit in a CurrencyCode, exception will be raised
/// - If only a currency is given, invalid_argument exception will be raised
/// - If given string is empty, it is equivalent to a default constructor
///
/// A space can be present or not between the amount and the currency code.
Expand Down
1 change: 0 additions & 1 deletion src/objects/include/priceoptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "cct_string.hpp"
#include "monetaryamount.hpp"
#include "priceoptionsdef.hpp"
#include "timedef.hpp"

namespace cct {
class PriceOptions {
Expand Down
2 changes: 1 addition & 1 deletion src/objects/include/volumeandpricenbdecimals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace cct {
struct VolAndPriNbDecimals {
constexpr bool operator==(const VolAndPriNbDecimals &o) const = default;
constexpr bool operator==(const VolAndPriNbDecimals &) const noexcept = default;

int8_t volNbDecimals = std::numeric_limits<uintmax_t>::digits10;
int8_t priNbDecimals = std::numeric_limits<uintmax_t>::digits10;
Expand Down
3 changes: 2 additions & 1 deletion src/objects/include/wallet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ class Wallet {
template <>
struct fmt::formatter<cct::Wallet> {
constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin(), end = ctx.end();
auto it = ctx.begin();
const auto end = ctx.end();
if (it != end && *it != '}') {
throw format_error("invalid format");
}
Expand Down
4 changes: 4 additions & 0 deletions src/objects/src/monetaryamount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "cct_config.hpp"
#include "cct_exception.hpp"
#include "cct_invalid_argument_exception.hpp"
#include "currencycode.hpp"
#include "mathhelpers.hpp"
#include "stringhelpers.hpp"
Expand Down Expand Up @@ -155,6 +156,9 @@ MonetaryAmount::MonetaryAmount(std::string_view amountCurrencyStr) {
std::string_view currencyStr(last, endIt);
RemoveTrailingSpaces(currencyStr);
RemovePrefixSpaces(currencyStr);
if (!currencyStr.empty() && amountStr.empty()) {
throw invalid_argument("Cannot construct MonetaryAmount with a currency without any amount");
}
_curWithDecimals = CurrencyCode(currencyStr);
sanitizeDecimals(nbDecimals, maxNbDecimals());
}
Expand Down
14 changes: 14 additions & 0 deletions src/objects/test/currencycode_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,23 @@ TEST(CurrencyCodeTest, UpperConversion) {
EXPECT_EQ(CurrencyCode("etc").str(), "ETC");
}

namespace {
constexpr bool HasZ(CurrencyCode cur) {
for (char ch : cur) {
if (ch == 'Z') {
return true;
}
}
return false;
}
} // namespace

TEST(CurrencyCodeTest, Constexpr) {
static_assert(CurrencyCode("doge") == CurrencyCode("DOGE"));
static_assert(CurrencyCode("XRP").code() != 0);

static_assert(!HasZ(CurrencyCode("LONGCUR")));
static_assert(HasZ(CurrencyCode("GTZFD")));
}

TEST(CurrencyCodeTest, Iterator) {
Expand Down
6 changes: 6 additions & 0 deletions src/objects/test/monetaryamount_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <optional>

#include "cct_exception.hpp"
#include "cct_invalid_argument_exception.hpp"
#include "cct_string.hpp"
#include "currencycode.hpp"
#include "mathhelpers.hpp"
Expand Down Expand Up @@ -180,6 +181,8 @@ TEST(MonetaryAmountTest, OverflowProtectionMultiplication) {
MonetaryAmount("0.00426622338114037", cur));
EXPECT_EQ(MonetaryAmount("38.0566894350664") * MonetaryAmount("0.00008795", cur),
MonetaryAmount("0.00334708583581405", cur));
EXPECT_EQ((-1) * MonetaryAmount("-9223372036854775807", cur), MonetaryAmount("922337203685477580", cur));
EXPECT_EQ((-1) * MonetaryAmount("-922337203685477580", cur), MonetaryAmount("922337203685477580", cur));
}
}

Expand Down Expand Up @@ -238,10 +241,13 @@ TEST(MonetaryAmountTest, StringConstructor) {
EXPECT_EQ(MonetaryAmount("-210.50 CAKE"), MonetaryAmount("-210.50", "CAKE"));
EXPECT_EQ(MonetaryAmount("05AUD"), MonetaryAmount(5, "AUD"));
EXPECT_EQ(MonetaryAmount("746REPV2"), MonetaryAmount("746", "REPV2"));

EXPECT_THROW(MonetaryAmount("usdt"), invalid_argument);
}

TEST(MonetaryAmountTest, StringConstructorAmbiguity) {
EXPECT_EQ(MonetaryAmount("804.621INCH"), MonetaryAmount("804.621", "INCH"));
EXPECT_EQ(MonetaryAmount("804.62 1INCH"), MonetaryAmount("804.62", "1INCH"));
EXPECT_EQ(MonetaryAmount("804.62", "1INCH"), MonetaryAmount("804.62", "1INCH"));
}

Expand Down
8 changes: 6 additions & 2 deletions src/tech/include/stringhelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <concepts>
#include <cstring>
#include <string_view>
#include <system_error>

#include "cct_config.hpp"
#include "cct_exception.hpp"
Expand All @@ -30,9 +31,12 @@ inline string ToString(std::integral auto i) {

template <std::integral Integral>
Integral FromString(std::string_view str) {
Integral ret;
Integral ret{};
if (auto [ptr, errc] = std::from_chars(str.data(), str.data() + str.size(), ret); CCT_UNLIKELY(errc != std::errc())) {
throw exception("Unable to decode string into integral");
if (errc == std::errc::result_out_of_range) {
throw exception("'{}' would produce an out of range integral", str);
}
throw exception("Unable to decode '{}' into integral", str);
}
return ret;
}
Expand Down
Loading