[libcxx-commits] [libcxx] [libc++] Add __detected_or_t and use it to implement some of the allocator traits aliases (PR #115654)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Nov 17 02:09:10 PST 2024
https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/115654
>From 811186764d1add4d83972db3ad0d2e7c96bb15a7 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sat, 16 Nov 2024 19:23:20 +0100
Subject: [PATCH 1/2] [libc++] Fix a few problems found by clang-tidy
---
libcxx/include/__flat_map/flat_map.h | 4 ++--
libcxx/include/__locale_dir/locale_base_api.h | 6 +++---
libcxx/include/__ranges/to.h | 8 ++++----
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/libcxx/include/__flat_map/flat_map.h b/libcxx/include/__flat_map/flat_map.h
index 073b63cd8f0a66..58b362ad7a706f 100644
--- a/libcxx/include/__flat_map/flat_map.h
+++ b/libcxx/include/__flat_map/flat_map.h
@@ -113,7 +113,7 @@ class flat_map {
class value_compare {
private:
key_compare __comp_;
- value_compare(key_compare __c) : __comp_(__c) {}
+ _LIBCPP_HIDE_FROM_ABI value_compare(key_compare __c) : __comp_(__c) {}
friend flat_map;
public:
@@ -659,7 +659,7 @@ class flat_map {
template <class _InputIterator>
requires __has_input_iterator_category<_InputIterator>::value
- void insert(sorted_unique_t, _InputIterator __first, _InputIterator __last) {
+ _LIBCPP_HIDE_FROM_ABI void insert(sorted_unique_t, _InputIterator __first, _InputIterator __last) {
if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) {
__reserve(__last - __first);
}
diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h
index 5cbe91207ca74e..8ed4c29cb8732f 100644
--- a/libcxx/include/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__locale_dir/locale_base_api.h
@@ -265,17 +265,17 @@ _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") // GCC doesn't support [[g
template <class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __snprintf(
char* __s, size_t __n, __locale_t __loc, const char* __format, _Args&&... __args) {
- return __libcpp_snprintf_l(__s, __n, __loc, __format, std::forward<_Args>(__args)...);
+ return std::__libcpp_snprintf_l(__s, __n, __loc, __format, std::forward<_Args>(__args)...);
}
template <class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf(
char** __s, __locale_t __loc, const char* __format, _Args&&... __args) {
- return __libcpp_asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
+ return std::__libcpp_asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
}
template <class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf(
const char* __s, __locale_t __loc, const char* __format, _Args&&... __args) {
- return __libcpp_sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
+ return std::__libcpp_sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
}
_LIBCPP_DIAGNOSTIC_POP
# undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT
diff --git a/libcxx/include/__ranges/to.h b/libcxx/include/__ranges/to.h
index 76249bdd9891c8..c937b0656de87d 100644
--- a/libcxx/include/__ranges/to.h
+++ b/libcxx/include/__ranges/to.h
@@ -111,14 +111,14 @@ template <class _Container, input_range _Range, class... _Args>
for (auto&& __ref : __range) {
using _Ref = decltype(__ref);
- if constexpr (requires { __result.emplace_back(declval<_Ref>()); }) {
+ if constexpr (requires { __result.emplace_back(std::declval<_Ref>()); }) {
__result.emplace_back(std::forward<_Ref>(__ref));
- } else if constexpr (requires { __result.push_back(declval<_Ref>()); }) {
+ } else if constexpr (requires { __result.push_back(std::declval<_Ref>()); }) {
__result.push_back(std::forward<_Ref>(__ref));
- } else if constexpr (requires { __result.emplace(__result.end(), declval<_Ref>()); }) {
+ } else if constexpr (requires { __result.emplace(__result.end(), std::declval<_Ref>()); }) {
__result.emplace(__result.end(), std::forward<_Ref>(__ref));
} else {
- static_assert(requires { __result.insert(__result.end(), declval<_Ref>()); });
+ static_assert(requires { __result.insert(__result.end(), std::declval<_Ref>()); });
__result.insert(__result.end(), std::forward<_Ref>(__ref));
}
}
>From d544bac7e6688012e97ff6e369131bf7ffeecac7 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sun, 10 Nov 2024 13:17:34 +0100
Subject: [PATCH 2/2] [libc++] Add __detected_or_t and use it to implement some
of the allocator traits aliases
---
libcxx/include/CMakeLists.txt | 1 +
libcxx/include/__memory/allocator_traits.h | 95 +++++++++-------------
libcxx/include/__memory/unique_ptr.h | 4 +-
libcxx/include/__type_traits/detected_or.h | 36 ++++++++
libcxx/include/module.modulemap | 1 +
5 files changed, 80 insertions(+), 57 deletions(-)
create mode 100644 libcxx/include/__type_traits/detected_or.h
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 83168d153a7f41..7bb4e0548eab2b 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -762,6 +762,7 @@ set(files
__type_traits/decay.h
__type_traits/dependent_type.h
__type_traits/desugars_to.h
+ __type_traits/detected_or.h
__type_traits/disjunction.h
__type_traits/enable_if.h
__type_traits/extent.h
diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h
index 499b30b85b6c9b..62b454c9227523 100644
--- a/libcxx/include/__memory/allocator_traits.h
+++ b/libcxx/include/__memory/allocator_traits.h
@@ -15,6 +15,7 @@
#include <__fwd/memory.h>
#include <__memory/construct_at.h>
#include <__memory/pointer_traits.h>
+#include <__type_traits/detected_or.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_constructible.h>
#include <__type_traits/is_empty.h>
@@ -42,17 +43,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
struct NAME<_Tp, __void_t<typename _Tp::PROPERTY > > : true_type {}
// __pointer
-template <class _Tp,
- class _Alloc,
- class _RawAlloc = __libcpp_remove_reference_t<_Alloc>,
- bool = __has_pointer<_RawAlloc>::value>
-struct __pointer {
- using type _LIBCPP_NODEBUG = typename _RawAlloc::pointer;
-};
-template <class _Tp, class _Alloc, class _RawAlloc>
-struct __pointer<_Tp, _Alloc, _RawAlloc, false> {
- using type _LIBCPP_NODEBUG = _Tp*;
-};
+template <class _Tp>
+using __pointer_member = typename _Tp::pointer;
+
+template <class _Tp, class _Alloc>
+using __pointer = __detected_or_t<_Tp*, __pointer_member, __libcpp_remove_reference_t<_Alloc> >;
// __const_pointer
_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_const_pointer, const_pointer);
@@ -100,13 +95,11 @@ struct __const_void_pointer<_Ptr, _Alloc, false> {
};
// __size_type
-_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_size_type, size_type);
-template <class _Alloc, class _DiffType, bool = __has_size_type<_Alloc>::value>
-struct __size_type : make_unsigned<_DiffType> {};
+template <class _Tp>
+using __size_type_member = typename _Tp::size_type;
+
template <class _Alloc, class _DiffType>
-struct __size_type<_Alloc, _DiffType, true> {
- using type _LIBCPP_NODEBUG = typename _Alloc::size_type;
-};
+using __size_type = __detected_or_t<__make_unsigned_t<_DiffType>, __size_type_member, _Alloc>;
// __alloc_traits_difference_type
_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_alloc_traits_difference_type, difference_type);
@@ -120,40 +113,34 @@ struct __alloc_traits_difference_type<_Alloc, _Ptr, true> {
};
// __propagate_on_container_copy_assignment
-_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_propagate_on_container_copy_assignment, propagate_on_container_copy_assignment);
-template <class _Alloc, bool = __has_propagate_on_container_copy_assignment<_Alloc>::value>
-struct __propagate_on_container_copy_assignment : false_type {};
+template <class _Tp>
+using __propagate_on_container_copy_assignment_member = typename _Tp::propagate_on_container_copy_assignment;
+
template <class _Alloc>
-struct __propagate_on_container_copy_assignment<_Alloc, true> {
- using type _LIBCPP_NODEBUG = typename _Alloc::propagate_on_container_copy_assignment;
-};
+using __propagate_on_container_copy_assignment =
+ __detected_or_t<false_type, __propagate_on_container_copy_assignment_member, _Alloc>;
// __propagate_on_container_move_assignment
-_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_propagate_on_container_move_assignment, propagate_on_container_move_assignment);
-template <class _Alloc, bool = __has_propagate_on_container_move_assignment<_Alloc>::value>
-struct __propagate_on_container_move_assignment : false_type {};
+template <class _Tp>
+using __propagate_on_container_move_assignment_member = typename _Tp::propagate_on_container_move_assignment;
+
template <class _Alloc>
-struct __propagate_on_container_move_assignment<_Alloc, true> {
- using type _LIBCPP_NODEBUG = typename _Alloc::propagate_on_container_move_assignment;
-};
+using __propagate_on_container_move_assignment =
+ __detected_or_t<false_type, __propagate_on_container_move_assignment_member, _Alloc>;
// __propagate_on_container_swap
-_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_propagate_on_container_swap, propagate_on_container_swap);
-template <class _Alloc, bool = __has_propagate_on_container_swap<_Alloc>::value>
-struct __propagate_on_container_swap : false_type {};
+template <class _Tp>
+using __propagate_on_container_swap_member = typename _Tp::propagate_on_container_swap;
+
template <class _Alloc>
-struct __propagate_on_container_swap<_Alloc, true> {
- using type _LIBCPP_NODEBUG = typename _Alloc::propagate_on_container_swap;
-};
+using __propagate_on_container_swap = __detected_or_t<false_type, __propagate_on_container_swap_member, _Alloc>;
// __is_always_equal
-_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_is_always_equal, is_always_equal);
-template <class _Alloc, bool = __has_is_always_equal<_Alloc>::value>
-struct __is_always_equal : is_empty<_Alloc> {};
+template <class _Tp>
+using __is_always_equal_member = typename _Tp::is_always_equal;
+
template <class _Alloc>
-struct __is_always_equal<_Alloc, true> {
- using type _LIBCPP_NODEBUG = typename _Alloc::is_always_equal;
-};
+using __is_always_equal = __detected_or_t<typename is_empty<_Alloc>::type, __is_always_equal_member, _Alloc>;
// __allocator_traits_rebind
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
@@ -245,20 +232,18 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(allocation_result);
template <class _Alloc>
struct _LIBCPP_TEMPLATE_VIS allocator_traits {
- using allocator_type = _Alloc;
- using value_type = typename allocator_type::value_type;
- using pointer = typename __pointer<value_type, allocator_type>::type;
- using const_pointer = typename __const_pointer<value_type, pointer, allocator_type>::type;
- using void_pointer = typename __void_pointer<pointer, allocator_type>::type;
- using const_void_pointer = typename __const_void_pointer<pointer, allocator_type>::type;
- using difference_type = typename __alloc_traits_difference_type<allocator_type, pointer>::type;
- using size_type = typename __size_type<allocator_type, difference_type>::type;
- using propagate_on_container_copy_assignment =
- typename __propagate_on_container_copy_assignment<allocator_type>::type;
- using propagate_on_container_move_assignment =
- typename __propagate_on_container_move_assignment<allocator_type>::type;
- using propagate_on_container_swap = typename __propagate_on_container_swap<allocator_type>::type;
- using is_always_equal = typename __is_always_equal<allocator_type>::type;
+ using allocator_type = _Alloc;
+ using value_type = typename allocator_type::value_type;
+ using pointer = __pointer<value_type, allocator_type>;
+ using const_pointer = typename __const_pointer<value_type, pointer, allocator_type>::type;
+ using void_pointer = typename __void_pointer<pointer, allocator_type>::type;
+ using const_void_pointer = typename __const_void_pointer<pointer, allocator_type>::type;
+ using difference_type = typename __alloc_traits_difference_type<allocator_type, pointer>::type;
+ using size_type = __size_type<allocator_type, difference_type>;
+ using propagate_on_container_copy_assignment = __propagate_on_container_copy_assignment<allocator_type>;
+ using propagate_on_container_move_assignment = __propagate_on_container_move_assignment<allocator_type>;
+ using propagate_on_container_swap = __propagate_on_container_swap<allocator_type>;
+ using is_always_equal = __is_always_equal<allocator_type>;
#ifndef _LIBCPP_CXX03_LANG
template <class _Tp>
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index 28c62e13566e24..9526255583dd56 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -143,7 +143,7 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
public:
typedef _Tp element_type;
typedef _Dp deleter_type;
- typedef _LIBCPP_NODEBUG typename __pointer<_Tp, deleter_type>::type pointer;
+ using pointer _LIBCPP_NODEBUG = __pointer<_Tp, deleter_type>;
static_assert(!is_rvalue_reference<deleter_type>::value, "the specified deleter type cannot be an rvalue reference");
@@ -410,7 +410,7 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp>
public:
typedef _Tp element_type;
typedef _Dp deleter_type;
- typedef typename __pointer<_Tp, deleter_type>::type pointer;
+ using pointer = __pointer<_Tp, deleter_type>;
// A unique_ptr contains the following members which may be trivially relocatable:
// - pointer: this may be trivially relocatable, so it's checked
diff --git a/libcxx/include/__type_traits/detected_or.h b/libcxx/include/__type_traits/detected_or.h
new file mode 100644
index 00000000000000..390f368411471e
--- /dev/null
+++ b/libcxx/include/__type_traits/detected_or.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_DETECTED_OR_H
+#define _LIBCPP___TYPE_TRAITS_DETECTED_OR_H
+
+#include <__config>
+#include <__type_traits/void_t.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Default, class _Void, template <class...> class _Op, class... _Args>
+struct __detector {
+ using type = _Default;
+};
+
+template <class _Default, template <class...> class _Op, class... _Args>
+struct __detector<_Default, __void_t<_Op<_Args...> >, _Op, _Args...> {
+ using type = _Op<_Args...>;
+};
+
+template <class _Default, template <class...> class _Op, class... _Args>
+using __detected_or_t = typename __detector<_Default, void, _Op, _Args...>::type;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_DETECTED_OR_H
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 139c0a83666435..86e877aedfb988 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -87,6 +87,7 @@ module std_core [system] {
module decay { header "__type_traits/decay.h" }
module dependent_type { header "__type_traits/dependent_type.h" }
module desugars_to { header "__type_traits/desugars_to.h" }
+ module detected_or { header "__type_traits/detected_or.h" }
module disjunction { header "__type_traits/disjunction.h" }
module enable_if { header "__type_traits/enable_if.h" }
module extent { header "__type_traits/extent.h" }
More information about the libcxx-commits
mailing list