-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
The range adaptors defined in <ranges> strengthen noexcept more aggressively than much of the STL. Upon noticing that a couple of conditional noexcepts in transform_view were incorrect for non-zero IDL modes, I threw together some preprocessor stuffs to "turn off" a conditional noexcept in non-zero IDL:
Lines 1016 to 1020 in be0441c
| #if _ITERATOR_DEBUG_LEVEL == 0 | |
| #define _NOEXCEPT_IDL0(...) noexcept(__VA_ARGS__) | |
| #else | |
| #define _NOEXCEPT_IDL0(...) | |
| #endif // _ITERATOR_DEBUG_LEVEL == 0 |
So that precondition-checking machinery that calls user-provided functions:
Lines 1064 to 1067 in be0441c
| constexpr void _Check_dereference() const { | |
| _STL_VERIFY(_Parent != nullptr, "cannot dereference value-initialized transform_view iterator"); | |
| _STL_VERIFY(_Current != _RANGES end(_Parent->_Range), "cannot dereference end transform_view iterator"); | |
| } |
is usable from functions that want to provide conditional noexcept:
Lines 1112 to 1120 in be0441c
| _NODISCARD constexpr decltype(auto) operator*() const | |
| _NOEXCEPT_IDL0(noexcept(_STD invoke(*_Parent->_Fun, *_Current))) /* strengthened */ { | |
| #if _ITERATOR_DEBUG_LEVEL != 0 | |
| _Check_dereference(); | |
| _STL_VERIFY( | |
| _Parent->_Fun, "Cannot dereference iterator into transform_view with no transformation function"); | |
| #endif // _ITERATOR_DEBUG_LEVEL != 0 | |
| return _STD invoke(*_Parent->_Fun, *_Current); | |
| } |
This is a bit of a hack, and it was received as such. I've since observed that other range adaptors have the same problem and simply slam into noexcept:
Lines 876 to 882 in be0441c
| _NODISCARD friend constexpr range_rvalue_reference_t<_Vw> iter_move(const _Iterator& _It) noexcept( | |
| noexcept(_RANGES iter_move(_It._Current))) { | |
| #if _ITERATOR_DEBUG_LEVEL != 0 | |
| _It._Check_dereference(); | |
| #endif // _ITERATOR_DEBUG_LEVEL != 0 | |
| return _RANGES iter_move(_It._Current); | |
| } |
(Note that conditional noexcept on iter_move and iter_swap overloads is not strengthened, but Standard-mandated.)
We need to devise policy for how we want to handle conditional noexcept on functions that call user-provided in "debug" modes only, including both strengthened and non-strengthened cases.