diff --git a/src/api/common/src/ssl_sha.cpp b/src/api/common/src/ssl_sha.cpp index 6fb18fd0..bb4ab55d 100644 --- a/src/api/common/src/ssl_sha.cpp +++ b/src/api/common/src/ssl_sha.cpp @@ -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(binData, len)); diff --git a/src/main/src/main.cpp b/src/main/src/main.cpp index 96f2520d..20ae1fcf 100644 --- a/src/main/src/main.cpp +++ b/src/main/src/main.cpp @@ -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); diff --git a/src/objects/include/currencycode.hpp b/src/objects/include/currencycode.hpp index 02890bdc..7a4b3484 100644 --- a/src/objects/include/currencycode.hpp +++ b/src/objects/include/currencycode.hpp @@ -69,7 +69,7 @@ class CurrencyCodeIterator { using pointer = const char *; using reference = const char &; - constexpr auto operator<=>(const CurrencyCodeIterator &) const noexcept = default; + constexpr std::strong_ordering operator<=>(const CurrencyCodeIterator &) const noexcept = default; bool operator==(const CurrencyCodeIterator &) const noexcept = default; CurrencyCodeIterator &operator++() noexcept { // Prefix increment @@ -165,7 +165,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; } @@ -178,7 +178,7 @@ 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); } @@ -187,7 +187,7 @@ class CurrencyCode { template 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; } @@ -205,13 +205,13 @@ class CurrencyCode { constexpr char operator[](uint32_t pos) const { return CurrencyCodeBase::CharAt(_data, static_cast(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; } @@ -257,7 +257,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); } @@ -269,7 +269,8 @@ class CurrencyCode { template <> struct fmt::formatter { 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"); } diff --git a/src/objects/include/currencyexchange.hpp b/src/objects/include/currencyexchange.hpp index c95e8ddb..3869d95f 100644 --- a/src/objects/include/currencyexchange.hpp +++ b/src/objects/include/currencyexchange.hpp @@ -1,8 +1,8 @@ #pragma once +#include #include #include -#include #include "cct_string.hpp" #include "currencycode.hpp" @@ -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; diff --git a/src/objects/include/exchangename.hpp b/src/objects/include/exchangename.hpp index 780f20a2..7b997173 100644 --- a/src/objects/include/exchangename.hpp +++ b/src/objects/include/exchangename.hpp @@ -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; } @@ -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::type; @@ -64,7 +61,7 @@ class ExchangeName { }; using ExchangeNameSpan = std::span; -using ExchangeNames = SmallVector; +using ExchangeNames = SmallVector; inline std::string_view ToString(std::string_view exchangeName) { return exchangeName; } inline std::string_view ToString(const ExchangeName &exchangeName) { return exchangeName.str(); } @@ -95,7 +92,8 @@ struct fmt::formatter { 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; diff --git a/src/objects/include/loadconfiguration.hpp b/src/objects/include/loadconfiguration.hpp index 581ab07e..ce534a4d 100644 --- a/src/objects/include/loadconfiguration.hpp +++ b/src/objects/include/loadconfiguration.hpp @@ -1,9 +1,8 @@ #pragma once +#include #include -#include "cct_const.hpp" - namespace cct { class LoadConfiguration { public: diff --git a/src/objects/include/market.hpp b/src/objects/include/market.hpp index c87ee6f9..03491edc 100644 --- a/src/objects/include/market.hpp +++ b/src/objects/include/market.hpp @@ -2,7 +2,6 @@ #include #include -#include #include "cct_format.hpp" #include "cct_string.hpp" @@ -70,7 +69,8 @@ class Market { template <> struct fmt::formatter { 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"); } diff --git a/src/objects/include/marketorderbook.hpp b/src/objects/include/marketorderbook.hpp index 45a4fdd5..de396110 100644 --- a/src/objects/include/marketorderbook.hpp +++ b/src/objects/include/marketorderbook.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include diff --git a/src/objects/include/monetaryamount.hpp b/src/objects/include/monetaryamount.hpp index cd381fc4..3566acbc 100644 --- a/src/objects/include/monetaryamount.hpp +++ b/src/objects/include/monetaryamount.hpp @@ -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. diff --git a/src/objects/include/priceoptions.hpp b/src/objects/include/priceoptions.hpp index 09b3bbe0..e3534bac 100644 --- a/src/objects/include/priceoptions.hpp +++ b/src/objects/include/priceoptions.hpp @@ -5,7 +5,6 @@ #include "cct_string.hpp" #include "monetaryamount.hpp" #include "priceoptionsdef.hpp" -#include "timedef.hpp" namespace cct { class PriceOptions { diff --git a/src/objects/include/volumeandpricenbdecimals.hpp b/src/objects/include/volumeandpricenbdecimals.hpp index ad1ebbd5..38dc4e75 100644 --- a/src/objects/include/volumeandpricenbdecimals.hpp +++ b/src/objects/include/volumeandpricenbdecimals.hpp @@ -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::digits10; int8_t priNbDecimals = std::numeric_limits::digits10; diff --git a/src/objects/include/wallet.hpp b/src/objects/include/wallet.hpp index 8ab1145c..e1d908bb 100644 --- a/src/objects/include/wallet.hpp +++ b/src/objects/include/wallet.hpp @@ -88,7 +88,8 @@ class Wallet { template <> struct fmt::formatter { 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"); } diff --git a/src/objects/src/monetaryamount.cpp b/src/objects/src/monetaryamount.cpp index 8cdf4770..afb1c521 100644 --- a/src/objects/src/monetaryamount.cpp +++ b/src/objects/src/monetaryamount.cpp @@ -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" @@ -156,6 +157,9 @@ MonetaryAmount::MonetaryAmount(std::string_view amountCurrencyStr) { RemoveTrailingSpaces(currencyStr); RemovePrefixSpaces(currencyStr); _curWithDecimals = CurrencyCode(currencyStr); + if (!_curWithDecimals.isNeutral() && amountStr.empty()) { + throw invalid_argument("Cannot construct MonetaryAmount with a currency without any amount"); + } sanitizeDecimals(nbDecimals, maxNbDecimals()); } diff --git a/src/objects/test/monetaryamount_test.cpp b/src/objects/test/monetaryamount_test.cpp index a6d60fd3..47f49795 100644 --- a/src/objects/test/monetaryamount_test.cpp +++ b/src/objects/test/monetaryamount_test.cpp @@ -6,6 +6,7 @@ #include #include "cct_exception.hpp" +#include "cct_invalid_argument_exception.hpp" #include "cct_string.hpp" #include "currencycode.hpp" #include "mathhelpers.hpp" @@ -238,10 +239,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")); }