[libcxx-commits] [libcxx] [libc++] Remove _Lazy (PR #202303)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jun 8 02:50:37 PDT 2026
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/202303
We don't actually need to evaluate anything as lazily as `_Lazy` does, so we can get rid of it. This was required previously in some places due to a language defect, which has been resolved and implemented by all compilers we support.
>From 0e39d9e6a4d5f393aa944a2f62f8f78cc90b652a Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Mon, 8 Jun 2026 11:48:55 +0200
Subject: [PATCH] [libc++] Remove _Lazy
---
libcxx/include/CMakeLists.txt | 1 -
libcxx/include/__expected/expected.h | 12 +++---
libcxx/include/__type_traits/conjunction.h | 2 +-
libcxx/include/__type_traits/disjunction.h | 3 +-
libcxx/include/__type_traits/lazy.h | 25 ------------
libcxx/include/module.modulemap.in | 1 -
libcxx/include/tuple | 45 ++++++++++------------
7 files changed, 28 insertions(+), 61 deletions(-)
delete mode 100644 libcxx/include/__type_traits/lazy.h
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 10dfb4b4d58cb..1f79769f635da 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -898,7 +898,6 @@ set(files
__type_traits/is_void.h
__type_traits/is_volatile.h
__type_traits/is_within_lifetime.h
- __type_traits/lazy.h
__type_traits/make_32_64_or_128_bit.h
__type_traits/make_const_lvalue_ref.h
__type_traits/make_signed.h
diff --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h
index 27bc086698399..32ed81a392702 100644
--- a/libcxx/include/__expected/expected.h
+++ b/libcxx/include/__expected/expected.h
@@ -37,7 +37,6 @@
#include <__type_traits/is_trivially_destructible.h>
#include <__type_traits/is_trivially_relocatable.h>
#include <__type_traits/is_void.h>
-#include <__type_traits/lazy.h>
#include <__type_traits/negation.h>
#include <__type_traits/remove_cv.h>
#include <__type_traits/remove_cvref.h>
@@ -685,12 +684,11 @@ class expected : private __expected_base<_Tp, _Err> {
private:
template <class _OtherErrQual>
static constexpr bool __can_assign_from_unexpected =
- _And< is_constructible<_Err, _OtherErrQual>,
- is_assignable<_Err&, _OtherErrQual>,
- _Lazy<_Or,
- is_nothrow_constructible<_Err, _OtherErrQual>,
- is_nothrow_move_constructible<_Tp>,
- is_nothrow_move_constructible<_Err>> >::value;
+ _And<is_constructible<_Err, _OtherErrQual>,
+ is_assignable<_Err&, _OtherErrQual>,
+ _Or<is_nothrow_constructible<_Err, _OtherErrQual>,
+ is_nothrow_move_constructible<_Tp>,
+ is_nothrow_move_constructible<_Err>>>::value;
public:
template <class _OtherErr>
diff --git a/libcxx/include/__type_traits/conjunction.h b/libcxx/include/__type_traits/conjunction.h
index ad9656acd47ec..9d84ef8c0ca1b 100644
--- a/libcxx/include/__type_traits/conjunction.h
+++ b/libcxx/include/__type_traits/conjunction.h
@@ -34,7 +34,7 @@ false_type __and_helper(...);
//
// However, `_And<_Pred...>` itself will evaluate its result immediately (without having to
// be instantiated) since it is an alias, unlike `conjunction<_Pred...>`, which is a struct.
-// If you want to defer the evaluation of `_And<_Pred...>` itself, use `_Lazy<_And, _Pred...>`.
+// If you want to defer the evaluation, use `conjunction{,_v}<_Pred...>`.
template <class... _Pred>
using _And _LIBCPP_NODEBUG = decltype(std::__and_helper<_Pred...>(0));
diff --git a/libcxx/include/__type_traits/disjunction.h b/libcxx/include/__type_traits/disjunction.h
index 8e7a38413a985..40f571a3f0d54 100644
--- a/libcxx/include/__type_traits/disjunction.h
+++ b/libcxx/include/__type_traits/disjunction.h
@@ -38,8 +38,7 @@ struct _OrImpl<false> {
//
// However, `_Or<_Pred...>` itself will evaluate its result immediately (without having to
// be instantiated) since it is an alias, unlike `disjunction<_Pred...>`, which is a struct.
-// If you want to defer the evaluation of `_Or<_Pred...>` itself, use `_Lazy<_Or, _Pred...>`
-// or `disjunction<_Pred...>` directly.
+// If you want to defer the evaluation , use `disjunction{,_v}<_Pred...>`.
template <class... _Args>
using _Or _LIBCPP_NODEBUG = typename _OrImpl<sizeof...(_Args) != 0>::template _Result<false_type, _Args...>;
diff --git a/libcxx/include/__type_traits/lazy.h b/libcxx/include/__type_traits/lazy.h
deleted file mode 100644
index 80826f1d64f60..0000000000000
--- a/libcxx/include/__type_traits/lazy.h
+++ /dev/null
@@ -1,25 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___TYPE_TRAITS_LAZY_H
-#define _LIBCPP___TYPE_TRAITS_LAZY_H
-
-#include <__config>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <template <class...> class _Func, class... _Args>
-struct _Lazy : _Func<_Args...> {};
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___TYPE_TRAITS_LAZY_H
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 29f3818c39671..50d58c76c16bc 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -333,7 +333,6 @@ module std_core [system] {
export std_core.type_traits.integral_constant
}
module is_within_lifetime { header "__type_traits/is_within_lifetime.h" }
- module lazy { header "__type_traits/lazy.h" }
module make_32_64_or_128_bit { header "__type_traits/make_32_64_or_128_bit.h" }
module make_const_lvalue_ref { header "__type_traits/make_const_lvalue_ref.h" }
module make_signed { header "__type_traits/make_signed.h" }
diff --git a/libcxx/include/tuple b/libcxx/include/tuple
index d6d9e765934cd..d51b3f47275ec 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -255,7 +255,6 @@ template <class... Types>
# include <__type_traits/is_same.h>
# include <__type_traits/is_swappable.h>
# include <__type_traits/is_trivially_relocatable.h>
-# include <__type_traits/lazy.h>
# include <__type_traits/maybe_const.h>
# include <__type_traits/nat.h>
# include <__type_traits/negation.h>
@@ -597,22 +596,22 @@ public:
template <template <class...> class _IsImpDefault = __is_implicitly_default_constructible,
template <class...> class _IsDefault = is_default_constructible,
__enable_if_t< _And< _IsDefault<_Tp>... >::value, int> = 0>
- _LIBCPP_HIDE_FROM_ABI constexpr explicit(_Not<_Lazy<_And, _IsImpDefault<_Tp>...> >::value)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_And<_IsImpDefault<_Tp>...>::value)
tuple() noexcept(_And<is_nothrow_default_constructible<_Tp>...>::value) {}
template <class _Alloc,
template <class...> class _IsImpDefault = __is_implicitly_default_constructible,
template <class...> class _IsDefault = is_default_constructible,
__enable_if_t< _And< _IsDefault<_Tp>... >::value, int> = 0>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, _IsImpDefault<_Tp>...> >::value)
- tuple(allocator_arg_t, _Alloc const& __a)
+ _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(!_And<_IsImpDefault<_Tp>...>::value) tuple(allocator_arg_t, _Alloc const& __a)
: __base_(allocator_arg_t(), __a, __value_init{}) {}
// tuple(const T&...) constructors (including allocator_arg_t variants)
template <template <class...> class _And = _And,
__enable_if_t< _And< _BoolConstant<sizeof...(_Tp) >= 1>, is_copy_constructible<_Tp>... >::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI
- _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(_Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> >::value)
+ _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!_And<is_convertible<const _Tp&, _Tp>...>::value)
tuple(const _Tp&... __t) noexcept(_And<is_nothrow_copy_constructible<_Tp>...>::value)
: __base_(__forward_args{}, __t...) {}
@@ -620,7 +619,7 @@ public:
template <class...> class _And = _And,
__enable_if_t< _And< _BoolConstant<sizeof...(_Tp) >= 1>, is_copy_constructible<_Tp>... >::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI
- _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> >::value)
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(!_And<is_convertible<const _Tp&, _Tp>...>::value)
tuple(allocator_arg_t, const _Alloc& __a, const _Tp&... __t)
: __base_(allocator_arg_t(), __a, __forward_args{}, __t...) {}
@@ -639,7 +638,7 @@ public:
template <class... _Up,
__enable_if_t< _And< _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>, _EnableUTypesCtor<_Up...> >::value,
int> = 0>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!_And<is_convertible<_Up, _Tp>...>::value)
tuple(_Up&&... __u) noexcept(_And<is_nothrow_constructible<_Tp, _Up>...>::value)
: __base_(__forward_args{}, std::forward<_Up>(__u)...) {}
@@ -647,7 +646,7 @@ public:
class... _Up,
__enable_if_t< _And< _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>, _EnableUTypesCtor<_Up...> >::value,
int> = 0>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(!_And<is_convertible<_Up, _Tp>...>::value)
tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
: __base_(allocator_arg_t(), __a, __forward_args{}, std::forward<_Up>(__u)...) {}
@@ -685,18 +684,16 @@ public:
_Not<is_same<_OtherTuple, const tuple&> >,
_Not<is_same<_OtherTuple, tuple&&> >,
is_constructible<_Tp, __copy_cvref_t<_OtherTuple, _Up> >...,
- _Lazy<_Or,
- _BoolConstant<sizeof...(_Tp) != 1>,
- // _Tp and _Up are 1-element packs - the pack expansions look
- // weird to avoid tripping up the type traits in degenerate cases
- _Lazy<_And,
- _Not<is_same<_Tp, _Up> >...,
- _Not<is_convertible<_OtherTuple, _Tp> >...,
- _Not<is_constructible<_Tp, _OtherTuple> >... > > > {};
+ _Or<_BoolConstant<sizeof...(_Tp) != 1>,
+ // _Tp and _Up are 1-element packs - the pack expansions look
+ // weird to avoid tripping up the type traits in degenerate cases
+ _And<_Not<is_same<_Tp, _Up> >...,
+ _Not<is_convertible<_OtherTuple, _Tp> >...,
+ _Not<is_constructible<_Tp, _OtherTuple> >... > > > {};
template <class... _Up, __enable_if_t< _And< _EnableCtorFromUTypesTuple<const tuple<_Up...>&> >::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI
- _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(_Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> >::value)
+ _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!_And<is_convertible<const _Up&, _Tp>...>::value)
tuple(const tuple<_Up...>& __t) noexcept(_And<is_nothrow_constructible<_Tp, const _Up&>...>::value)
: __base_(__from_tuple(), __t) {}
@@ -704,7 +701,7 @@ public:
class _Alloc,
__enable_if_t< _And< _EnableCtorFromUTypesTuple<const tuple<_Up...>&> >::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI
- _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> >::value)
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(!_And<is_convertible<const _Up&, _Tp>...>::value)
tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
: __base_(allocator_arg_t(), __a, __from_tuple(), __t) {}
@@ -712,25 +709,25 @@ public:
// tuple(tuple<U...>&) constructors (including allocator_arg_t variants)
template <class... _Up, enable_if_t< _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr>
- _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_Lazy<_And, is_convertible<_Up&, _Tp>...>::value) tuple(tuple<_Up...>& __t)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_And<is_convertible<_Up&, _Tp>...>::value) tuple(tuple<_Up...>& __t)
: __base_(__from_tuple(), __t) {}
template <class _Alloc, class... _Up, enable_if_t< _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr>
- _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_Lazy<_And, is_convertible<_Up&, _Tp>...>::value)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_And<is_convertible<_Up&, _Tp>...>::value)
tuple(allocator_arg_t, const _Alloc& __alloc, tuple<_Up...>& __t)
: __base_(allocator_arg_t(), __alloc, __from_tuple(), __t) {}
# endif // _LIBCPP_STD_VER >= 23
// tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
template <class... _Up, __enable_if_t< _And< _EnableCtorFromUTypesTuple<tuple<_Up...>&&> >::value, int> = 0>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!_And<is_convertible<_Up, _Tp>...>::value)
tuple(tuple<_Up...>&& __t) noexcept(_And<is_nothrow_constructible<_Tp, _Up>...>::value)
: __base_(__from_tuple(), std::move(__t)) {}
template <class _Alloc,
class... _Up,
__enable_if_t< _And< _EnableCtorFromUTypesTuple<tuple<_Up...>&&> >::value, int> = 0>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(!_And<is_convertible<_Up, _Tp>...>::value)
tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
: __base_(allocator_arg_t(), __a, __from_tuple(), std::move(__t)) {}
@@ -738,14 +735,14 @@ public:
// tuple(const tuple<U...>&&) constructors (including allocator_arg_t variants)
template <class... _Up, enable_if_t< _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr>
- _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_Lazy<_And, is_convertible<const _Up&&, _Tp>...>::value)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_And<is_convertible<const _Up&&, _Tp>...>::value)
tuple(const tuple<_Up...>&& __t)
: __base_(__from_tuple(), std::move(__t)) {}
template <class _Alloc,
class... _Up,
enable_if_t< _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr>
- _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_Lazy<_And, is_convertible<const _Up&&, _Tp>...>::value)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_And<is_convertible<const _Up&&, _Tp>...>::value)
tuple(allocator_arg_t, const _Alloc& __alloc, const tuple<_Up...>&& __t)
: __base_(allocator_arg_t(), __alloc, __from_tuple(), std::move(__t)) {}
# endif // _LIBCPP_STD_VER >= 23
More information about the libcxx-commits
mailing list