diff --git a/include/boost/decimal/decimal128_t.hpp b/include/boost/decimal/decimal128_t.hpp index 81c942934..6483c1a2e 100644 --- a/include/boost/decimal/decimal128_t.hpp +++ b/include/boost/decimal/decimal128_t.hpp @@ -257,6 +257,13 @@ BOOST_DECIMAL_EXPORT class decimal128_t final #endif constexpr decimal128_t(T1 coeff, T2 exp, bool sign = false) noexcept; + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal128_t(T1, T2, bool) noexcept { static_assert(detail::is_unsigned_v, "Construction from signed integer, exponent, and sign is ambiguous, so it is disallowed. You must use an Unsigned Integer for the coefficient to construct from {coefficient, exponent, sign}"); } + #ifdef BOOST_DECIMAL_HAS_CONCEPTS template #else diff --git a/include/boost/decimal/decimal32_t.hpp b/include/boost/decimal/decimal32_t.hpp index e762187af..9aea4680c 100644 --- a/include/boost/decimal/decimal32_t.hpp +++ b/include/boost/decimal/decimal32_t.hpp @@ -282,6 +282,13 @@ BOOST_DECIMAL_EXPORT class decimal32_t final // NOLINT(cppcoreguidelines-special #endif constexpr decimal32_t(T1 coeff, T2 exp, bool sign = false) noexcept; + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal32_t(T1, T2, bool) noexcept { static_assert(detail::is_unsigned_v, "Construction from signed integer, exponent, and sign is ambiguous, so it is disallowed. You must use an Unsigned Integer for the coefficient to construct from {coefficient, exponent, sign}"); } + #ifdef BOOST_DECIMAL_HAS_CONCEPTS template #else diff --git a/include/boost/decimal/decimal64_t.hpp b/include/boost/decimal/decimal64_t.hpp index 11f2503f5..9e26c57d6 100644 --- a/include/boost/decimal/decimal64_t.hpp +++ b/include/boost/decimal/decimal64_t.hpp @@ -319,6 +319,13 @@ BOOST_DECIMAL_EXPORT class decimal64_t final #endif constexpr decimal64_t(T1 coeff, T2 exp, bool sign = false) noexcept; + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal64_t(T1, T2, bool) noexcept { static_assert(detail::is_unsigned_v, "Construction from signed integer, exponent, and sign is ambiguous, so it is disallowed. You must use an Unsigned Integer for the coefficient to construct from {coefficient, exponent, sign}"); } + #ifdef BOOST_DECIMAL_HAS_CONCEPTS template #else diff --git a/include/boost/decimal/decimal_fast128_t.hpp b/include/boost/decimal/decimal_fast128_t.hpp index abde71e8f..14825ca17 100644 --- a/include/boost/decimal/decimal_fast128_t.hpp +++ b/include/boost/decimal/decimal_fast128_t.hpp @@ -157,6 +157,13 @@ BOOST_DECIMAL_EXPORT class decimal_fast128_t final #endif constexpr decimal_fast128_t(T1 coeff, T2 exp, bool sign = false) noexcept; + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal_fast128_t(T1, T2, bool) noexcept { static_assert(detail::is_unsigned_v, "Construction from signed integer, exponent, and sign is ambiguous, so it is disallowed. You must use an Unsigned Integer for the coefficient to construct from {coefficient, exponent, sign}"); } + #ifdef BOOST_DECIMAL_HAS_CONCEPTS template #else diff --git a/include/boost/decimal/decimal_fast32_t.hpp b/include/boost/decimal/decimal_fast32_t.hpp index 0d8388edc..71405f541 100644 --- a/include/boost/decimal/decimal_fast32_t.hpp +++ b/include/boost/decimal/decimal_fast32_t.hpp @@ -150,6 +150,9 @@ BOOST_DECIMAL_EXPORT class decimal_fast32_t final template && detail::is_integral_v, bool> = true> constexpr decimal_fast32_t(T1 coeff, T2 exp, bool sign = false) noexcept; + template && detail::is_integral_v, bool> = true> + constexpr decimal_fast32_t(T1, T2, bool) noexcept { static_assert(detail::is_unsigned_v, "Construction from signed integer, exponent, and sign is ambiguous, so it is disallowed. You must use an Unsigned Integer for the coefficient to construct from {coefficient, exponent, sign}"); } + template && detail::is_integral_v, bool> = true> constexpr decimal_fast32_t(T1 coeff, T2 exp) noexcept; diff --git a/include/boost/decimal/decimal_fast64_t.hpp b/include/boost/decimal/decimal_fast64_t.hpp index 34477362b..c6584c289 100644 --- a/include/boost/decimal/decimal_fast64_t.hpp +++ b/include/boost/decimal/decimal_fast64_t.hpp @@ -168,6 +168,13 @@ BOOST_DECIMAL_EXPORT class decimal_fast64_t final #endif constexpr decimal_fast64_t(T1 coeff, T2 exp, bool sign = false) noexcept; + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal_fast64_t(T1, T2, bool) noexcept { static_assert(detail::is_unsigned_v, "Construction from signed integer, exponent, and sign is ambiguous, so it is disallowed. You must use an Unsigned Integer for the coefficient to construct from {coefficient, exponent, sign}"); } + #ifdef BOOST_DECIMAL_HAS_CONCEPTS template #else diff --git a/test/Jamfile b/test/Jamfile index 99ee847fe..b1817f974 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -66,6 +66,7 @@ run github_issue_1035.cpp ; run github_issue_1054.cpp ; run github_issue_1055.cpp ; run github_issue_1057.cpp ; +compile-fail github_issue_1087.cpp ; run link_1.cpp link_2.cpp link_3.cpp ; run quick.cpp ; run random_decimal32_comp.cpp ; diff --git a/test/github_issue_1087.cpp b/test/github_issue_1087.cpp new file mode 100644 index 000000000..a22c614e7 --- /dev/null +++ b/test/github_issue_1087.cpp @@ -0,0 +1,30 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1087 + +#include +#include + +using namespace boost::decimal; + +template +void test() +{ + T val {-3, 3, true}; + BOOST_TEST_EQ(val, T(UINT32_C(3), 3, true)); +} + +int main() +{ + test(); + test(); + test(); + + test(); + test(); + test(); + + return 0; +}