diff --git a/include/io1/money.hpp b/include/io1/money.hpp index 59ecaf1..cbebfd3 100644 --- a/include/io1/money.hpp +++ b/include/io1/money.hpp @@ -15,14 +15,6 @@ #include #include -namespace io1 -{ - class money; -} - -template -constexpr io1::money operator""_money(void) noexcept; - namespace io1 { class money @@ -49,9 +41,6 @@ namespace io1 template explicit constexpr money(T amount) noexcept = delete; - template - friend constexpr money(::operator""_money)(void) noexcept; - [[nodiscard]] constexpr value_type const & data(void) const noexcept { return amount_; } [[nodiscard]] constexpr money operator++(int) noexcept { return money{amount_++}; } @@ -120,7 +109,6 @@ namespace io1 }; private: - struct StringLitteralDecoder; struct PutMoney; struct GetMoney; @@ -203,52 +191,55 @@ namespace io1 } // Helper structure to build a io1::Money object from a user-defined string litteral - struct money::StringLitteralDecoder + namespace detail { - public: - template - [[nodiscard]] constexpr static money apply(void) noexcept + struct StringLitteralDecoder { - return money{parse_mantissa<0, STR...>()}; - } + public: + template + [[nodiscard]] constexpr static money apply(void) noexcept + { + return money{parse_mantissa<0, STR...>()}; + } - private: - template - [[nodiscard]] constexpr static value_type parse_digit(void) noexcept - { - static_assert('0' <= DIGIT && '9' >= DIGIT, "Unexpected digit!"); + private: + template + [[nodiscard]] constexpr static money::value_type parse_digit(void) noexcept + { + static_assert('0' <= DIGIT && '9' >= DIGIT, "Unexpected digit!"); - constexpr auto d = static_cast(DIGIT - '0'); - constexpr auto ten = static_cast(10); + constexpr auto d = static_cast(DIGIT - '0'); + constexpr auto ten = static_cast(10); - static_assert(CURRENT_MANTISSA >= 0, "Parsing a raw user-defined litteral."); - static_assert((std::numeric_limits::max() - d) / ten >= CURRENT_MANTISSA, - "Number not representable by io1::Money"); + static_assert(CURRENT_MANTISSA >= 0, "Parsing a raw user-defined litteral."); + static_assert((std::numeric_limits::max() - d) / ten >= CURRENT_MANTISSA, + "Number not representable by io1::Money"); - return ten * CURRENT_MANTISSA + d; - } + return ten * CURRENT_MANTISSA + d; + } - template - [[nodiscard]] constexpr static bool not_a_digit(void) noexcept - { - return (DIGIT == '.' || DIGIT == '\''); - } + template + [[nodiscard]] constexpr static bool not_a_digit(void) noexcept + { + return (DIGIT == '.' || DIGIT == '\''); + } - template - constexpr static value_type parse_mantissa(void) noexcept - { - constexpr auto new_mantissa = []() + template + constexpr static money::value_type parse_mantissa(void) noexcept { - if constexpr (not_a_digit()) return CURRENT_MANTISSA; + constexpr auto new_mantissa = []() + { + if constexpr (not_a_digit()) return CURRENT_MANTISSA; + else + return parse_digit(); + }(); + + if constexpr (0 < sizeof...(STR)) return parse_mantissa(); else - return parse_digit(); - }(); - - if constexpr (0 < sizeof...(STR)) return parse_mantissa(); - else - return new_mantissa; - } - }; + return new_mantissa; + } + }; + } // namespace detail inline std::ostream & operator<<(std::ostream & stream, io1::money m) noexcept { @@ -344,14 +335,16 @@ namespace io1 return {.quot = money(result.quot), .rem = money(result.rem)}; } + inline namespace literals + { + template + constexpr io1::money operator""_money(void) noexcept + { + return io1::detail::StringLitteralDecoder::apply(); + } + } // namespace literals } // namespace io1 -template -constexpr io1::money operator""_money(void) noexcept -{ - return io1::money::StringLitteralDecoder::apply(); -} - template struct std::formatter { diff --git a/test/test_money.cpp b/test/test_money.cpp index bb3cc02..993d4e3 100644 --- a/test/test_money.cpp +++ b/test/test_money.cpp @@ -9,6 +9,8 @@ #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include +using namespace io1::literals; + TEST_CASE("Value bounds") { [[maybe_unused]] constexpr auto max = 9'223'372'036'854'775'807_money; diff --git a/test/tutorial.cpp b/test/tutorial.cpp index 32a9212..351f9d6 100644 --- a/test/tutorial.cpp +++ b/test/tutorial.cpp @@ -6,6 +6,8 @@ #include #include +using namespace io1::literals; + class american_moneypunct_facet : public std::moneypunct { private: