Skip to content

Commit 27b0d0f

Browse files
committed
Now that errored status codes are status codes, we need to prevent
recursive make_status_code() ADL lookup when determining noexceptness.
1 parent b924f4a commit 27b0d0f

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

include/status-code/errored_status_code.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ template <class DomainType> class errored_status_code : public status_code<Domai
9696
&& !std::is_same<typename std::decay<T>::type, in_place_t>::value // not in_place_t
9797
&& is_status_code<MakeStatusCodeResult>::value // ADL makes a status code
9898
&& std::is_constructible<errored_status_code, MakeStatusCodeResult>::value)) // ADLed status code is compatible
99-
errored_status_code(T &&v, Args &&...args) noexcept(noexcept(make_status_code(std::declval<T>(),
100-
std::declval<Args>()...))) // NOLINT
99+
errored_status_code(T &&v,
100+
Args &&...args) noexcept(detail::safe_get_make_status_code_noexcept<T, Args...>::value) // NOLINT
101101
: errored_status_code(make_status_code(static_cast<T &&>(v), static_cast<Args &&>(args)...))
102102
{
103103
_check();
@@ -269,8 +269,8 @@ class errored_status_code<detail::erased<ErasedType>> : public status_code<detai
269269
&& !std::is_same<typename std::decay<T>::type, value_type>::value // not copy/move of value type
270270
&& is_status_code<MakeStatusCodeResult>::value // ADL makes a status code
271271
&& std::is_constructible<errored_status_code, MakeStatusCodeResult>::value)) // ADLed status code is compatible
272-
errored_status_code(T &&v, Args &&...args) noexcept(noexcept(make_status_code(std::declval<T>(),
273-
std::declval<Args>()...))) // NOLINT
272+
errored_status_code(T &&v,
273+
Args &&...args) noexcept(detail::safe_get_make_status_code_noexcept<T, Args...>::value) // NOLINT
274274
: errored_status_code(make_status_code(static_cast<T &&>(v), static_cast<Args &&>(args)...))
275275
{
276276
_check();

include/status-code/status_code.hpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Distributed under the Boost Software License, Version 1.0.
2727

2828
#include "status_code_domain.hpp"
2929

30-
#if(__cplusplus >= 201700 || _HAS_CXX17) && !defined(SYSTEM_ERROR2_DISABLE_STD_IN_PLACE)
30+
#if (__cplusplus >= 201700 || _HAS_CXX17) && !defined(SYSTEM_ERROR2_DISABLE_STD_IN_PLACE)
3131
// 0.26
3232
#include <utility> // for in_place
3333

@@ -226,6 +226,21 @@ namespace detail
226226
using type = typename impl::make_status_code_rettype<impl::types<Args...>>::type;
227227
};
228228
#endif
229+
230+
template <class T> struct safe_get_make_status_code_noexcept_select
231+
{
232+
static constexpr bool value = false;
233+
};
234+
template <> struct safe_get_make_status_code_noexcept_select<int>
235+
{
236+
static constexpr bool value = true;
237+
};
238+
template <class T, class... Args>
239+
using get_make_status_code_noexcept =
240+
typename std::conditional<noexcept(make_status_code(std::declval<T>(), std::declval<Args>()...)), int, void>::type;
241+
template <class T, class... Args>
242+
using safe_get_make_status_code_noexcept =
243+
safe_get_make_status_code_noexcept_select<test_apply<get_make_status_code_noexcept, Args...>>;
229244
} // namespace detail
230245

231246
//! Trait returning true if the type is a status code.
@@ -528,8 +543,8 @@ class SYSTEM_ERROR2_TRIVIAL_ABI status_code : public mixins::mixin<detail::statu
528543
&& !std::is_same<typename std::decay<T>::type, in_place_t>::value // not in_place_t
529544
&& is_status_code<MakeStatusCodeResult>::value // ADL makes a status code
530545
&& std::is_constructible<status_code, MakeStatusCodeResult>::value)) // ADLed status code is compatible
531-
constexpr status_code(T &&v, Args &&...args) noexcept(noexcept(make_status_code(std::declval<T>(),
532-
std::declval<Args>()...))) // NOLINT
546+
constexpr status_code(T &&v, Args &&...args) noexcept(
547+
detail::safe_get_make_status_code_noexcept<T, Args...>::value) // NOLINT
533548
: status_code(make_status_code(static_cast<T &&>(v), static_cast<Args &&>(args)...))
534549
{
535550
}
@@ -700,8 +715,8 @@ class SYSTEM_ERROR2_TRIVIAL_ABI status_code<detail::erased<ErasedType>>
700715
&& !std::is_same<typename std::decay<T>::type, value_type>::value // not copy/move of value type
701716
&& is_status_code<MakeStatusCodeResult>::value // ADL makes a status code
702717
&& std::is_constructible<status_code, MakeStatusCodeResult>::value)) // ADLed status code is compatible
703-
constexpr status_code(T &&v, Args &&...args) noexcept(noexcept(make_status_code(std::declval<T>(),
704-
std::declval<Args>()...))) // NOLINT
718+
constexpr status_code(T &&v, Args &&...args) noexcept(
719+
detail::safe_get_make_status_code_noexcept<T, Args...>::value) // NOLINT
705720
: status_code(make_status_code(static_cast<T &&>(v), static_cast<Args &&>(args)...))
706721
{
707722
}

0 commit comments

Comments
 (0)