@@ -237,21 +237,6 @@ constexpr decltype(auto) get(ltpl::Tuple<T...>& tuple) noexcept
237237 }(std::make_index_sequence<I>{});
238238}
239239
240- constexpr bool all_true (Access) noexcept { return true ; }
241-
242- template <std::size_t N>
243- constexpr bool all_true (bool const (&array)[N]) noexcept
244- {
245- for (bool ok : array)
246- {
247- if (!ok)
248- {
249- return false ;
250- }
251- }
252- return true ;
253- }
254-
255240struct TupleCatIndex
256241{
257242 std::size_t outer;
@@ -276,8 +261,8 @@ class Tuple
276261 ~Tuple () = default ;
277262
278263 // Non-empty Tuple, default construct all elements.
279- constexpr Tuple () //
280- noexcept (detail::all_true({ detail::NothrowDefaultAndMoveConstructible<T>...} )) //
264+ constexpr Tuple () //
265+ noexcept (( detail::NothrowDefaultAndMoveConstructible<T> && ... && true )) //
281266 requires(sizeof ...(T) > 0)
282267 : lambda(detail::make_lambda<T...>(T()...))
283268 {
@@ -290,21 +275,21 @@ class Tuple
290275 // If every element of the Tuple can be implicitly constructed from the arguments then this constructor is also
291276 // implicit.
292277 template <class ... U>
293- constexpr explicit (!detail::all_true({ std::is_convertible_v<U, T>...})) //
294- Tuple(U&&... v) //
295- noexcept (detail::all_true({ std::is_nothrow_constructible_v<T, U>...} )) //
296- requires(sizeof ...(T) == sizeof...(U) && sizeof...(T) >= 1 &&
297- detail::all_true({std::is_constructible_v<T, U>...}) && detail:: is_not_exactly_v<Tuple, U...>)
278+ constexpr explicit ((! std::is_convertible_v<U, T> || ... || false )) //
279+ Tuple(U&&... v) //
280+ noexcept (( std::is_nothrow_constructible_v<T, U> && ... && true )) //
281+ requires(sizeof ...(T) == sizeof...(U) && sizeof...(T) >= 1 && (std::is_constructible_v<T, U> && ... && true ) &&
282+ detail::is_not_exactly_v<Tuple, U...>)
298283 : lambda(detail::make_lambda<T...>(detail::Wrap<T>::wrap(static_cast <U&&>(v))...))
299284 {
300285 }
301286
302287 // Converting copy constructor
303288 template <class ... U>
304- constexpr explicit (!detail::all_true({ std::is_convertible_v<const U&, T>...})) //
305- Tuple(const Tuple<U...>& other) //
306- noexcept (detail::all_true({ std::is_nothrow_constructible_v<T, const U&>...} )) //
307- requires(sizeof ...(T) == sizeof...(U) && detail::all_true({ std::is_constructible_v<T, const U&>...} ) &&
289+ constexpr explicit ((! std::is_convertible_v<const U&, T> || ... || false )) //
290+ Tuple(const Tuple<U...>& other) //
291+ noexcept (( std::is_nothrow_constructible_v<T, const U&> && ... && true )) //
292+ requires(sizeof ...(T) == sizeof...(U) && ( std::is_constructible_v<T, const U&> && ... && true ) &&
308293 detail::is_converting_copy_constructor_v<Tuple, U...>)
309294 // We have to const_cast because the lambda's operator() is mutable. But since we cast each element to const& no
310295 // UB can occur.
@@ -318,10 +303,10 @@ class Tuple
318303
319304 // Converting move constructor
320305 template <class ... U>
321- constexpr explicit (!detail::all_true({ std::is_convertible_v<U, T>...})) //
322- Tuple(Tuple<U...>&& other) //
323- noexcept (detail::all_true({ std::is_nothrow_constructible_v<T, const U&>...} )) //
324- requires(sizeof ...(T) == sizeof...(U) && detail::all_true({ std::is_constructible_v<T, U>...} ) &&
306+ constexpr explicit ((! std::is_convertible_v<U, T> || ... || false )) //
307+ Tuple(Tuple<U...>&& other) //
308+ noexcept (( std::is_nothrow_constructible_v<T, const U&> && ... && true )) //
309+ requires(sizeof ...(T) == sizeof...(U) && ( std::is_constructible_v<T, U> && ... && true ) &&
325310 detail::is_converting_move_constructor_v<Tuple, U...>)
326311 : lambda(other.lambda(
327312 [](detail::WrapT<U>&... v_other)
@@ -342,9 +327,9 @@ class Tuple
342327
343328 // Converting copy-assignment operator.
344329 template <class ... U>
345- constexpr Tuple& operator =(const Tuple<U...>& other) //
346- noexcept (detail::all_true({ std::is_nothrow_assignable_v<T&, const U&>...} )) //
347- requires (sizeof ...(T) == sizeof ...(U) && detail::all_true({ std::is_assignable_v<T&, const U&>...} ))
330+ constexpr Tuple& operator =(const Tuple<U...>& other) //
331+ noexcept (( std::is_nothrow_assignable_v<T&, const U&> && ... && true )) //
332+ requires (sizeof ...(T) == sizeof ...(U) && ( std::is_assignable_v<T&, const U&> && ... && true ))
348333 {
349334 lambda (
350335 [&other](detail::WrapT<T>&... t)
@@ -362,9 +347,9 @@ class Tuple
362347
363348 // Converting move-assignment operator.
364349 template <class ... U>
365- constexpr Tuple& operator =(Tuple<U...>&& other) //
366- noexcept (detail::all_true({ std::is_nothrow_assignable_v<T&, U>...} )) //
367- requires (sizeof ...(T) == sizeof ...(U) && detail::all_true({ std::is_assignable_v<T&, U>...} ))
350+ constexpr Tuple& operator =(Tuple<U...>&& other) //
351+ noexcept (( std::is_nothrow_assignable_v<T&, U> && ... && true )) //
352+ requires (sizeof ...(T) == sizeof ...(U) && ( std::is_assignable_v<T&, U> && ... && true ))
368353 {
369354 lambda (
370355 [&other](detail::WrapT<T>&... t)
@@ -381,7 +366,7 @@ class Tuple
381366 // This comparison operator is SFINAE friendly, which is not required by the C++20 standard.
382367 template <class ... U>
383368 [[nodiscard]] friend constexpr bool operator ==(const Tuple& lhs, const Tuple<U...>& rhs) //
384- requires (sizeof ...(T) == sizeof ...(U) && (true && ... && detail::WeaklyEqualityComparableWith<T, U> ))
369+ requires (sizeof ...(T) == sizeof ...(U) && (detail::WeaklyEqualityComparableWith<T, U> && ... && true ))
385370 {
386371 return const_cast <Tuple&>(lhs).lambda (
387372 [&rhs](const detail::WrapT<T>&... v_lhs)
@@ -395,9 +380,9 @@ class Tuple
395380 }
396381
397382 template <class ... U>
398- friend constexpr void swap (Tuple& lhs, Tuple& rhs) //
399- noexcept (detail::all_true({ std::is_nothrow_swappable_v<T>...} )) //
400- requires(detail::all_true({ std::is_swappable_v<T>...} ))
383+ friend constexpr void swap (Tuple& lhs, Tuple& rhs) //
384+ noexcept (( std::is_nothrow_swappable_v<T> && ... && true )) //
385+ requires(( std::is_swappable_v<T> && ... && true ))
401386 {
402387 return lhs.lambda (
403388 [&rhs](detail::WrapT<T>&... v_lhs)
@@ -413,9 +398,9 @@ class Tuple
413398
414399 // C++23 overload of swap.
415400 template <class ... U>
416- friend constexpr void swap (const Tuple& lhs, const Tuple& rhs) //
417- noexcept (detail::all_true({ std::is_nothrow_swappable_v<const T>...} )) //
418- requires(detail::all_true({ std::is_swappable_v<const T>...} ))
401+ friend constexpr void swap (const Tuple& lhs, const Tuple& rhs) //
402+ noexcept (( std::is_nothrow_swappable_v<const T> && ... && true )) //
403+ requires(( std::is_swappable_v<const T> && ... && true ))
419404 {
420405 return const_cast <Tuple&>(lhs).lambda (
421406 [&rhs](const detail::WrapT<T>&... v_lhs)
0 commit comments