[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 3183c02 2/5: Make an operator 'consteval'
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 3183c02 2/5: Make an operator 'consteval' |
Date: |
Tue, 11 May 2021 12:03:52 -0400 (EDT) |
branch: master
commit 3183c028598fa7f1ea159bacd05a2c29012a7e89
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Make an operator 'consteval'
As shown in the unit test, any misuse is now a compile-time error, even
outside a constexpr context.
Incidentally simplified the error message, which can appear only at
compile time, e.g.:
in ‘constexpr’ expansion of ‘operator""_cents(9007199254740993)’
error: expression ‘<throw-expression>’ is not a constant expression
79 | : throw std::domain_error("outside currency domain")
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
so extra code to print the value a second time is unwarranted.
---
currency.hpp | 8 +++-----
currency_test.cpp | 25 ++++++-------------------
2 files changed, 9 insertions(+), 24 deletions(-)
diff --git a/currency.hpp b/currency.hpp
index d2c6e2b..3aa2037 100644
--- a/currency.hpp
+++ b/currency.hpp
@@ -28,7 +28,6 @@
#include <limits>
#include <ostream>
#include <stdexcept> // runtime_error
-#include <string> // to_string()
#include <vector>
class raw_cents {}; // Tag class.
@@ -39,7 +38,7 @@ class currency
friend currency from_cents(double); // private ctor
template<typename> friend class round_to; // private ctor
friend class round_to_test; // currency::cents_digits
- friend constexpr currency operator""_cents(unsigned long long int);
+ friend consteval currency operator""_cents(unsigned long long int);
static constexpr int cents_digits = 2;
static constexpr double cents_per_dollar = 100.0;
@@ -70,15 +69,14 @@ class currency
data_type m_ = {};
};
-inline constexpr currency operator""_cents(unsigned long long int cents)
+consteval currency operator""_cents(unsigned long long int cents)
{
constexpr auto mant_dig = std::numeric_limits<currency::data_type>::digits;
constexpr unsigned long long int limit = 1ULL << mant_dig;
return
cents <= limit
? currency(static_cast<currency::data_type>(cents), raw_cents{})
- : throw std::runtime_error
- ("currency: " + std::to_string(cents) + " out of bounds");
+ : throw std::domain_error("outside currency domain")
;
}
diff --git a/currency_test.cpp b/currency_test.cpp
index c0f08f2..02150dd 100644
--- a/currency_test.cpp
+++ b/currency_test.cpp
@@ -163,26 +163,13 @@ void currency_test::test_literals()
currency const nc9007199254740992( -9007199254740992_cents);
LMI_TEST_EQUAL( -9007199254740992, nc9007199254740992.m_);
- // These are run-time errors:
- LMI_TEST_THROW
- (9007199254740993_cents
- ,std::runtime_error
- ,"currency: 9007199254740993 out of bounds"
- );
- // In this error message, the positive literal is invalid, so
- // an exception is thrown before the return value can be negated.
- LMI_TEST_THROW
- (-9007199254740993_cents
- ,std::runtime_error
- ,"currency: 9007199254740993 out of bounds"
- );
-
- // These are evaluated at compile time:
- constexpr currency compile_time_constant_pos( 9007199254740992_cents);
- constexpr currency compile_time_constant_neg(-9007199254740992_cents);
+ // These are evaluated at compile time, even though this is not
+ // a constexpr context:
+ auto compile_time_constant_pos( 9007199254740992_cents);
+ auto compile_time_constant_neg(-9007199254740992_cents);
// These would be compile-time errors:
-// constexpr currency error_at_compile_time_pos( 9007199254740993_cents);
-// constexpr currency error_at_compile_time_neg(-9007199254740993_cents);
+// auto error_at_compile_time_pos( 9007199254740993_cents);
+// auto error_at_compile_time_neg(-9007199254740993_cents);
}
void currency_test::test_negation()