[llvm] [clang] [mlir] [openmp] [clang-tools-extra] [lld] [libclc] [flang] [lldb] [libc] [libcxx] [compiler-rt] [libc++][memory] P1132R8: `out_ptr` - a scalable output pointer abstraction (PR #73618)
Hristo Hristov via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 29 21:06:30 PST 2024
https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/73618
>From 84770c82152f027588dd744bbfb91ed55377e007 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <zingam at outlook.com>
Date: Sun, 30 Apr 2023 13:17:20 +0300
Subject: [PATCH 01/23] [libc++][memory] P1132R8: out_ptr - a scalable output
pointer abstraction
Differential Revision: https://reviews.llvm.org/D150525
---
libcxx/docs/FeatureTestMacroTable.rst | 2 +-
libcxx/docs/Status/Cxx23Issues.csv | 4 +-
libcxx/docs/Status/Cxx23Papers.csv | 2 +-
libcxx/include/CMakeLists.txt | 2 +
libcxx/include/__memory/allocator_traits.h | 1 -
libcxx/include/__memory/inout_ptr.h | 100 +++++++++
libcxx/include/__memory/out_ptr.h | 97 +++++++++
libcxx/include/__memory/pointer_traits.h | 67 +++++-
libcxx/include/memory | 18 ++
libcxx/include/module.modulemap.in | 2 +
libcxx/include/version | 2 +-
libcxx/modules/std/memory.inc | 10 +-
.../memory.version.compile.pass.cpp | 16 +-
.../version.version.compile.pass.cpp | 16 +-
.../inout.ptr/inout.ptr.compile.pass.cpp | 35 +++
.../adapt/inout.ptr/inout.ptr.pass.cpp | 205 ++++++++++++++++++
.../inout.ptr/inout.ptr.t.compile.pass.cpp | 32 +++
.../adapt/inout.ptr/inout.ptr.t.verify.cpp | 29 +++
.../adapt/inout.ptr/inout.ptr.verify.cpp | 30 +++
.../adapt/out.ptr/out.ptr.compile.pass.cpp | 34 +++
.../smartptr/adapt/out.ptr/out.ptr.pass.cpp | 163 ++++++++++++++
.../adapt/out.ptr/out.ptr.t.compile.pass.cpp | 32 +++
.../adapt/out.ptr/out.ptr.t.verify.cpp | 29 +++
.../smartptr/adapt/out.ptr/out.ptr.verify.cpp | 30 +++
.../test/std/utilities/smartptr/adapt/types.h | 77 +++++++
.../generate_feature_test_macro_components.py | 1 -
26 files changed, 999 insertions(+), 37 deletions(-)
create mode 100644 libcxx/include/__memory/inout_ptr.h
create mode 100644 libcxx/include/__memory/out_ptr.h
create mode 100644 libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.compile.pass.cpp
create mode 100644 libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.pass.cpp
create mode 100644 libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.compile.pass.cpp
create mode 100644 libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.verify.cpp
create mode 100644 libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.verify.cpp
create mode 100644 libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.compile.pass.cpp
create mode 100644 libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.pass.cpp
create mode 100644 libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.compile.pass.cpp
create mode 100644 libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.verify.cpp
create mode 100644 libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.verify.cpp
create mode 100644 libcxx/test/std/utilities/smartptr/adapt/types.h
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index d09f65b7cadc0..4b2adc70f5174 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -342,7 +342,7 @@ Status
--------------------------------------------------- -----------------
``__cpp_lib_optional`` ``202110L``
--------------------------------------------------- -----------------
- ``__cpp_lib_out_ptr`` *unimplemented*
+ ``__cpp_lib_out_ptr`` ``202106L``
--------------------------------------------------- -----------------
``__cpp_lib_print`` *unimplemented*
--------------------------------------------------- -----------------
diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv
index b24ecc5525a14..e5ad365f9ffb8 100644
--- a/libcxx/docs/Status/Cxx23Issues.csv
+++ b/libcxx/docs/Status/Cxx23Issues.csv
@@ -192,7 +192,7 @@
"`3515 <https://wg21.link/LWG3515>`__","§[stacktrace.basic.nonmem]: ``operator<<`` should be less templatized", "November 2022","","",""
"`3545 <https://wg21.link/LWG3545>`__","``std::pointer_traits`` should be SFINAE-friendly", "November 2022","|Complete|","18.0",""
"`3569 <https://wg21.link/LWG3569>`__","``join_view`` fails to support ranges of ranges with non-default_initializable iterators", "November 2022","","","|ranges|"
-"`3594 <https://wg21.link/LWG3594>`__","``inout_ptr`` — inconsistent ``release()`` in destructor", "November 2022","","",""
+"`3594 <https://wg21.link/LWG3594>`__","``inout_ptr`` — inconsistent ``release()`` in destructor", "November 2022","|Complete|","17.0",""
"`3597 <https://wg21.link/LWG3597>`__","Unsigned integer types don't model advanceable", "November 2022","","","|ranges|"
"`3600 <https://wg21.link/LWG3600>`__","Making ``istream_iterator`` copy constructor trivial is an ABI break", "November 2022","","",""
"`3629 <https://wg21.link/LWG3629>`__","``make_error_code`` and ``make_error_condition`` are customization points","November 2022","|Complete|","16.0",""
@@ -282,7 +282,7 @@
"`3645 <https://wg21.link/LWG3645>`__","``resize_and_overwrite`` is overspecified to call its callback with lvalues","February 2023","|Complete|","14.0",""
"`3655 <https://wg21.link/LWG3655>`__","The ``INVOKE`` operation and union types","February 2023","|Complete|","18.0",""
"`3723 <https://wg21.link/LWG3723>`__","``priority_queue::push_range`` needs to ``append_range``","February 2023","","","|ranges|"
-"`3734 <https://wg21.link/LWG3734>`__","Inconsistency in ``inout_ptr`` and ``out_ptr`` for empty case","February 2023","","",""
+"`3734 <https://wg21.link/LWG3734>`__","Inconsistency in ``inout_ptr`` and ``out_ptr`` for empty case","February 2023","|Complete|","17.0",""
"`3772 <https://wg21.link/LWG3772>`__","``repeat_view``'s ``piecewise`` constructor is missing Postconditions","February 2023","","","|ranges|"
"`3786 <https://wg21.link/LWG3786>`__","Flat maps' deduction guide needs to default ``Allocator`` to be useful","February 2023","","",""
"`3803 <https://wg21.link/LWG3803>`__","``flat_foo`` constructors taking ``KeyContainer`` lack ``KeyCompare`` parameter","February 2023","","",""
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index 5cc9e488297b9..198b0ab9d390e 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -13,7 +13,7 @@
"","","","","","",""
"`P0401R6 <https://wg21.link/P0401R6>`__","LWG","Providing size feedback in the Allocator interface","June 2021","|Complete|","15.0"
"`P0448R4 <https://wg21.link/P0448R4>`__","LWG","A strstream replacement using span<charT> as buffer","June 2021","",""
-"`P1132R8 <https://wg21.link/P1132R8>`__","LWG","out_ptr - a scalable output pointer abstraction","June 2021","",""
+"`P1132R8 <https://wg21.link/P1132R8>`__","LWG","out_ptr - a scalable output pointer abstraction","June 2021","|Complete|","17.0"
"`P1328R1 <https://wg21.link/P1328R1>`__","LWG","Making std::type_info::operator== constexpr","June 2021","|Complete|","17.0"
"`P1425R4 <https://wg21.link/P1425R4>`__","LWG","Iterators pair constructors for stack and queue","June 2021","|Complete|","14.0","|ranges|"
"`P1518R2 <https://wg21.link/P1518R2>`__","LWG","Stop overconstraining allocators in container deduction guides","June 2021","|Complete|","13.0"
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index d8faf6467b79a..e5a28734ae34b 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -529,6 +529,8 @@ set(files
__memory/concepts.h
__memory/construct_at.h
__memory/destruct_n.h
+ __memory/inout_ptr.h
+ __memory/out_ptr.h
__memory/pointer_traits.h
__memory/ranges_construct_at.h
__memory/ranges_uninitialized_algorithms.h
diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h
index eea5ee973d37f..ed13cf8a3c278 100644
--- a/libcxx/include/__memory/allocator_traits.h
+++ b/libcxx/include/__memory/allocator_traits.h
@@ -38,7 +38,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp> struct NAME<_Tp, __void_t<typename _Tp:: PROPERTY > > : true_type { }
// __pointer
-_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_pointer, pointer);
template <class _Tp, class _Alloc,
class _RawAlloc = __libcpp_remove_reference_t<_Alloc>,
bool = __has_pointer<_RawAlloc>::value>
diff --git a/libcxx/include/__memory/inout_ptr.h b/libcxx/include/__memory/inout_ptr.h
new file mode 100644
index 0000000000000..c2044a4642cf4
--- /dev/null
+++ b/libcxx/include/__memory/inout_ptr.h
@@ -0,0 +1,100 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___INOUT_PTR_H
+#define _LIBCPP___INOUT_PTR_H
+
+#include <__config>
+#include <__memory/addressof.h>
+#include <__memory/pointer_traits.h>
+#include <__memory/shared_ptr.h>
+#include <__memory/unique_ptr.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_specialization.h>
+#include <__type_traits/is_void.h>
+#include <tuple>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+template <class _Smart, class _Pointer, class... _Args>
+class _LIBCPP_TEMPLATE_VIS inout_ptr_t {
+ static_assert(!__is_specialization_v<_Smart, shared_ptr>, "std::shared_ptr<> is not supported");
+
+public:
+ _LIBCPP_HIDE_FROM_ABI explicit inout_ptr_t(_Smart& __s, _Args... __args)
+ : __s_(__s), __a_(std::forward<_Args>(__args)...), __p_([&__s] {
+ if constexpr (is_pointer_v<_Smart>) {
+ return __s;
+ } else {
+ return __s.get();
+ }
+ }()) {
+ if constexpr (requires { __s.release(); }) {
+ __s.release();
+ } else {
+ __s = _Smart();
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI inout_ptr_t(const inout_ptr_t&) = delete;
+
+ _LIBCPP_HIDE_FROM_ABI ~inout_ptr_t() {
+ if (!__p_) {
+ return;
+ }
+
+ using _SP = __pointer_of_or_t<_Smart, _Pointer>;
+ if constexpr (is_pointer_v<_Smart>) {
+ std::apply([&](auto&&... __args) { __s_ = _Smart(static_cast<_SP>(__p_), std::forward<_Args>(__args)...); },
+ std::move(__a_));
+ } else if constexpr (__resettable_smart_pointer_with_args<_Smart, _Pointer, _Args...>) {
+ std::apply([&](auto&&... __args) { __s_.reset(static_cast<_SP>(__p_), std::forward<_Args>(__args)...); },
+ std::move(__a_));
+ } else if constexpr (is_constructible_v<_Smart, _SP, _Args...>) {
+ std::apply([&](auto&&... __args) { __s_ = _Smart(static_cast<_SP>(__p_), std::forward<_Args>(__args)...); },
+ std::move(__a_));
+ } else {
+ static_assert(is_pointer_v<_Smart> || __resettable_smart_pointer_with_args<_Smart, _Pointer, _Args...> ||
+ is_constructible_v<_Smart, _SP, _Args...>);
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI operator _Pointer*() const noexcept { return std::addressof(const_cast<_Pointer&>(__p_)); }
+
+ _LIBCPP_HIDE_FROM_ABI operator void**() const noexcept
+ requires(!is_same_v<_Pointer, void*>)
+ {
+ static_assert(is_pointer_v<_Pointer>);
+
+ return reinterpret_cast<void**>(static_cast<_Pointer*>(*this));
+ }
+
+private:
+ _Smart& __s_;
+ tuple<_Args...> __a_;
+ _Pointer __p_;
+};
+
+template <class _Pointer = void, class _Smart, class... _Args>
+_LIBCPP_HIDE_FROM_ABI auto inout_ptr(_Smart& __s, _Args&&... __args) {
+ using _Ptr = conditional_t<is_void_v<_Pointer>, __pointer_of_t<_Smart>, _Pointer>;
+ return std::inout_ptr_t<_Smart, _Ptr, _Args&&...>{__s, std::forward<_Args>(__args)...};
+}
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___INOUT_PTR_H
diff --git a/libcxx/include/__memory/out_ptr.h b/libcxx/include/__memory/out_ptr.h
new file mode 100644
index 0000000000000..09c77cbafe69e
--- /dev/null
+++ b/libcxx/include/__memory/out_ptr.h
@@ -0,0 +1,97 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___OUT_PTR_H
+#define _LIBCPP___OUT_PTR_H
+
+#include <__config>
+#include <__memory/addressof.h>
+#include <__memory/pointer_traits.h>
+#include <__memory/shared_ptr.h>
+#include <__memory/unique_ptr.h>
+#include <__type_traits/is_specialization.h>
+#include <__type_traits/is_void.h>
+#include <tuple>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+template <class _Tp>
+concept __resettable_adapted_ptr = requires(_Tp __ptr) { __ptr().reset(); };
+
+template <class _Smart, class _Pointer, class... _Args>
+class _LIBCPP_TEMPLATE_VIS out_ptr_t {
+ static_assert(!__is_specialization_v<_Smart, shared_ptr> || sizeof...(_Args) > 0,
+ "Specialization of std::shared_ptr<> requires a deleter.");
+
+public:
+ _LIBCPP_HIDE_FROM_ABI explicit out_ptr_t(_Smart& __s, _Args... __args)
+ : __s_(__s), __a_(std::forward<_Args>(__args)...), __p_() {
+ using _Ptr = decltype(__s);
+ if constexpr (__resettable_smart_pointer<_Ptr>) {
+ __s_.reset();
+ } else if constexpr (is_constructible_v<_Smart>) {
+ __s_ = _Smart();
+ } else {
+ static_assert(__resettable_smart_pointer<_Ptr> || is_constructible_v<_Smart>);
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI out_ptr_t(const out_ptr_t&) = delete;
+
+ _LIBCPP_HIDE_FROM_ABI ~out_ptr_t() {
+ if (!__p_) {
+ return;
+ }
+
+ using _SP = __pointer_of_or_t<_Smart, _Pointer>;
+ if constexpr (__resettable_smart_pointer_with_args<_Smart, _Pointer, _Args...>) {
+ std::apply([&](auto&&... __args) { __s_.reset(static_cast<_SP>(__p_), std::forward<_Args>(__args)...); },
+ std::move(__a_));
+ } else if constexpr (is_constructible_v<_Smart, _SP, _Args...>) {
+ std::apply([&](auto&&... __args) { __s_ = _Smart(static_cast<_SP>(__p_), std::forward<_Args>(__args)...); },
+ std::move(__a_));
+ } else {
+ static_assert(__resettable_smart_pointer_with_args<_Smart, _Pointer, _Args...> ||
+ is_constructible_v<_Smart, _SP, _Args...>);
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI operator _Pointer*() const noexcept { return std::addressof(const_cast<_Pointer&>(__p_)); }
+
+ _LIBCPP_HIDE_FROM_ABI operator void**() const noexcept
+ requires(!is_same_v<_Pointer, void*>)
+ {
+ static_assert(is_pointer_v<_Pointer>);
+
+ return reinterpret_cast<void**>(static_cast<_Pointer*>(*this));
+ }
+
+private:
+ _Smart& __s_;
+ tuple<_Args...> __a_;
+ _Pointer __p_ = _Pointer();
+};
+
+template <class _Pointer = void, class _Smart, class... _Args>
+_LIBCPP_HIDE_FROM_ABI auto out_ptr(_Smart& __s, _Args&&... __args) {
+ using _Ptr = conditional_t<is_void_v<_Pointer>, __pointer_of_t<_Smart>, _Pointer>;
+ return std::out_ptr_t<_Smart, _Ptr, _Args&&...>{__s, std::forward<_Args>(__args)...};
+}
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___OUT_PTR_H
diff --git a/libcxx/include/__memory/pointer_traits.h b/libcxx/include/__memory/pointer_traits.h
index 7617948ed76bd..2be0deb50cb8e 100644
--- a/libcxx/include/__memory/pointer_traits.h
+++ b/libcxx/include/__memory/pointer_traits.h
@@ -15,11 +15,14 @@
#include <__type_traits/conditional.h>
#include <__type_traits/conjunction.h>
#include <__type_traits/decay.h>
+#include <__type_traits/enable_if.h>
#include <__type_traits/is_class.h>
#include <__type_traits/is_function.h>
#include <__type_traits/is_void.h>
+#include <__type_traits/negation.h>
#include <__type_traits/void_t.h>
#include <__utility/declval.h>
+#include <__utility/forward.h>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -28,11 +31,16 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Tp, class = void>
-struct __has_element_type : false_type {};
+// clang-format off
+#define _LIBCPP_CLASS_TRAITS_HAS_XXX(NAME, PROPERTY) \
+ template <class _Tp, class = void> \
+ struct NAME : false_type {}; \
+ template <class _Tp> \
+ struct NAME<_Tp, __void_t<typename _Tp::PROPERTY> > : true_type {}
+// clang-format on
-template <class _Tp>
-struct __has_element_type<_Tp, __void_t<typename _Tp::element_type> > : true_type {};
+_LIBCPP_CLASS_TRAITS_HAS_XXX(__has_pointer, pointer);
+_LIBCPP_CLASS_TRAITS_HAS_XXX(__has_element_type, element_type);
template <class _Ptr, bool = __has_element_type<_Ptr>::value>
struct __pointer_traits_element_type {};
@@ -242,6 +250,57 @@ auto to_address(const _Pointer& __p) noexcept -> decltype(std::__to_address(__p)
}
#endif
+#if _LIBCPP_STD_VER >= 23
+
+template <class _Tp>
+struct __pointer_of {};
+
+template <class _Tp>
+ requires(__has_pointer<_Tp>::value)
+struct __pointer_of<_Tp> {
+ using type = typename _Tp::pointer;
+};
+
+template <class _Tp>
+ requires(!__has_pointer<_Tp>::value && __has_element_type<_Tp>::value)
+struct __pointer_of<_Tp> {
+ using type = typename _Tp::element_type*;
+};
+
+template <class _Tp>
+ requires(!__has_pointer<_Tp>::value && !__has_element_type<_Tp>::value &&
+ __has_element_type<pointer_traits<_Tp>>::value)
+struct __pointer_of<_Tp> {
+ using type = typename pointer_traits<_Tp>::element_type*;
+};
+
+template <typename _Tp>
+using __pointer_of_t = typename __pointer_of<_Tp>::type;
+
+template <class _Tp, class _Up>
+struct __pointer_of_or {
+ using type _LIBCPP_NODEBUG = _Up;
+};
+
+template <class _Tp, class _Up>
+ requires requires { typename __pointer_of_t<_Tp>; }
+struct __pointer_of_or<_Tp, _Up> {
+ using type _LIBCPP_NODEBUG = __pointer_of_t<_Tp>;
+};
+
+template <typename _Tp, typename _Up>
+using __pointer_of_or_t = typename __pointer_of_or<_Tp, _Up>::type;
+
+template <class _Smart>
+concept __resettable_smart_pointer = requires(_Smart __s) { __s.reset(); };
+
+template <class _Smart, class _Pointer = void, class... _Args>
+concept __resettable_smart_pointer_with_args = requires(_Smart __s, _Pointer __p, _Args... __args) {
+ __s.reset(static_cast<__pointer_of_or_t<_Smart, _Pointer>>(__p), std::forward<_Args>(__args)...);
+};
+
+#endif
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___MEMORY_POINTER_TRAITS_H
diff --git a/libcxx/include/memory b/libcxx/include/memory
index 24ba82f43ddd3..d3ab5f73bf00a 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -910,6 +910,22 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
template<size_t N, class T>
[[nodiscard]] constexpr T* assume_aligned(T* ptr); // since C++20
+// [out.ptr.t], class template out_ptr_t
+template<class Smart, class Pointer, class... Args>
+ class out_ptr_t; // since c++23
+
+// [out.ptr], function template out_ptr
+template<class Pointer = void, class Smart, class... Args>
+ auto out_ptr(Smart& s, Args&&... args); // since c++23
+
+// [inout.ptr.t], class template inout_ptr_t
+template<class Smart, class Pointer, class... Args>
+ class inout_ptr_t; // since c++23
+
+// [inout.ptr], function template inout_ptr
+template<class Pointer = void, class Smart, class... Args>
+ auto inout_ptr(Smart& s, Args&&... args); // since c++23
+
} // std
*/
@@ -928,6 +944,8 @@ template<size_t N, class T>
#include <__memory/compressed_pair.h>
#include <__memory/concepts.h>
#include <__memory/construct_at.h>
+#include <__memory/inout_ptr.h>
+#include <__memory/out_ptr.h>
#include <__memory/pointer_traits.h>
#include <__memory/ranges_construct_at.h>
#include <__memory/ranges_uninitialized_algorithms.h>
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 90ee7fbb2157c..f8a154d254167 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1519,6 +1519,8 @@ module std_private_memory_concepts [system] {
}
module std_private_memory_construct_at [system] { header "__memory/construct_at.h" }
module std_private_memory_destruct_n [system] { header "__memory/destruct_n.h" }
+module std_private_memory_inout_ptr [system] { header "__memory/inout_ptr.h" }
+module std_private_memory_out_ptr [system] { header "__memory/out_ptr.h" }
module std_private_memory_pointer_traits [system] { header "__memory/pointer_traits.h" }
module std_private_memory_ranges_construct_at [system] { header "__memory/ranges_construct_at.h" }
module std_private_memory_ranges_uninitialized_algorithms [system] {
diff --git a/libcxx/include/version b/libcxx/include/version
index e84790b888d33..2203dfd0e6005 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -455,7 +455,7 @@ __cpp_lib_within_lifetime 202306L <type_traits>
// # define __cpp_lib_move_only_function 202110L
# undef __cpp_lib_optional
# define __cpp_lib_optional 202110L
-// # define __cpp_lib_out_ptr 202106L
+# define __cpp_lib_out_ptr 202106L
// # define __cpp_lib_print 202207L
// # define __cpp_lib_ranges_as_const 202207L
# define __cpp_lib_ranges_as_rvalue 202207L
diff --git a/libcxx/modules/std/memory.inc b/libcxx/modules/std/memory.inc
index fba2461732c1b..a02fa2b865f57 100644
--- a/libcxx/modules/std/memory.inc
+++ b/libcxx/modules/std/memory.inc
@@ -177,17 +177,19 @@ export namespace std {
// [util.smartptr.atomic], atomic smart pointers
// using std::atomic;
+#if _LIBCPP_STD_VER >= 23
// [out.ptr.t], class template out_ptr_t
- // using std::out_ptr_t;
+ using std::out_ptr_t;
// [out.ptr], function template out_ptr
- // using std::out_ptr;
+ using std::out_ptr;
// [inout.ptr.t], class template inout_ptr_t
- // using std::inout_ptr_t;
+ using std::inout_ptr_t;
// [inout.ptr], function template inout_ptr
- // using std::inout_ptr;
+ using std::inout_ptr;
+#endif // _LIBCPP_STD_VER >= 23
#ifndef _LIBCPP_HAS_NO_THREADS
// [depr.util.smartptr.shared.atomic]
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
index b1f6c76d84739..c3b37ed35a3ad 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
@@ -485,17 +485,11 @@
# error "__cpp_lib_make_unique should have the value 201304L in c++23"
# endif
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_out_ptr
-# error "__cpp_lib_out_ptr should be defined in c++23"
-# endif
-# if __cpp_lib_out_ptr != 202106L
-# error "__cpp_lib_out_ptr should have the value 202106L in c++23"
-# endif
-# else // _LIBCPP_VERSION
-# ifdef __cpp_lib_out_ptr
-# error "__cpp_lib_out_ptr should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_out_ptr
+# error "__cpp_lib_out_ptr should be defined in c++23"
+# endif
+# if __cpp_lib_out_ptr != 202106L
+# error "__cpp_lib_out_ptr should have the value 202106L in c++23"
# endif
# ifndef __cpp_lib_ranges
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index a995795e305c4..413fca0e79fec 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -5210,17 +5210,11 @@
# error "__cpp_lib_optional should have the value 202110L in c++23"
# endif
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_out_ptr
-# error "__cpp_lib_out_ptr should be defined in c++23"
-# endif
-# if __cpp_lib_out_ptr != 202106L
-# error "__cpp_lib_out_ptr should have the value 202106L in c++23"
-# endif
-# else // _LIBCPP_VERSION
-# ifdef __cpp_lib_out_ptr
-# error "__cpp_lib_out_ptr should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_out_ptr
+# error "__cpp_lib_out_ptr should be defined in c++23"
+# endif
+# if __cpp_lib_out_ptr != 202106L
+# error "__cpp_lib_out_ptr should have the value 202106L in c++23"
# endif
# if !defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.compile.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.compile.pass.cpp
new file mode 100644
index 0000000000000..d2eb8c3a6ac00
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.compile.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <memory>
+
+// [inout.ptr], function template inout_ptr
+// template<class Pointer = void, class Smart, class... Args>
+// auto inout_ptr(Smart& s, Args&&... args); // since c++23
+
+#include <memory>
+
+int main(int, char**) {
+ {
+ std::unique_ptr<int> uPtr;
+
+ auto inoutUPtr1 = std::inout_ptr(uPtr);
+ auto inoutUPtr2 = std::inout_ptr<int*>(uPtr);
+ }
+ {
+ auto deleter = [](auto* p) { delete p; };
+ std::unique_ptr<int, decltype(deleter)> uPtr;
+
+ auto inoutUPtr1 = std::inout_ptr(uPtr, deleter);
+ auto inoutUPtr2 = std::inout_ptr<int*>(uPtr, deleter);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.pass.cpp
new file mode 100644
index 0000000000000..ece5628053427
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.pass.cpp
@@ -0,0 +1,205 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <memory>
+
+// [inout.ptr.t], class template inout_ptr_t
+// template<class Smart, class Pointer, class... Args>
+// class inout_ptr_t; // since c++23
+
+// [inout.ptr], function template inout_ptr
+// template<class Pointer = void, class Smart, class... Args>
+// auto inout_ptr(Smart& s, Args&&... args); // since c++23
+
+#include <cassert>
+#include <memory>
+
+#include "../types.h"
+
+// Test helpers.
+
+void replace_int_p(int** pp) {
+ assert(**pp == 90);
+ delete *pp;
+ *pp = new int{84};
+}
+
+void replace_int_p_with_nullptr(int** pp) {
+ assert(**pp == 90);
+ delete *pp;
+ *pp = nullptr;
+}
+
+void replace_nullptr_with_int_p(int** pp) {
+ assert(*pp == nullptr);
+ *pp = new int{84};
+}
+
+void replace_int_void_p(void** pp) {
+ assert(*(static_cast<int*>(*pp)) == 90);
+ delete static_cast<int*>(*pp);
+ *pp = new int{84};
+}
+
+void replace_int_void_p_with_nullptr(void** pp) {
+ assert(*(static_cast<int*>(*pp)) == 90);
+ delete static_cast<int*>(*pp);
+ *pp = nullptr;
+}
+
+void replace_nullptr_with_int_void_p(void** pp) {
+ assert(*pp == nullptr);
+ *pp = new int{84};
+}
+
+void replace_SomeInt_p(SomeInt** pp) {
+ auto si = **pp;
+ assert(si.value == 90);
+ delete static_cast<SomeInt*>(*pp);
+ *pp = new SomeInt{9084};
+}
+
+void replace_SomeInt_void_p(void** pp) {
+ assert(reinterpret_cast<SomeInt*>(*pp)->value == 90);
+ delete static_cast<SomeInt*>(*pp);
+ *pp = reinterpret_cast<void*>(new SomeInt{9084});
+}
+
+// Test `std::inout_ptr()` function.
+
+void test_raw_ptr() {
+ {
+ auto rPtr = new int{90};
+
+ replace_int_p(std::inout_ptr<int*>(rPtr));
+ assert(*rPtr == 84);
+
+ delete rPtr;
+ }
+ {
+ auto rPtr = new int{90};
+
+ replace_int_p_with_nullptr(std::inout_ptr<int*>(rPtr));
+ assert(rPtr == nullptr);
+ }
+ {
+ int* rPtr = nullptr;
+
+ replace_nullptr_with_int_p(std::inout_ptr<int*>(rPtr));
+ assert(*rPtr == 84);
+ delete rPtr;
+ }
+ {
+ auto rPtr = new int{90};
+
+ replace_int_void_p(std::inout_ptr<int*>(rPtr));
+ assert(*rPtr == 84);
+ delete rPtr;
+ }
+ {
+ auto rPtr = new int{90};
+
+ replace_int_void_p_with_nullptr(std::inout_ptr<int*>(rPtr));
+ assert(rPtr == nullptr);
+ }
+ {
+ int* rPtr = nullptr;
+
+ replace_nullptr_with_int_void_p(std::inout_ptr<int*>(rPtr));
+ assert(*rPtr == 84);
+ delete rPtr;
+ }
+ {
+ auto* rPtr = new SomeInt{90};
+
+ replace_SomeInt_p(std::inout_ptr(rPtr));
+ assert(rPtr->value == 9084);
+ delete rPtr;
+ }
+ {
+ auto* rPtr = new SomeInt{90};
+
+ replace_SomeInt_void_p(std::inout_ptr<SomeInt*>(rPtr));
+ assert(rPtr->value == 9084);
+ delete rPtr;
+ }
+}
+
+void test_unique_ptr() {
+ {
+ auto uPtr = std::make_unique<int>(90);
+
+ replace_int_p(std::inout_ptr(uPtr));
+ assert(*uPtr == 84);
+ }
+ {
+ std::unique_ptr<int> uPtr;
+
+ replace_nullptr_with_int_p(std::inout_ptr(uPtr));
+ assert(*uPtr == 84);
+ }
+ {
+ auto uPtr = std::make_unique<int>(90);
+
+ replace_int_void_p(std::inout_ptr(uPtr));
+ assert(*uPtr == 84);
+ }
+ {
+ std::unique_ptr<int> uPtr;
+
+ replace_nullptr_with_int_void_p(std::inout_ptr(uPtr));
+ assert(*uPtr == 84);
+ }
+ {
+ auto uPtr = std::make_unique<SomeInt>(90);
+
+ replace_SomeInt_p(std::inout_ptr(uPtr));
+ assert(uPtr->value == 9084);
+ }
+ {
+ auto uPtr = std::make_unique<SomeInt>(90);
+
+ replace_SomeInt_void_p(std::inout_ptr<SomeInt*>(uPtr));
+ assert(uPtr->value == 9084);
+ }
+}
+
+void test_custom_ptr() {
+ // ConstructiblePtr
+ {
+ ConstructiblePtr<int> cPtr(new int{90});
+
+ replace_int_p(std::inout_ptr(cPtr));
+ assert(cPtr == 84);
+ }
+ // ResettablePtr
+ {
+ ResettablePtr<int> rPtr(new int{90});
+
+ replace_int_p(std::inout_ptr(rPtr));
+ assert(rPtr == 84);
+ }
+ // NonConstructiblePtr
+ {
+ NonConstructiblePtr<int> nPtr;
+ nPtr.reset(new int{90});
+
+ replace_int_p(std::inout_ptr(nPtr));
+ assert(nPtr == 84);
+ }
+}
+
+int main(int, char**) {
+ test_raw_ptr();
+ test_unique_ptr();
+ test_custom_ptr();
+
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.compile.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.compile.pass.cpp
new file mode 100644
index 0000000000000..18979d014dc01
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.compile.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <memory>
+
+// [inout.ptr.t], class template inout_ptr_t
+// template<class Smart, class Pointer, class... Args>
+// class inout_ptr_t; // since c++23
+
+#include <memory>
+
+int main(int, char**) {
+ {
+ std::unique_ptr<int> uPtr;
+
+ std::inout_ptr_t<std::unique_ptr<int>, int*>{uPtr};
+ }
+ {
+ std::unique_ptr<int> uPtr;
+
+ std::inout_ptr_t<std::unique_ptr<int>, int*>{uPtr};
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.verify.cpp
new file mode 100644
index 0000000000000..33cc55520bb40
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.verify.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <memory>
+
+// [inout.ptr.t], class template inout_ptr_t
+// template<class Smart, class Pointer, class... Args>
+// class inout_ptr_t; // since c++23
+
+#include <memory>
+
+int main(int, char**) {
+ // `std::inout_ptr<>` does not support `std::shared_ptr<>`.
+ {
+ std::shared_ptr<int> sPtr;
+
+ // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed due to requirement '!__is_specialization_v<std::shared_ptr<int>, std::shared_ptr>'{{.*}}std::shared_ptr<> is not supported}}
+ std::inout_ptr_t<std::shared_ptr<int>, int*>{sPtr};
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.verify.cpp
new file mode 100644
index 0000000000000..3e23e54378120
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <memory>
+
+// [inout.ptr], function template inout_ptr
+// template<class Pointer = void, class Smart, class... Args>
+// auto inout_ptr(Smart& s, Args&&... args); // since c++23
+
+#include <memory>
+
+int main(int, char**) {
+ // `std::inout_ptr<>` does not support `std::shared_ptr<>`.
+ {
+ std::shared_ptr<int> sPtr;
+
+ // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed due to requirement '!__is_specialization_v<std::shared_ptr<int>, std::shared_ptr>'{{.*}}std::shared_ptr<> is not supported}}
+ auto inoutUPtr1 = std::inout_ptr(sPtr);
+ auto inoutUPtr2 = std::inout_ptr<int*>(sPtr);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.compile.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.compile.pass.cpp
new file mode 100644
index 0000000000000..71f78a5bf770a
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.compile.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <memory>
+
+// [out.ptr], function template out_ptr
+// template<class Pointer = void, class Smart, class... Args>
+// auto out_ptr(Smart& s, Args&&... args); // since c++23
+
+#include <memory>
+
+int main(int, char**) {
+ {
+ std::unique_ptr<int> uPtr;
+
+ auto outUPtr1 = std::out_ptr(uPtr);
+ auto outUPtr2 = std::out_ptr<int*>(uPtr);
+ }
+ {
+ std::shared_ptr<int> sPtr;
+
+ auto outSPtr1 = std::out_ptr(sPtr, [](auto* p) { delete p; });
+ auto outSPtr2 = std::out_ptr<int*>(sPtr, [](auto* p) { delete p; });
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.pass.cpp
new file mode 100644
index 0000000000000..2ccf48643c332
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.pass.cpp
@@ -0,0 +1,163 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <memory>
+
+// [out.ptr.t], class template out_ptr_t
+// template<class Smart, class Pointer, class... Args>
+// class out_ptr_t; // since c++23
+
+// [out.ptr], function template out_ptr
+// template<class Pointer = void, class Smart, class... Args>
+// auto out_ptr(Smart& s, Args&&... args); // since c++23
+
+#include <cassert>
+#include <memory>
+
+#include "../types.h"
+
+// Test helpers.
+
+void get_int_p(int** pp) { *pp = new int{84}; }
+
+void get_int_p_nullptr(int** pp) { *pp = nullptr; }
+
+void get_int_void_p(void** pp) { *(reinterpret_cast<int**>(pp)) = new int{84}; }
+
+void get_int_void_p_nullptr(void** pp) { *pp = nullptr; }
+
+void get_SomeInt_p(SomeInt** pp) { *pp = new SomeInt{84}; }
+
+void get_SomeInt_void_p(void** pp) { *pp = reinterpret_cast<int*>(new int{84}); }
+
+// Test `std::out_ptr()` function.
+
+void test_raw_ptr() {
+ {
+ auto n{90};
+ auto rPtr = &n;
+
+ get_int_p(std::inout_ptr<int*>(rPtr));
+ assert(*rPtr == 84);
+ delete rPtr;
+
+ get_int_p_nullptr(std::out_ptr<int*>(rPtr));
+ assert(rPtr == nullptr);
+
+ get_int_void_p(std::inout_ptr<int*>(rPtr));
+ assert(*rPtr == 84);
+ delete rPtr;
+
+ get_int_void_p_nullptr(std::out_ptr<int*>(rPtr));
+ assert(rPtr == nullptr);
+ }
+ {
+ SomeInt si{90};
+ auto* rPtr = &si;
+
+ get_SomeInt_p(std::out_ptr(rPtr));
+ assert(rPtr->value == 84);
+ delete rPtr;
+ }
+ {
+ SomeInt si{90};
+ auto* rPtr = &si;
+
+ get_SomeInt_void_p(std::out_ptr<SomeInt*>(rPtr));
+ assert(rPtr->value == 84);
+ delete rPtr;
+ }
+}
+
+void test_shared_ptr() {
+ {
+ auto sPtr = std::make_shared<int>(90);
+
+ get_int_p(std::out_ptr(sPtr, [](auto* p) { delete p; }));
+ assert(*sPtr == 84);
+
+ sPtr.reset(new int(90));
+
+ get_int_void_p(std::out_ptr(sPtr, [](auto* p) { delete p; }));
+ assert(*sPtr == 84);
+ }
+ {
+ auto sPtr = std::make_shared<SomeInt>(90);
+
+ get_SomeInt_p(std::out_ptr(sPtr, [](auto* p) { delete p; }));
+ assert(sPtr->value == 84);
+ }
+ {
+ auto sPtr = std::make_shared<SomeInt>(90);
+
+ get_SomeInt_void_p(std::out_ptr<SomeInt*>(sPtr, [](auto* p) { delete p; }));
+ assert(sPtr->value == 84);
+ }
+}
+
+void test_unique_ptr() {
+ {
+ auto uPtr = std::make_unique<int>(90);
+
+ get_int_p(std::out_ptr(uPtr));
+ assert(*uPtr == 84);
+
+ uPtr.reset(new int{90});
+
+ get_int_void_p(std::out_ptr(uPtr));
+ assert(*uPtr == 84);
+ }
+ {
+ auto uPtr = std::make_unique<SomeInt>(90);
+
+ get_SomeInt_p(std::out_ptr(uPtr));
+ assert(uPtr->value == 84);
+ }
+ {
+ auto uPtr = std::make_unique<SomeInt>(90);
+
+ get_SomeInt_void_p(std::out_ptr<SomeInt*>(uPtr));
+ assert(uPtr->value == 84);
+ }
+}
+
+void test_custom_ptr() {
+ // ConstructiblePtr
+ {
+ ConstructiblePtr<int> cPtr(new int{90});
+
+ get_int_p(std::out_ptr(cPtr));
+ assert(cPtr == 84);
+ }
+ // ResettablePtr
+ {
+ ResettablePtr<int> rPtr(new int{90});
+
+ get_int_p(std::out_ptr(rPtr));
+ assert(rPtr == 84);
+ }
+ // NonConstructiblePtr
+ {
+ NonConstructiblePtr<int> nPtr;
+ nPtr.reset(new int{90});
+
+ get_int_p(std::out_ptr(nPtr));
+ assert(nPtr == 84);
+ }
+}
+
+int main(int, char**) {
+ test_raw_ptr();
+ test_shared_ptr();
+ test_unique_ptr();
+ test_custom_ptr();
+
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.compile.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.compile.pass.cpp
new file mode 100644
index 0000000000000..12ad53ac3811e
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.compile.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <memory>
+
+// [out.ptr.t], class template out_ptr_t
+// template<class Smart, class Pointer, class... Args>
+// class out_ptr_t; // since c++23
+
+#include <memory>
+
+int main(int, char**) {
+ {
+ std::unique_ptr<int> uPtr;
+
+ std::out_ptr_t<std::unique_ptr<int>, int*>{uPtr};
+ }
+ {
+ std::unique_ptr<int, std::default_delete<int>> uPtr;
+
+ std::out_ptr_t<decltype(uPtr), int*, std::default_delete<int>>{uPtr, std::default_delete<int>{}};
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.verify.cpp
new file mode 100644
index 0000000000000..c89007b77ae82
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.verify.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <memory>
+
+// [out.ptr.t], class template out_ptr_t
+// template<class Smart, class Pointer, class... Args>
+// class out_ptr_t; // since c++23
+
+#include <memory>
+
+int main(int, char**) {
+ // `std::out_ptr_t<>` requires `std::shared_ptr<>` with a deleter.
+ {
+ std::shared_ptr<int> sPtr;
+
+ // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed due to requirement '!__is_specialization_v<std::shared_ptr<int>, std::shared_ptr> || sizeof...(_Args) > 0'{{.*}}Specialization of std::shared_ptr<> requires a deleter.}}
+ std::out_ptr_t<std::shared_ptr<int>, int*>{sPtr};
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.verify.cpp
new file mode 100644
index 0000000000000..f48592059ea0a
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <memory>
+
+// [out.ptr], function template out_ptr
+// template<class Pointer = void, class Smart, class... Args>
+// auto out_ptr(Smart& s, Args&&... args); // since c++23
+
+#include <memory>
+
+int main(int, char**) {
+ // `std::out_ptr<>` requires `std::shared_ptr<>` with a deleter.
+ {
+ std::shared_ptr<int> sPtr;
+
+ // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed due to requirement '!__is_specialization_v<std::shared_ptr<int>, std::shared_ptr> || sizeof...(_Args) > 0'{{.*}}Specialization of std::shared_ptr<> requires a deleter.}}
+ auto outSPtr1 = std::out_ptr(sPtr);
+ auto outSPtr2 = std::out_ptr<int*>(sPtr);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/types.h b/libcxx/test/std/utilities/smartptr/adapt/types.h
new file mode 100644
index 0000000000000..0e2dad400308d
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/adapt/types.h
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 TEST_LIBCXX_UTILITIES_SMARTPTR_ADAPT_TYPES_H
+#define TEST_LIBCXX_UTILITIES_SMARTPTR_ADAPT_TYPES_H
+
+#include <type_traits>
+#include <memory>
+
+struct ResetArg {};
+
+// Custom pointer types.
+
+template <typename _Tp>
+struct ConstructiblePtr {
+ using pointer = _Tp*;
+ std::unique_ptr<_Tp> ptr;
+
+ ConstructiblePtr() = default;
+ explicit ConstructiblePtr(_Tp* p) : ptr{p} {}
+
+ auto operator==(_Tp val) { return *ptr == val; }
+
+ auto* get() const { return ptr.get(); }
+
+ void release() { ptr.release(); }
+};
+
+static_assert(std::is_same_v<std::__pointer_of_t< ConstructiblePtr<int>>, int* >);
+static_assert(std::is_constructible_v< ConstructiblePtr<int>, int* >);
+
+template <typename _Tp>
+struct ResettablePtr {
+ using element_type = _Tp;
+ std::unique_ptr<_Tp> ptr;
+
+ explicit ResettablePtr(_Tp* p) : ptr{p} {}
+
+ auto operator*() const { return *ptr; }
+
+ auto operator==(_Tp val) { return *ptr == val; }
+
+ void reset() { ptr.reset(); }
+ void reset(_Tp* p, ResetArg) { ptr.reset(p); }
+
+ auto* get() const { return ptr.get(); }
+
+ void release() { ptr.release(); }
+};
+
+static_assert(std::is_same_v<std::__pointer_of_t< ResettablePtr<int>>, int* >);
+static_assert(std::is_constructible_v< ResettablePtr<int>, int* >);
+
+template <typename _Tp>
+struct NonConstructiblePtr : public ResettablePtr<_Tp> {
+ NonConstructiblePtr() : NonConstructiblePtr::ResettablePtr(nullptr){};
+
+ void reset(_Tp* p) { ResettablePtr<_Tp>::ptr.reset(p); }
+};
+
+static_assert(std::is_same_v<std::__pointer_of_t< NonConstructiblePtr<int>>, int* >);
+static_assert(!std::is_constructible_v< NonConstructiblePtr<int>, int* >);
+
+// Custom types.
+
+struct SomeInt {
+ int value;
+
+ constexpr explicit SomeInt(int val = 0) : value{val} {}
+};
+
+#endif // TEST_LIBCXX_UTILITIES_SMARTPTR_ADAPT_TYPES_H
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 47ee20de0fdc2..9910afa15cff6 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -854,7 +854,6 @@ def add_version_header(tc):
"c++26": 202311, # P2833R2 Freestanding Library: inout expected span
},
"headers": ["memory"],
- "unimplemented": True,
},
{
"name": "__cpp_lib_parallel_algorithm",
>From 4bc779ef33ed55605e502f597b94fff69b9e95f9 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <zingam at outlook.com>
Date: Thu, 30 Nov 2023 09:58:10 +0200
Subject: [PATCH 02/23] [out_ptr] Address review comments + new tests
---
libcxx/docs/FeatureTestMacroTable.rst | 2 +-
libcxx/docs/Status/Cxx23Issues.csv | 4 +-
libcxx/docs/Status/Cxx23Papers.csv | 2 +-
libcxx/docs/Status/Cxx2cIssues.csv | 2 +-
libcxx/include/__memory/inout_ptr.h | 8 ++--
libcxx/include/__memory/out_ptr.h | 2 +-
libcxx/include/__memory/pointer_traits.h | 2 -
libcxx/include/version | 2 +-
.../memory.version.compile.pass.cpp | 16 +++----
.../version.version.compile.pass.cpp | 16 +++----
...le.pass.cpp => inout.ptr.general.pass.cpp} | 4 ++
.../adapt/inout.ptr/inout.ptr.pass.cpp | 4 --
.../adapt/inout.ptr/inout.ptr.t.ctor.pass.cpp | 43 +++++++++++++++++++
...le.pass.cpp => inout.ptr.t.deref.pass.cpp} | 3 ++
.../adapt/inout.ptr/inout.ptr.verify.cpp | 1 +
...pile.pass.cpp => out.ptr.general.pass.cpp} | 4 ++
.../smartptr/adapt/out.ptr/out.ptr.pass.cpp | 4 --
.../adapt/out.ptr/out.ptr.t.ctor.pass.cpp | 41 ++++++++++++++++++
...pile.pass.cpp => out.ptr.t.deref.pass.cpp} | 3 ++
.../smartptr/adapt/out.ptr/out.ptr.verify.cpp | 1 +
20 files changed, 122 insertions(+), 42 deletions(-)
rename libcxx/test/std/utilities/smartptr/adapt/inout.ptr/{inout.ptr.compile.pass.cpp => inout.ptr.general.pass.cpp} (92%)
create mode 100644 libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.ctor.pass.cpp
rename libcxx/test/std/utilities/smartptr/adapt/inout.ptr/{inout.ptr.t.compile.pass.cpp => inout.ptr.t.deref.pass.cpp} (91%)
rename libcxx/test/std/utilities/smartptr/adapt/out.ptr/{out.ptr.compile.pass.cpp => out.ptr.general.pass.cpp} (92%)
create mode 100644 libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.ctor.pass.cpp
rename libcxx/test/std/utilities/smartptr/adapt/out.ptr/{out.ptr.t.compile.pass.cpp => out.ptr.t.deref.pass.cpp} (92%)
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 4b2adc70f5174..eb7957c07e307 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -426,7 +426,7 @@ Status
--------------------------------------------------- -----------------
``__cpp_lib_linalg`` *unimplemented*
--------------------------------------------------- -----------------
- ``__cpp_lib_out_ptr`` *unimplemented*
+ ``__cpp_lib_out_ptr`` ``202311L``
--------------------------------------------------- -----------------
``__cpp_lib_ratio`` ``202306L``
--------------------------------------------------- -----------------
diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv
index e5ad365f9ffb8..3e0122706930d 100644
--- a/libcxx/docs/Status/Cxx23Issues.csv
+++ b/libcxx/docs/Status/Cxx23Issues.csv
@@ -192,7 +192,7 @@
"`3515 <https://wg21.link/LWG3515>`__","§[stacktrace.basic.nonmem]: ``operator<<`` should be less templatized", "November 2022","","",""
"`3545 <https://wg21.link/LWG3545>`__","``std::pointer_traits`` should be SFINAE-friendly", "November 2022","|Complete|","18.0",""
"`3569 <https://wg21.link/LWG3569>`__","``join_view`` fails to support ranges of ranges with non-default_initializable iterators", "November 2022","","","|ranges|"
-"`3594 <https://wg21.link/LWG3594>`__","``inout_ptr`` — inconsistent ``release()`` in destructor", "November 2022","|Complete|","17.0",""
+"`3594 <https://wg21.link/LWG3594>`__","``inout_ptr`` — inconsistent ``release()`` in destructor", "November 2022","|Complete|","18.0",""
"`3597 <https://wg21.link/LWG3597>`__","Unsigned integer types don't model advanceable", "November 2022","","","|ranges|"
"`3600 <https://wg21.link/LWG3600>`__","Making ``istream_iterator`` copy constructor trivial is an ABI break", "November 2022","","",""
"`3629 <https://wg21.link/LWG3629>`__","``make_error_code`` and ``make_error_condition`` are customization points","November 2022","|Complete|","16.0",""
@@ -282,7 +282,7 @@
"`3645 <https://wg21.link/LWG3645>`__","``resize_and_overwrite`` is overspecified to call its callback with lvalues","February 2023","|Complete|","14.0",""
"`3655 <https://wg21.link/LWG3655>`__","The ``INVOKE`` operation and union types","February 2023","|Complete|","18.0",""
"`3723 <https://wg21.link/LWG3723>`__","``priority_queue::push_range`` needs to ``append_range``","February 2023","","","|ranges|"
-"`3734 <https://wg21.link/LWG3734>`__","Inconsistency in ``inout_ptr`` and ``out_ptr`` for empty case","February 2023","|Complete|","17.0",""
+"`3734 <https://wg21.link/LWG3734>`__","Inconsistency in ``inout_ptr`` and ``out_ptr`` for empty case","February 2023","|Complete|","18.0",""
"`3772 <https://wg21.link/LWG3772>`__","``repeat_view``'s ``piecewise`` constructor is missing Postconditions","February 2023","","","|ranges|"
"`3786 <https://wg21.link/LWG3786>`__","Flat maps' deduction guide needs to default ``Allocator`` to be useful","February 2023","","",""
"`3803 <https://wg21.link/LWG3803>`__","``flat_foo`` constructors taking ``KeyContainer`` lack ``KeyCompare`` parameter","February 2023","","",""
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index 198b0ab9d390e..02352837fa4da 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -13,7 +13,7 @@
"","","","","","",""
"`P0401R6 <https://wg21.link/P0401R6>`__","LWG","Providing size feedback in the Allocator interface","June 2021","|Complete|","15.0"
"`P0448R4 <https://wg21.link/P0448R4>`__","LWG","A strstream replacement using span<charT> as buffer","June 2021","",""
-"`P1132R8 <https://wg21.link/P1132R8>`__","LWG","out_ptr - a scalable output pointer abstraction","June 2021","|Complete|","17.0"
+"`P1132R8 <https://wg21.link/P1132R8>`__","LWG","out_ptr - a scalable output pointer abstraction","June 2021","|Complete|","18.0"
"`P1328R1 <https://wg21.link/P1328R1>`__","LWG","Making std::type_info::operator== constexpr","June 2021","|Complete|","17.0"
"`P1425R4 <https://wg21.link/P1425R4>`__","LWG","Iterators pair constructors for stack and queue","June 2021","|Complete|","14.0","|ranges|"
"`P1518R2 <https://wg21.link/P1518R2>`__","LWG","Stop overconstraining allocators in container deduction guides","June 2021","|Complete|","13.0"
diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index fe0f13f6e8cb2..1f407e322f891 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -24,7 +24,7 @@
"`3749 <https://wg21.link/LWG3749>`__","``common_iterator`` should handle integer-class difference types","Kona November 2023","","",""
"`3809 <https://wg21.link/LWG3809>`__","Is ``std::subtract_with_carry_engine<uint16_t>`` supposed to work","Kona November 2023","","",""
"`3892 <https://wg21.link/LWG3892>`__","Incorrect formatting of nested ranges and tuples","Kona November 2023","|Complete|","17.0","|format|"
-"`3897 <https://wg21.link/LWG3897>`__","``inout_ptr`` will not update raw pointer to 0","Kona November 2023","","",""
+"`3897 <https://wg21.link/LWG3897>`__","``inout_ptr`` will not update raw pointer to 0","Kona November 2023","|Complete|","18.0",""
"`3946 <https://wg21.link/LWG3946>`__","The definition of ``const_iterator_t`` should be reworked","Kona November 2023","","",""
"`3947 <https://wg21.link/LWG3947>`__","Unexpected constraints on ``adjacent_transform_view::base()``","Kona November 2023","","","|ranges|"
"`3948 <https://wg21.link/LWG3948>`__","``possibly-const-range and as-const-pointer`` should be ``noexcept``","Kona November 2023","","","|ranges|"
diff --git a/libcxx/include/__memory/inout_ptr.h b/libcxx/include/__memory/inout_ptr.h
index c2044a4642cf4..f91ecd8baff57 100644
--- a/libcxx/include/__memory/inout_ptr.h
+++ b/libcxx/include/__memory/inout_ptr.h
@@ -51,8 +51,10 @@ class _LIBCPP_TEMPLATE_VIS inout_ptr_t {
_LIBCPP_HIDE_FROM_ABI inout_ptr_t(const inout_ptr_t&) = delete;
_LIBCPP_HIDE_FROM_ABI ~inout_ptr_t() {
- if (!__p_) {
- return;
+ if constexpr (!is_pointer_v<_Smart>) {
+ if (!__p_) {
+ return;
+ }
}
using _SP = __pointer_of_or_t<_Smart, _Pointer>;
@@ -90,7 +92,7 @@ class _LIBCPP_TEMPLATE_VIS inout_ptr_t {
template <class _Pointer = void, class _Smart, class... _Args>
_LIBCPP_HIDE_FROM_ABI auto inout_ptr(_Smart& __s, _Args&&... __args) {
using _Ptr = conditional_t<is_void_v<_Pointer>, __pointer_of_t<_Smart>, _Pointer>;
- return std::inout_ptr_t<_Smart, _Ptr, _Args&&...>{__s, std::forward<_Args>(__args)...};
+ return std::inout_ptr_t<_Smart, _Ptr, _Args&&...>(__s, std::forward<_Args>(__args)...);
}
#endif // _LIBCPP_STD_VER >= 23
diff --git a/libcxx/include/__memory/out_ptr.h b/libcxx/include/__memory/out_ptr.h
index 09c77cbafe69e..eebc18c97fdcd 100644
--- a/libcxx/include/__memory/out_ptr.h
+++ b/libcxx/include/__memory/out_ptr.h
@@ -87,7 +87,7 @@ class _LIBCPP_TEMPLATE_VIS out_ptr_t {
template <class _Pointer = void, class _Smart, class... _Args>
_LIBCPP_HIDE_FROM_ABI auto out_ptr(_Smart& __s, _Args&&... __args) {
using _Ptr = conditional_t<is_void_v<_Pointer>, __pointer_of_t<_Smart>, _Pointer>;
- return std::out_ptr_t<_Smart, _Ptr, _Args&&...>{__s, std::forward<_Args>(__args)...};
+ return std::out_ptr_t<_Smart, _Ptr, _Args&&...>(__s, std::forward<_Args>(__args)...);
}
#endif // _LIBCPP_STD_VER >= 23
diff --git a/libcxx/include/__memory/pointer_traits.h b/libcxx/include/__memory/pointer_traits.h
index 2be0deb50cb8e..4e902746e6a35 100644
--- a/libcxx/include/__memory/pointer_traits.h
+++ b/libcxx/include/__memory/pointer_traits.h
@@ -15,11 +15,9 @@
#include <__type_traits/conditional.h>
#include <__type_traits/conjunction.h>
#include <__type_traits/decay.h>
-#include <__type_traits/enable_if.h>
#include <__type_traits/is_class.h>
#include <__type_traits/is_function.h>
#include <__type_traits/is_void.h>
-#include <__type_traits/negation.h>
#include <__type_traits/void_t.h>
#include <__utility/declval.h>
#include <__utility/forward.h>
diff --git a/libcxx/include/version b/libcxx/include/version
index 2203dfd0e6005..079e9f346a917 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -502,7 +502,7 @@ __cpp_lib_within_lifetime 202306L <type_traits>
// # define __cpp_lib_hazard_pointer 202306L
// # define __cpp_lib_linalg 202311L
# undef __cpp_lib_out_ptr
-// # define __cpp_lib_out_ptr 202311L
+# define __cpp_lib_out_ptr 202311L
# define __cpp_lib_ratio 202306L
// # define __cpp_lib_rcu 202306L
// # define __cpp_lib_saturation_arithmetic 202311L
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
index c3b37ed35a3ad..f50f1788cc497 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
@@ -616,17 +616,11 @@
# error "__cpp_lib_make_unique should have the value 201304L in c++26"
# endif
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_out_ptr
-# error "__cpp_lib_out_ptr should be defined in c++26"
-# endif
-# if __cpp_lib_out_ptr != 202311L
-# error "__cpp_lib_out_ptr should have the value 202311L in c++26"
-# endif
-# else // _LIBCPP_VERSION
-# ifdef __cpp_lib_out_ptr
-# error "__cpp_lib_out_ptr should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_out_ptr
+# error "__cpp_lib_out_ptr should be defined in c++26"
+# endif
+# if __cpp_lib_out_ptr != 202311L
+# error "__cpp_lib_out_ptr should have the value 202311L in c++26"
# endif
# ifndef __cpp_lib_ranges
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 413fca0e79fec..272177da0b444 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -6917,17 +6917,11 @@
# error "__cpp_lib_optional should have the value 202110L in c++26"
# endif
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_out_ptr
-# error "__cpp_lib_out_ptr should be defined in c++26"
-# endif
-# if __cpp_lib_out_ptr != 202311L
-# error "__cpp_lib_out_ptr should have the value 202311L in c++26"
-# endif
-# else // _LIBCPP_VERSION
-# ifdef __cpp_lib_out_ptr
-# error "__cpp_lib_out_ptr should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_out_ptr
+# error "__cpp_lib_out_ptr should be defined in c++26"
+# endif
+# if __cpp_lib_out_ptr != 202311L
+# error "__cpp_lib_out_ptr should have the value 202311L in c++26"
# endif
# if !defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.compile.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.general.pass.cpp
similarity index 92%
rename from libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.compile.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.general.pass.cpp
index d2eb8c3a6ac00..1b45d04f7942d 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.compile.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.general.pass.cpp
@@ -21,14 +21,18 @@ int main(int, char**) {
std::unique_ptr<int> uPtr;
auto inoutUPtr1 = std::inout_ptr(uPtr);
+ (void)inoutUPtr1;
auto inoutUPtr2 = std::inout_ptr<int*>(uPtr);
+ (void)inoutUPtr2;
}
{
auto deleter = [](auto* p) { delete p; };
std::unique_ptr<int, decltype(deleter)> uPtr;
auto inoutUPtr1 = std::inout_ptr(uPtr, deleter);
+ (void)inoutUPtr1;
auto inoutUPtr2 = std::inout_ptr<int*>(uPtr, deleter);
+ (void)inoutUPtr2;
}
return 0;
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.pass.cpp
index ece5628053427..58f09dc3a9ec3 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.pass.cpp
@@ -10,10 +10,6 @@
// <memory>
-// [inout.ptr.t], class template inout_ptr_t
-// template<class Smart, class Pointer, class... Args>
-// class inout_ptr_t; // since c++23
-
// [inout.ptr], function template inout_ptr
// template<class Pointer = void, class Smart, class... Args>
// auto inout_ptr(Smart& s, Args&&... args); // since c++23
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.ctor.pass.cpp
new file mode 100644
index 0000000000000..0a21a41539e43
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.ctor.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <memory>
+
+// [inout.ptr.t], class template inout_ptr_t
+// template<class Smart, class Pointer, class... Args>
+// class inout_ptr_t; // since c++23
+
+// explicit inout_ptr_t(Smart&, Args...);
+
+#include <memory>
+
+#include "test_convertible.h"
+
+int main(int, char**) {
+ {
+ std::unique_ptr<int> uPtr;
+
+ std::inout_ptr_t<std::unique_ptr<int>, int*>{uPtr};
+
+ static_assert(
+ !test_convertible<std::inout_ptr_t<std::unique_ptr<int>, int*>>(), "This constructor must be explicit");
+ }
+ {
+ auto deleter = [](auto* p) { delete p; };
+ std::unique_ptr<int, decltype(deleter)> uPtr;
+
+ std::inout_ptr_t<std::unique_ptr<int, decltype(deleter)>, int*>{uPtr};
+
+ static_assert(!test_convertible<std::inout_ptr_t<std::unique_ptr<int, decltype(deleter)>, int*>>(),
+ "This constructor must be explicit");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.compile.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.deref.pass.cpp
similarity index 91%
rename from libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.compile.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.deref.pass.cpp
index 18979d014dc01..86a055a7644e2 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.compile.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.deref.pass.cpp
@@ -14,6 +14,9 @@
// template<class Smart, class Pointer, class... Args>
// class inout_ptr_t; // since c++23
+// operator Pointer*() const noexcept;
+// operator void**() const noexcept;
+
#include <memory>
int main(int, char**) {
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.verify.cpp
index 3e23e54378120..eb296767085b7 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.verify.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.verify.cpp
@@ -23,6 +23,7 @@ int main(int, char**) {
// expected-error-re@*:* {{{{(static_assert|static assertion)}} failed due to requirement '!__is_specialization_v<std::shared_ptr<int>, std::shared_ptr>'{{.*}}std::shared_ptr<> is not supported}}
auto inoutUPtr1 = std::inout_ptr(sPtr);
+ // expected-error@*:* {{no matching conversion for functional-style cast from 'std::shared_ptr<int>' to 'std::inout_ptr_t<shared_ptr<int>, _Ptr>' (aka 'inout_ptr_t<std::shared_ptr<int>, int *>'}}
auto inoutUPtr2 = std::inout_ptr<int*>(sPtr);
}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.compile.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.general.pass.cpp
similarity index 92%
rename from libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.compile.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.general.pass.cpp
index 71f78a5bf770a..84bea7248e7a6 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.compile.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.general.pass.cpp
@@ -21,13 +21,17 @@ int main(int, char**) {
std::unique_ptr<int> uPtr;
auto outUPtr1 = std::out_ptr(uPtr);
+ (void)outUPtr1;
auto outUPtr2 = std::out_ptr<int*>(uPtr);
+ (void)outUPtr2;
}
{
std::shared_ptr<int> sPtr;
auto outSPtr1 = std::out_ptr(sPtr, [](auto* p) { delete p; });
+ (void)outSPtr1;
auto outSPtr2 = std::out_ptr<int*>(sPtr, [](auto* p) { delete p; });
+ (void)outSPtr2;
}
return 0;
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.pass.cpp
index 2ccf48643c332..a5189717fad62 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.pass.cpp
@@ -10,10 +10,6 @@
// <memory>
-// [out.ptr.t], class template out_ptr_t
-// template<class Smart, class Pointer, class... Args>
-// class out_ptr_t; // since c++23
-
// [out.ptr], function template out_ptr
// template<class Pointer = void, class Smart, class... Args>
// auto out_ptr(Smart& s, Args&&... args); // since c++23
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.ctor.pass.cpp
new file mode 100644
index 0000000000000..39604247216e8
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.ctor.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <memory>
+
+// [out.ptr.t], class template out_ptr_t
+// template<class Smart, class Pointer, class... Args>
+// class out_ptr_t; // since c++23
+
+// explicit out_ptr_t(Smart&, Args...);
+
+#include <memory>
+
+#include "test_convertible.h"
+
+int main(int, char**) {
+ {
+ std::unique_ptr<int> uPtr;
+
+ std::out_ptr_t<std::unique_ptr<int>, int*>{uPtr};
+
+ static_assert(!test_convertible<std::out_ptr_t<std::unique_ptr<int>, int*>>(), "This constructor must be explicit");
+ }
+ {
+ std::unique_ptr<int, std::default_delete<int>> uPtr;
+
+ std::out_ptr_t<decltype(uPtr), int*, std::default_delete<int>>{uPtr, std::default_delete<int>{}};
+
+ static_assert(!test_convertible<std::out_ptr_t<decltype(uPtr), int*, std::default_delete<int>>>(),
+ "This constructor must be explicit");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.compile.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.deref.pass.cpp
similarity index 92%
rename from libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.compile.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.deref.pass.cpp
index 12ad53ac3811e..a0f3af8f87fd7 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.compile.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.deref.pass.cpp
@@ -14,6 +14,9 @@
// template<class Smart, class Pointer, class... Args>
// class out_ptr_t; // since c++23
+// operator Pointer*() const noexcept;
+// operator void**() const noexcept;
+
#include <memory>
int main(int, char**) {
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.verify.cpp
index f48592059ea0a..3c51583421e76 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.verify.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.verify.cpp
@@ -23,6 +23,7 @@ int main(int, char**) {
// expected-error-re@*:* {{{{(static_assert|static assertion)}} failed due to requirement '!__is_specialization_v<std::shared_ptr<int>, std::shared_ptr> || sizeof...(_Args) > 0'{{.*}}Specialization of std::shared_ptr<> requires a deleter.}}
auto outSPtr1 = std::out_ptr(sPtr);
+ // expected-error@*:* {{no matching conversion for functional-style cast from 'std::shared_ptr<int>' to 'std::out_ptr_t<shared_ptr<int>, _Ptr>' (aka 'out_ptr_t<std::shared_ptr<int>, int *>')}}
auto outSPtr2 = std::out_ptr<int*>(sPtr);
}
>From b23e91a1ca684b8454fe84ff570b7245f52e49d1 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <zingam at outlook.com>
Date: Thu, 30 Nov 2023 15:03:00 +0200
Subject: [PATCH 03/23] [out_ptr] Added tests
---
.../inout.ptr.compile.pass.cpp} | 18 +-
.../inout.ptr/inout.ptr.general.pass.cpp | 184 +++++++++++++++-
.../adapt/inout.ptr/inout.ptr.pass.cpp | 201 ------------------
....pass.cpp => inout.ptr.t.convert.pass.cpp} | 20 +-
...eral.pass.cpp => out.ptr.compile.pass.cpp} | 4 -
.../{out.ptr.pass.cpp => out.ptr.general.cpp} | 0
.../adapt/out.ptr/out.ptr.t.convert.pass.cpp | 58 +++++
7 files changed, 256 insertions(+), 229 deletions(-)
rename libcxx/test/std/utilities/smartptr/adapt/{out.ptr/out.ptr.t.deref.pass.cpp => inout.ptr/inout.ptr.compile.pass.cpp} (54%)
delete mode 100644 libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.pass.cpp
rename libcxx/test/std/utilities/smartptr/adapt/inout.ptr/{inout.ptr.t.deref.pass.cpp => inout.ptr.t.convert.pass.cpp} (55%)
rename libcxx/test/std/utilities/smartptr/adapt/out.ptr/{out.ptr.general.pass.cpp => out.ptr.compile.pass.cpp} (92%)
rename libcxx/test/std/utilities/smartptr/adapt/out.ptr/{out.ptr.pass.cpp => out.ptr.general.cpp} (100%)
create mode 100644 libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.convert.pass.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.deref.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.compile.pass.cpp
similarity index 54%
rename from libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.deref.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.compile.pass.cpp
index a0f3af8f87fd7..d2eb8c3a6ac00 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.deref.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.compile.pass.cpp
@@ -10,12 +10,9 @@
// <memory>
-// [out.ptr.t], class template out_ptr_t
-// template<class Smart, class Pointer, class... Args>
-// class out_ptr_t; // since c++23
-
-// operator Pointer*() const noexcept;
-// operator void**() const noexcept;
+// [inout.ptr], function template inout_ptr
+// template<class Pointer = void, class Smart, class... Args>
+// auto inout_ptr(Smart& s, Args&&... args); // since c++23
#include <memory>
@@ -23,12 +20,15 @@ int main(int, char**) {
{
std::unique_ptr<int> uPtr;
- std::out_ptr_t<std::unique_ptr<int>, int*>{uPtr};
+ auto inoutUPtr1 = std::inout_ptr(uPtr);
+ auto inoutUPtr2 = std::inout_ptr<int*>(uPtr);
}
{
- std::unique_ptr<int, std::default_delete<int>> uPtr;
+ auto deleter = [](auto* p) { delete p; };
+ std::unique_ptr<int, decltype(deleter)> uPtr;
- std::out_ptr_t<decltype(uPtr), int*, std::default_delete<int>>{uPtr, std::default_delete<int>{}};
+ auto inoutUPtr1 = std::inout_ptr(uPtr, deleter);
+ auto inoutUPtr2 = std::inout_ptr<int*>(uPtr, deleter);
}
return 0;
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.general.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.general.pass.cpp
index 1b45d04f7942d..58f09dc3a9ec3 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.general.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.general.pass.cpp
@@ -14,26 +14,188 @@
// template<class Pointer = void, class Smart, class... Args>
// auto inout_ptr(Smart& s, Args&&... args); // since c++23
+#include <cassert>
#include <memory>
-int main(int, char**) {
+#include "../types.h"
+
+// Test helpers.
+
+void replace_int_p(int** pp) {
+ assert(**pp == 90);
+ delete *pp;
+ *pp = new int{84};
+}
+
+void replace_int_p_with_nullptr(int** pp) {
+ assert(**pp == 90);
+ delete *pp;
+ *pp = nullptr;
+}
+
+void replace_nullptr_with_int_p(int** pp) {
+ assert(*pp == nullptr);
+ *pp = new int{84};
+}
+
+void replace_int_void_p(void** pp) {
+ assert(*(static_cast<int*>(*pp)) == 90);
+ delete static_cast<int*>(*pp);
+ *pp = new int{84};
+}
+
+void replace_int_void_p_with_nullptr(void** pp) {
+ assert(*(static_cast<int*>(*pp)) == 90);
+ delete static_cast<int*>(*pp);
+ *pp = nullptr;
+}
+
+void replace_nullptr_with_int_void_p(void** pp) {
+ assert(*pp == nullptr);
+ *pp = new int{84};
+}
+
+void replace_SomeInt_p(SomeInt** pp) {
+ auto si = **pp;
+ assert(si.value == 90);
+ delete static_cast<SomeInt*>(*pp);
+ *pp = new SomeInt{9084};
+}
+
+void replace_SomeInt_void_p(void** pp) {
+ assert(reinterpret_cast<SomeInt*>(*pp)->value == 90);
+ delete static_cast<SomeInt*>(*pp);
+ *pp = reinterpret_cast<void*>(new SomeInt{9084});
+}
+
+// Test `std::inout_ptr()` function.
+
+void test_raw_ptr() {
+ {
+ auto rPtr = new int{90};
+
+ replace_int_p(std::inout_ptr<int*>(rPtr));
+ assert(*rPtr == 84);
+
+ delete rPtr;
+ }
+ {
+ auto rPtr = new int{90};
+
+ replace_int_p_with_nullptr(std::inout_ptr<int*>(rPtr));
+ assert(rPtr == nullptr);
+ }
+ {
+ int* rPtr = nullptr;
+
+ replace_nullptr_with_int_p(std::inout_ptr<int*>(rPtr));
+ assert(*rPtr == 84);
+ delete rPtr;
+ }
+ {
+ auto rPtr = new int{90};
+
+ replace_int_void_p(std::inout_ptr<int*>(rPtr));
+ assert(*rPtr == 84);
+ delete rPtr;
+ }
+ {
+ auto rPtr = new int{90};
+
+ replace_int_void_p_with_nullptr(std::inout_ptr<int*>(rPtr));
+ assert(rPtr == nullptr);
+ }
+ {
+ int* rPtr = nullptr;
+
+ replace_nullptr_with_int_void_p(std::inout_ptr<int*>(rPtr));
+ assert(*rPtr == 84);
+ delete rPtr;
+ }
+ {
+ auto* rPtr = new SomeInt{90};
+
+ replace_SomeInt_p(std::inout_ptr(rPtr));
+ assert(rPtr->value == 9084);
+ delete rPtr;
+ }
+ {
+ auto* rPtr = new SomeInt{90};
+
+ replace_SomeInt_void_p(std::inout_ptr<SomeInt*>(rPtr));
+ assert(rPtr->value == 9084);
+ delete rPtr;
+ }
+}
+
+void test_unique_ptr() {
+ {
+ auto uPtr = std::make_unique<int>(90);
+
+ replace_int_p(std::inout_ptr(uPtr));
+ assert(*uPtr == 84);
+ }
{
std::unique_ptr<int> uPtr;
- auto inoutUPtr1 = std::inout_ptr(uPtr);
- (void)inoutUPtr1;
- auto inoutUPtr2 = std::inout_ptr<int*>(uPtr);
- (void)inoutUPtr2;
+ replace_nullptr_with_int_p(std::inout_ptr(uPtr));
+ assert(*uPtr == 84);
}
{
- auto deleter = [](auto* p) { delete p; };
- std::unique_ptr<int, decltype(deleter)> uPtr;
+ auto uPtr = std::make_unique<int>(90);
- auto inoutUPtr1 = std::inout_ptr(uPtr, deleter);
- (void)inoutUPtr1;
- auto inoutUPtr2 = std::inout_ptr<int*>(uPtr, deleter);
- (void)inoutUPtr2;
+ replace_int_void_p(std::inout_ptr(uPtr));
+ assert(*uPtr == 84);
}
+ {
+ std::unique_ptr<int> uPtr;
+
+ replace_nullptr_with_int_void_p(std::inout_ptr(uPtr));
+ assert(*uPtr == 84);
+ }
+ {
+ auto uPtr = std::make_unique<SomeInt>(90);
+
+ replace_SomeInt_p(std::inout_ptr(uPtr));
+ assert(uPtr->value == 9084);
+ }
+ {
+ auto uPtr = std::make_unique<SomeInt>(90);
+
+ replace_SomeInt_void_p(std::inout_ptr<SomeInt*>(uPtr));
+ assert(uPtr->value == 9084);
+ }
+}
+
+void test_custom_ptr() {
+ // ConstructiblePtr
+ {
+ ConstructiblePtr<int> cPtr(new int{90});
+
+ replace_int_p(std::inout_ptr(cPtr));
+ assert(cPtr == 84);
+ }
+ // ResettablePtr
+ {
+ ResettablePtr<int> rPtr(new int{90});
+
+ replace_int_p(std::inout_ptr(rPtr));
+ assert(rPtr == 84);
+ }
+ // NonConstructiblePtr
+ {
+ NonConstructiblePtr<int> nPtr;
+ nPtr.reset(new int{90});
+
+ replace_int_p(std::inout_ptr(nPtr));
+ assert(nPtr == 84);
+ }
+}
+
+int main(int, char**) {
+ test_raw_ptr();
+ test_unique_ptr();
+ test_custom_ptr();
return 0;
}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.pass.cpp
deleted file mode 100644
index 58f09dc3a9ec3..0000000000000
--- a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.pass.cpp
+++ /dev/null
@@ -1,201 +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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-
-// <memory>
-
-// [inout.ptr], function template inout_ptr
-// template<class Pointer = void, class Smart, class... Args>
-// auto inout_ptr(Smart& s, Args&&... args); // since c++23
-
-#include <cassert>
-#include <memory>
-
-#include "../types.h"
-
-// Test helpers.
-
-void replace_int_p(int** pp) {
- assert(**pp == 90);
- delete *pp;
- *pp = new int{84};
-}
-
-void replace_int_p_with_nullptr(int** pp) {
- assert(**pp == 90);
- delete *pp;
- *pp = nullptr;
-}
-
-void replace_nullptr_with_int_p(int** pp) {
- assert(*pp == nullptr);
- *pp = new int{84};
-}
-
-void replace_int_void_p(void** pp) {
- assert(*(static_cast<int*>(*pp)) == 90);
- delete static_cast<int*>(*pp);
- *pp = new int{84};
-}
-
-void replace_int_void_p_with_nullptr(void** pp) {
- assert(*(static_cast<int*>(*pp)) == 90);
- delete static_cast<int*>(*pp);
- *pp = nullptr;
-}
-
-void replace_nullptr_with_int_void_p(void** pp) {
- assert(*pp == nullptr);
- *pp = new int{84};
-}
-
-void replace_SomeInt_p(SomeInt** pp) {
- auto si = **pp;
- assert(si.value == 90);
- delete static_cast<SomeInt*>(*pp);
- *pp = new SomeInt{9084};
-}
-
-void replace_SomeInt_void_p(void** pp) {
- assert(reinterpret_cast<SomeInt*>(*pp)->value == 90);
- delete static_cast<SomeInt*>(*pp);
- *pp = reinterpret_cast<void*>(new SomeInt{9084});
-}
-
-// Test `std::inout_ptr()` function.
-
-void test_raw_ptr() {
- {
- auto rPtr = new int{90};
-
- replace_int_p(std::inout_ptr<int*>(rPtr));
- assert(*rPtr == 84);
-
- delete rPtr;
- }
- {
- auto rPtr = new int{90};
-
- replace_int_p_with_nullptr(std::inout_ptr<int*>(rPtr));
- assert(rPtr == nullptr);
- }
- {
- int* rPtr = nullptr;
-
- replace_nullptr_with_int_p(std::inout_ptr<int*>(rPtr));
- assert(*rPtr == 84);
- delete rPtr;
- }
- {
- auto rPtr = new int{90};
-
- replace_int_void_p(std::inout_ptr<int*>(rPtr));
- assert(*rPtr == 84);
- delete rPtr;
- }
- {
- auto rPtr = new int{90};
-
- replace_int_void_p_with_nullptr(std::inout_ptr<int*>(rPtr));
- assert(rPtr == nullptr);
- }
- {
- int* rPtr = nullptr;
-
- replace_nullptr_with_int_void_p(std::inout_ptr<int*>(rPtr));
- assert(*rPtr == 84);
- delete rPtr;
- }
- {
- auto* rPtr = new SomeInt{90};
-
- replace_SomeInt_p(std::inout_ptr(rPtr));
- assert(rPtr->value == 9084);
- delete rPtr;
- }
- {
- auto* rPtr = new SomeInt{90};
-
- replace_SomeInt_void_p(std::inout_ptr<SomeInt*>(rPtr));
- assert(rPtr->value == 9084);
- delete rPtr;
- }
-}
-
-void test_unique_ptr() {
- {
- auto uPtr = std::make_unique<int>(90);
-
- replace_int_p(std::inout_ptr(uPtr));
- assert(*uPtr == 84);
- }
- {
- std::unique_ptr<int> uPtr;
-
- replace_nullptr_with_int_p(std::inout_ptr(uPtr));
- assert(*uPtr == 84);
- }
- {
- auto uPtr = std::make_unique<int>(90);
-
- replace_int_void_p(std::inout_ptr(uPtr));
- assert(*uPtr == 84);
- }
- {
- std::unique_ptr<int> uPtr;
-
- replace_nullptr_with_int_void_p(std::inout_ptr(uPtr));
- assert(*uPtr == 84);
- }
- {
- auto uPtr = std::make_unique<SomeInt>(90);
-
- replace_SomeInt_p(std::inout_ptr(uPtr));
- assert(uPtr->value == 9084);
- }
- {
- auto uPtr = std::make_unique<SomeInt>(90);
-
- replace_SomeInt_void_p(std::inout_ptr<SomeInt*>(uPtr));
- assert(uPtr->value == 9084);
- }
-}
-
-void test_custom_ptr() {
- // ConstructiblePtr
- {
- ConstructiblePtr<int> cPtr(new int{90});
-
- replace_int_p(std::inout_ptr(cPtr));
- assert(cPtr == 84);
- }
- // ResettablePtr
- {
- ResettablePtr<int> rPtr(new int{90});
-
- replace_int_p(std::inout_ptr(rPtr));
- assert(rPtr == 84);
- }
- // NonConstructiblePtr
- {
- NonConstructiblePtr<int> nPtr;
- nPtr.reset(new int{90});
-
- replace_int_p(std::inout_ptr(nPtr));
- assert(nPtr == 84);
- }
-}
-
-int main(int, char**) {
- test_raw_ptr();
- test_unique_ptr();
- test_custom_ptr();
-
- return 0;
-}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.deref.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.convert.pass.cpp
similarity index 55%
rename from libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.deref.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.convert.pass.cpp
index 86a055a7644e2..cee19c11c78c3 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.deref.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.convert.pass.cpp
@@ -17,18 +17,30 @@
// operator Pointer*() const noexcept;
// operator void**() const noexcept;
+#include <cassert>
+#include <concepts>
#include <memory>
int main(int, char**) {
{
- std::unique_ptr<int> uPtr;
+ std::unique_ptr<int> uPtr = std::make_unique<int>(84);
- std::inout_ptr_t<std::unique_ptr<int>, int*>{uPtr};
+ const std::inout_ptr_t<std::unique_ptr<int>, int*> ioPtr{uPtr};
+
+ static_assert(noexcept(ioPtr.operator int**()));
+ std::same_as<int**> decltype(auto) pPtr = ioPtr.operator int**();
+
+ assert(**pPtr == 84);
}
{
- std::unique_ptr<int> uPtr;
+ std::unique_ptr<int> uPtr = std::make_unique<int>(84);
+
+ const std::inout_ptr_t<std::unique_ptr<int>, void*> ioPtr{uPtr};
+
+ static_assert(noexcept(ioPtr.operator void**()));
+ std::same_as<void**> decltype(auto) pPtr = ioPtr.operator void**();
- std::inout_ptr_t<std::unique_ptr<int>, int*>{uPtr};
+ assert(**reinterpret_cast<int**>(pPtr) == 84);
}
return 0;
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.general.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.compile.pass.cpp
similarity index 92%
rename from libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.general.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.compile.pass.cpp
index 84bea7248e7a6..71f78a5bf770a 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.general.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.compile.pass.cpp
@@ -21,17 +21,13 @@ int main(int, char**) {
std::unique_ptr<int> uPtr;
auto outUPtr1 = std::out_ptr(uPtr);
- (void)outUPtr1;
auto outUPtr2 = std::out_ptr<int*>(uPtr);
- (void)outUPtr2;
}
{
std::shared_ptr<int> sPtr;
auto outSPtr1 = std::out_ptr(sPtr, [](auto* p) { delete p; });
- (void)outSPtr1;
auto outSPtr2 = std::out_ptr<int*>(sPtr, [](auto* p) { delete p; });
- (void)outSPtr2;
}
return 0;
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.general.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.general.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.convert.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.convert.pass.cpp
new file mode 100644
index 0000000000000..1e19d1ee5b4ec
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.convert.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <memory>
+
+// [out.ptr.t], class template out_ptr_t
+// template<class Smart, class Pointer, class... Args>
+// class out_ptr_t; // since c++23
+
+// operator Pointer*() const noexcept;
+// operator void**() const noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <memory>
+#include <iostream>
+
+int main(int, char**) {
+ {
+ std::unique_ptr<int> uPtr;
+
+ const std::out_ptr_t<std::unique_ptr<int>, int*> oPtr{uPtr};
+
+ static_assert(noexcept(oPtr.operator int**()));
+ std::same_as<int**> decltype(auto) pPtr = oPtr.operator int**();
+
+ assert(*pPtr == nullptr);
+ }
+ {
+ std::unique_ptr<int, std::default_delete<int>> uPtr;
+
+ const std::out_ptr_t<decltype(uPtr), int*, std::default_delete<int>> oPtr{uPtr, std::default_delete<int>{}};
+
+ static_assert(noexcept(oPtr.operator int**()));
+ std::same_as<int**> decltype(auto) pPtr = oPtr.operator int**();
+
+ assert(*pPtr == nullptr);
+ }
+ {
+ std::unique_ptr<int> uPtr;
+
+ const std::out_ptr_t<std::unique_ptr<int>, void*> oPtr{uPtr};
+
+ static_assert(noexcept(oPtr.operator void**()));
+ std::same_as<void**> decltype(auto) pPtr = oPtr.operator void**();
+
+ assert(*pPtr == nullptr);
+ }
+
+ return 0;
+}
>From cb71ea2e2942a85b85712a877f994b6189efd83b Mon Sep 17 00:00:00 2001
From: Hristo Hristov <zingam at outlook.com>
Date: Thu, 30 Nov 2023 15:04:52 +0200
Subject: [PATCH 04/23] Removed tests files
---
.../inout.ptr/inout.ptr.compile.pass.cpp | 35 -------------------
.../adapt/out.ptr/out.ptr.compile.pass.cpp | 34 ------------------
2 files changed, 69 deletions(-)
delete mode 100644 libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.compile.pass.cpp
delete mode 100644 libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.compile.pass.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.compile.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.compile.pass.cpp
deleted file mode 100644
index d2eb8c3a6ac00..0000000000000
--- a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.compile.pass.cpp
+++ /dev/null
@@ -1,35 +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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-
-// <memory>
-
-// [inout.ptr], function template inout_ptr
-// template<class Pointer = void, class Smart, class... Args>
-// auto inout_ptr(Smart& s, Args&&... args); // since c++23
-
-#include <memory>
-
-int main(int, char**) {
- {
- std::unique_ptr<int> uPtr;
-
- auto inoutUPtr1 = std::inout_ptr(uPtr);
- auto inoutUPtr2 = std::inout_ptr<int*>(uPtr);
- }
- {
- auto deleter = [](auto* p) { delete p; };
- std::unique_ptr<int, decltype(deleter)> uPtr;
-
- auto inoutUPtr1 = std::inout_ptr(uPtr, deleter);
- auto inoutUPtr2 = std::inout_ptr<int*>(uPtr, deleter);
- }
-
- return 0;
-}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.compile.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.compile.pass.cpp
deleted file mode 100644
index 71f78a5bf770a..0000000000000
--- a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.compile.pass.cpp
+++ /dev/null
@@ -1,34 +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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-
-// <memory>
-
-// [out.ptr], function template out_ptr
-// template<class Pointer = void, class Smart, class... Args>
-// auto out_ptr(Smart& s, Args&&... args); // since c++23
-
-#include <memory>
-
-int main(int, char**) {
- {
- std::unique_ptr<int> uPtr;
-
- auto outUPtr1 = std::out_ptr(uPtr);
- auto outUPtr2 = std::out_ptr<int*>(uPtr);
- }
- {
- std::shared_ptr<int> sPtr;
-
- auto outSPtr1 = std::out_ptr(sPtr, [](auto* p) { delete p; });
- auto outSPtr2 = std::out_ptr<int*>(sPtr, [](auto* p) { delete p; });
- }
-
- return 0;
-}
>From d9e04a741ae92ff7916910ca6afd764eab610d63 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <zingam at outlook.com>
Date: Thu, 14 Dec 2023 20:53:43 +0200
Subject: [PATCH 05/23] Addressed comments: Renamed test files
---
.../{inout.ptr.general.pass.cpp => inout_ptr.general.pass.cpp} | 0
.../inout.ptr/{inout.ptr.verify.cpp => inout_ptr.verify.cpp} | 0
...{inout.ptr.t.convert.pass.cpp => inout_ptr_t.convert.pass.cpp} | 0
.../{inout.ptr.t.ctor.pass.cpp => inout_ptr_t.ctor.pass.cpp} | 0
.../inout.ptr/{inout.ptr.t.verify.cpp => inout_ptr_t.verify.cpp} | 0
.../adapt/out.ptr/{out.ptr.general.cpp => out_ptr.general.cpp} | 0
.../adapt/out.ptr/{out.ptr.verify.cpp => out_ptr.verify.cpp} | 0
.../{out.ptr.t.convert.pass.cpp => out_ptr_t.convert.pass.cpp} | 0
.../out.ptr/{out.ptr.t.ctor.pass.cpp => out_ptr_t.ctor.pass.cpp} | 0
.../adapt/out.ptr/{out.ptr.t.verify.cpp => out_ptr_t.verify.cpp} | 0
10 files changed, 0 insertions(+), 0 deletions(-)
rename libcxx/test/std/utilities/smartptr/adapt/inout.ptr/{inout.ptr.general.pass.cpp => inout_ptr.general.pass.cpp} (100%)
rename libcxx/test/std/utilities/smartptr/adapt/inout.ptr/{inout.ptr.verify.cpp => inout_ptr.verify.cpp} (100%)
rename libcxx/test/std/utilities/smartptr/adapt/inout.ptr/{inout.ptr.t.convert.pass.cpp => inout_ptr_t.convert.pass.cpp} (100%)
rename libcxx/test/std/utilities/smartptr/adapt/inout.ptr/{inout.ptr.t.ctor.pass.cpp => inout_ptr_t.ctor.pass.cpp} (100%)
rename libcxx/test/std/utilities/smartptr/adapt/inout.ptr/{inout.ptr.t.verify.cpp => inout_ptr_t.verify.cpp} (100%)
rename libcxx/test/std/utilities/smartptr/adapt/out.ptr/{out.ptr.general.cpp => out_ptr.general.cpp} (100%)
rename libcxx/test/std/utilities/smartptr/adapt/out.ptr/{out.ptr.verify.cpp => out_ptr.verify.cpp} (100%)
rename libcxx/test/std/utilities/smartptr/adapt/out.ptr/{out.ptr.t.convert.pass.cpp => out_ptr_t.convert.pass.cpp} (100%)
rename libcxx/test/std/utilities/smartptr/adapt/out.ptr/{out.ptr.t.ctor.pass.cpp => out_ptr_t.ctor.pass.cpp} (100%)
rename libcxx/test/std/utilities/smartptr/adapt/out.ptr/{out.ptr.t.verify.cpp => out_ptr_t.verify.cpp} (100%)
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.general.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr.general.pass.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.general.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr.general.pass.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr.verify.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.verify.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr.verify.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.convert.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr_t.convert.pass.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.convert.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr_t.convert.pass.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr_t.ctor.pass.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.ctor.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr_t.ctor.pass.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr_t.verify.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout.ptr.t.verify.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr_t.verify.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.general.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.general.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.general.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.general.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.verify.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.verify.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.verify.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.convert.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr_t.convert.pass.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.convert.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr_t.convert.pass.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr_t.ctor.pass.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.ctor.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr_t.ctor.pass.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr_t.verify.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/out.ptr/out.ptr.t.verify.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr_t.verify.cpp
>From 3405ee5a7c5d5e367f6c533c033600d20bb959d7 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <zingam at outlook.com>
Date: Fri, 15 Dec 2023 10:05:17 +0200
Subject: [PATCH 06/23] Addressed comments: Renamed ctr args
---
libcxx/include/__memory/inout_ptr.h | 14 +++++++-------
libcxx/include/__memory/out_ptr.h | 6 +++---
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/libcxx/include/__memory/inout_ptr.h b/libcxx/include/__memory/inout_ptr.h
index f91ecd8baff57..18157b271cd75 100644
--- a/libcxx/include/__memory/inout_ptr.h
+++ b/libcxx/include/__memory/inout_ptr.h
@@ -33,18 +33,18 @@ class _LIBCPP_TEMPLATE_VIS inout_ptr_t {
static_assert(!__is_specialization_v<_Smart, shared_ptr>, "std::shared_ptr<> is not supported");
public:
- _LIBCPP_HIDE_FROM_ABI explicit inout_ptr_t(_Smart& __s, _Args... __args)
- : __s_(__s), __a_(std::forward<_Args>(__args)...), __p_([&__s] {
+ _LIBCPP_HIDE_FROM_ABI explicit inout_ptr_t(_Smart& __smart, _Args... __args)
+ : __s_(__smart), __a_(std::forward<_Args>(__args)...), __p_([&__smart] {
if constexpr (is_pointer_v<_Smart>) {
- return __s;
+ return __smart;
} else {
- return __s.get();
+ return __smart.get();
}
}()) {
- if constexpr (requires { __s.release(); }) {
- __s.release();
+ if constexpr (requires { __s_.release(); }) {
+ __s_.release();
} else {
- __s = _Smart();
+ __s_ = _Smart();
}
}
diff --git a/libcxx/include/__memory/out_ptr.h b/libcxx/include/__memory/out_ptr.h
index eebc18c97fdcd..6d3dd4b588dab 100644
--- a/libcxx/include/__memory/out_ptr.h
+++ b/libcxx/include/__memory/out_ptr.h
@@ -36,9 +36,9 @@ class _LIBCPP_TEMPLATE_VIS out_ptr_t {
"Specialization of std::shared_ptr<> requires a deleter.");
public:
- _LIBCPP_HIDE_FROM_ABI explicit out_ptr_t(_Smart& __s, _Args... __args)
- : __s_(__s), __a_(std::forward<_Args>(__args)...), __p_() {
- using _Ptr = decltype(__s);
+ _LIBCPP_HIDE_FROM_ABI explicit out_ptr_t(_Smart& __smart, _Args... __args)
+ : __s_(__smart), __a_(std::forward<_Args>(__args)...), __p_() {
+ using _Ptr = decltype(__smart);
if constexpr (__resettable_smart_pointer<_Ptr>) {
__s_.reset();
} else if constexpr (is_constructible_v<_Smart>) {
>From 2b2aaec9aaac7ae7a764e2639f34a1bb3d7412fd Mon Sep 17 00:00:00 2001
From: Hristo Hristov <zingam at outlook.com>
Date: Fri, 15 Dec 2023 18:54:24 +0200
Subject: [PATCH 07/23] Addressed comments: Refactored tests
---
libcxx/include/__memory/out_ptr.h | 2 +
libcxx/include/__memory/pointer_traits.h | 2 +-
.../inout.ptr/inout_ptr.general.pass.cpp | 218 ++++++++----------
.../adapt/out.ptr/out_ptr.general.cpp | 159 -------------
.../adapt/out.ptr/out_ptr.general.pass.cpp | 212 +++++++++++++++++
.../smartptr/adapt/out.ptr/out_ptr.verify.cpp | 21 ++
.../test/std/utilities/smartptr/adapt/types.h | 23 ++
7 files changed, 360 insertions(+), 277 deletions(-)
delete mode 100644 libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.general.cpp
create mode 100644 libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.general.pass.cpp
diff --git a/libcxx/include/__memory/out_ptr.h b/libcxx/include/__memory/out_ptr.h
index 6d3dd4b588dab..618fc372bd965 100644
--- a/libcxx/include/__memory/out_ptr.h
+++ b/libcxx/include/__memory/out_ptr.h
@@ -63,6 +63,8 @@ class _LIBCPP_TEMPLATE_VIS out_ptr_t {
std::apply([&](auto&&... __args) { __s_ = _Smart(static_cast<_SP>(__p_), std::forward<_Args>(__args)...); },
std::move(__a_));
} else {
+ // static_assert(__resettable_smart_pointer_with_args<_Smart, _Pointer, _Args...>);
+ // static_assert(is_constructible_v<_Smart, _SP, _Args...>);
static_assert(__resettable_smart_pointer_with_args<_Smart, _Pointer, _Args...> ||
is_constructible_v<_Smart, _SP, _Args...>);
}
diff --git a/libcxx/include/__memory/pointer_traits.h b/libcxx/include/__memory/pointer_traits.h
index 4e902746e6a35..bf486c6ddbb17 100644
--- a/libcxx/include/__memory/pointer_traits.h
+++ b/libcxx/include/__memory/pointer_traits.h
@@ -292,7 +292,7 @@ using __pointer_of_or_t = typename __pointer_of_or<_Tp, _Up>::type;
template <class _Smart>
concept __resettable_smart_pointer = requires(_Smart __s) { __s.reset(); };
-template <class _Smart, class _Pointer = void, class... _Args>
+template <class _Smart, class _Pointer, class... _Args>
concept __resettable_smart_pointer_with_args = requires(_Smart __s, _Pointer __p, _Args... __args) {
__s.reset(static_cast<__pointer_of_or_t<_Smart, _Pointer>>(__p), std::forward<_Args>(__args)...);
};
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr.general.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr.general.pass.cpp
index 58f09dc3a9ec3..4114ab6ee7549 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr.general.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr.general.pass.cpp
@@ -19,58 +19,15 @@
#include "../types.h"
-// Test helpers.
+void test_replace_int_p() {
+ auto replace_int_p = [](int** pp) {
+ assert(**pp == 90);
-void replace_int_p(int** pp) {
- assert(**pp == 90);
- delete *pp;
- *pp = new int{84};
-}
-
-void replace_int_p_with_nullptr(int** pp) {
- assert(**pp == 90);
- delete *pp;
- *pp = nullptr;
-}
-
-void replace_nullptr_with_int_p(int** pp) {
- assert(*pp == nullptr);
- *pp = new int{84};
-}
-
-void replace_int_void_p(void** pp) {
- assert(*(static_cast<int*>(*pp)) == 90);
- delete static_cast<int*>(*pp);
- *pp = new int{84};
-}
-
-void replace_int_void_p_with_nullptr(void** pp) {
- assert(*(static_cast<int*>(*pp)) == 90);
- delete static_cast<int*>(*pp);
- *pp = nullptr;
-}
-
-void replace_nullptr_with_int_void_p(void** pp) {
- assert(*pp == nullptr);
- *pp = new int{84};
-}
-
-void replace_SomeInt_p(SomeInt** pp) {
- auto si = **pp;
- assert(si.value == 90);
- delete static_cast<SomeInt*>(*pp);
- *pp = new SomeInt{9084};
-}
-
-void replace_SomeInt_void_p(void** pp) {
- assert(reinterpret_cast<SomeInt*>(*pp)->value == 90);
- delete static_cast<SomeInt*>(*pp);
- *pp = reinterpret_cast<void*>(new SomeInt{9084});
-}
-
-// Test `std::inout_ptr()` function.
+ delete *pp;
+ *pp = new int{84};
+ };
-void test_raw_ptr() {
+ // raw pointer
{
auto rPtr = new int{90};
@@ -79,123 +36,150 @@ void test_raw_ptr() {
delete rPtr;
}
- {
- auto rPtr = new int{90};
- replace_int_p_with_nullptr(std::inout_ptr<int*>(rPtr));
- assert(rPtr == nullptr);
- }
+ // std::unique_ptr
{
- int* rPtr = nullptr;
+ auto uPtr = std::make_unique<int>(90);
- replace_nullptr_with_int_p(std::inout_ptr<int*>(rPtr));
- assert(*rPtr == 84);
- delete rPtr;
+ replace_int_p(std::inout_ptr(uPtr));
+ assert(*uPtr == 84);
}
- {
- auto rPtr = new int{90};
- replace_int_void_p(std::inout_ptr<int*>(rPtr));
- assert(*rPtr == 84);
- delete rPtr;
- }
+ // pointer-like ConstructiblePtr
{
- auto rPtr = new int{90};
+ ConstructiblePtr<int> cPtr(new int{90});
- replace_int_void_p_with_nullptr(std::inout_ptr<int*>(rPtr));
- assert(rPtr == nullptr);
+ replace_int_p(std::inout_ptr(cPtr));
+ assert(cPtr == 84);
}
+
+ // pointer-like ResettablePtr
{
- int* rPtr = nullptr;
+ ResettablePtr<int> rPtr(new int{90});
- replace_nullptr_with_int_void_p(std::inout_ptr<int*>(rPtr));
- assert(*rPtr == 84);
- delete rPtr;
+ replace_int_p(std::inout_ptr(rPtr));
+ assert(rPtr == 84);
}
+
+ // pointer-like NonConstructiblePtr
{
- auto* rPtr = new SomeInt{90};
+ NonConstructiblePtr<int> nPtr;
+ nPtr.reset(new int{90});
- replace_SomeInt_p(std::inout_ptr(rPtr));
- assert(rPtr->value == 9084);
- delete rPtr;
+ replace_int_p(std::inout_ptr(nPtr));
+ assert(nPtr == 84);
}
+}
+
+void test_replace_int_p_with_nullptr() {
+ auto replace_int_p_with_nullptr = [](int** pp) -> void {
+ assert(**pp == 90);
+
+ delete *pp;
+ *pp = nullptr;
+ };
+
+ // raw pointer
{
- auto* rPtr = new SomeInt{90};
+ auto rPtr = new int{90};
- replace_SomeInt_void_p(std::inout_ptr<SomeInt*>(rPtr));
- assert(rPtr->value == 9084);
- delete rPtr;
+ replace_int_p_with_nullptr(std::inout_ptr<int*>(rPtr));
+ assert(rPtr == nullptr);
}
-}
-void test_unique_ptr() {
+ // std::unique_ptr
{
auto uPtr = std::make_unique<int>(90);
- replace_int_p(std::inout_ptr(uPtr));
- assert(*uPtr == 84);
+ replace_int_p_with_nullptr(std::inout_ptr(uPtr));
+ assert(uPtr == nullptr);
}
+}
+
+void test_replace_int_void_p() {
+ auto replace_int_void_p = [](void** pp) {
+ assert(*(static_cast<int*>(*pp)) == 90);
+
+ delete static_cast<int*>(*pp);
+ *pp = new int{84};
+ };
+
+ // raw pointer
{
- std::unique_ptr<int> uPtr;
+ auto rPtr = new int{90};
- replace_nullptr_with_int_p(std::inout_ptr(uPtr));
- assert(*uPtr == 84);
+ replace_int_void_p(std::inout_ptr<int*>(rPtr));
+ assert(*rPtr == 84);
+
+ delete rPtr;
}
+
+ // std::unique_ptr
{
auto uPtr = std::make_unique<int>(90);
replace_int_void_p(std::inout_ptr(uPtr));
assert(*uPtr == 84);
}
- {
- std::unique_ptr<int> uPtr;
+}
- replace_nullptr_with_int_void_p(std::inout_ptr(uPtr));
- assert(*uPtr == 84);
- }
+void test_replace_int_void_p_with_nullptr() {
+ auto replace_int_void_p_with_nullptr = [](void** pp) {
+ assert(*(static_cast<int*>(*pp)) == 90);
+
+ delete static_cast<int*>(*pp);
+ *pp = nullptr;
+ };
+
+ // raw pointer
{
- auto uPtr = std::make_unique<SomeInt>(90);
+ auto rPtr = new int{90};
- replace_SomeInt_p(std::inout_ptr(uPtr));
- assert(uPtr->value == 9084);
+ replace_int_void_p_with_nullptr(std::inout_ptr<int*>(rPtr));
+ assert(rPtr == nullptr);
}
+
+ // std::unique_ptr
{
- auto uPtr = std::make_unique<SomeInt>(90);
+ auto uPtr = std::make_unique<int>(90);
- replace_SomeInt_void_p(std::inout_ptr<SomeInt*>(uPtr));
- assert(uPtr->value == 9084);
+ replace_int_void_p_with_nullptr(std::inout_ptr(uPtr));
+ assert(uPtr == nullptr);
}
}
-void test_custom_ptr() {
- // ConstructiblePtr
- {
- ConstructiblePtr<int> cPtr(new int{90});
+void test_replace_nullptr_with_int_p() {
+ auto replace_nullptr_with_int_p = [](int** pp) {
+ assert(*pp == nullptr);
- replace_int_p(std::inout_ptr(cPtr));
- assert(cPtr == 84);
- }
- // ResettablePtr
+ *pp = new int{84};
+ };
+
+ // raw pointer
{
- ResettablePtr<int> rPtr(new int{90});
+ int* rPtr = nullptr;
- replace_int_p(std::inout_ptr(rPtr));
- assert(rPtr == 84);
+ replace_nullptr_with_int_p(std::inout_ptr<int*>(rPtr));
+ assert(*rPtr == 84);
+
+ delete rPtr;
}
- // NonConstructiblePtr
+
+ // std::unique_ptr
{
- NonConstructiblePtr<int> nPtr;
- nPtr.reset(new int{90});
+ std::unique_ptr<int> uPtr;
- replace_int_p(std::inout_ptr(nPtr));
- assert(nPtr == 84);
+ replace_nullptr_with_int_p(std::inout_ptr(uPtr));
+ assert(*uPtr == 84);
}
}
int main(int, char**) {
- test_raw_ptr();
- test_unique_ptr();
- test_custom_ptr();
+ test_replace_int_p();
+ test_replace_int_p_with_nullptr();
+ test_replace_int_void_p();
+ test_replace_int_void_p_with_nullptr();
+ test_replace_nullptr_with_int_p();
return 0;
}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.general.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.general.cpp
deleted file mode 100644
index a5189717fad62..0000000000000
--- a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.general.cpp
+++ /dev/null
@@ -1,159 +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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-
-// <memory>
-
-// [out.ptr], function template out_ptr
-// template<class Pointer = void, class Smart, class... Args>
-// auto out_ptr(Smart& s, Args&&... args); // since c++23
-
-#include <cassert>
-#include <memory>
-
-#include "../types.h"
-
-// Test helpers.
-
-void get_int_p(int** pp) { *pp = new int{84}; }
-
-void get_int_p_nullptr(int** pp) { *pp = nullptr; }
-
-void get_int_void_p(void** pp) { *(reinterpret_cast<int**>(pp)) = new int{84}; }
-
-void get_int_void_p_nullptr(void** pp) { *pp = nullptr; }
-
-void get_SomeInt_p(SomeInt** pp) { *pp = new SomeInt{84}; }
-
-void get_SomeInt_void_p(void** pp) { *pp = reinterpret_cast<int*>(new int{84}); }
-
-// Test `std::out_ptr()` function.
-
-void test_raw_ptr() {
- {
- auto n{90};
- auto rPtr = &n;
-
- get_int_p(std::inout_ptr<int*>(rPtr));
- assert(*rPtr == 84);
- delete rPtr;
-
- get_int_p_nullptr(std::out_ptr<int*>(rPtr));
- assert(rPtr == nullptr);
-
- get_int_void_p(std::inout_ptr<int*>(rPtr));
- assert(*rPtr == 84);
- delete rPtr;
-
- get_int_void_p_nullptr(std::out_ptr<int*>(rPtr));
- assert(rPtr == nullptr);
- }
- {
- SomeInt si{90};
- auto* rPtr = &si;
-
- get_SomeInt_p(std::out_ptr(rPtr));
- assert(rPtr->value == 84);
- delete rPtr;
- }
- {
- SomeInt si{90};
- auto* rPtr = &si;
-
- get_SomeInt_void_p(std::out_ptr<SomeInt*>(rPtr));
- assert(rPtr->value == 84);
- delete rPtr;
- }
-}
-
-void test_shared_ptr() {
- {
- auto sPtr = std::make_shared<int>(90);
-
- get_int_p(std::out_ptr(sPtr, [](auto* p) { delete p; }));
- assert(*sPtr == 84);
-
- sPtr.reset(new int(90));
-
- get_int_void_p(std::out_ptr(sPtr, [](auto* p) { delete p; }));
- assert(*sPtr == 84);
- }
- {
- auto sPtr = std::make_shared<SomeInt>(90);
-
- get_SomeInt_p(std::out_ptr(sPtr, [](auto* p) { delete p; }));
- assert(sPtr->value == 84);
- }
- {
- auto sPtr = std::make_shared<SomeInt>(90);
-
- get_SomeInt_void_p(std::out_ptr<SomeInt*>(sPtr, [](auto* p) { delete p; }));
- assert(sPtr->value == 84);
- }
-}
-
-void test_unique_ptr() {
- {
- auto uPtr = std::make_unique<int>(90);
-
- get_int_p(std::out_ptr(uPtr));
- assert(*uPtr == 84);
-
- uPtr.reset(new int{90});
-
- get_int_void_p(std::out_ptr(uPtr));
- assert(*uPtr == 84);
- }
- {
- auto uPtr = std::make_unique<SomeInt>(90);
-
- get_SomeInt_p(std::out_ptr(uPtr));
- assert(uPtr->value == 84);
- }
- {
- auto uPtr = std::make_unique<SomeInt>(90);
-
- get_SomeInt_void_p(std::out_ptr<SomeInt*>(uPtr));
- assert(uPtr->value == 84);
- }
-}
-
-void test_custom_ptr() {
- // ConstructiblePtr
- {
- ConstructiblePtr<int> cPtr(new int{90});
-
- get_int_p(std::out_ptr(cPtr));
- assert(cPtr == 84);
- }
- // ResettablePtr
- {
- ResettablePtr<int> rPtr(new int{90});
-
- get_int_p(std::out_ptr(rPtr));
- assert(rPtr == 84);
- }
- // NonConstructiblePtr
- {
- NonConstructiblePtr<int> nPtr;
- nPtr.reset(new int{90});
-
- get_int_p(std::out_ptr(nPtr));
- assert(nPtr == 84);
- }
-}
-
-int main(int, char**) {
- test_raw_ptr();
- test_shared_ptr();
- test_unique_ptr();
- test_custom_ptr();
-
- return 0;
-}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.general.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.general.pass.cpp
new file mode 100644
index 0000000000000..7fc1ed06a4d20
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.general.pass.cpp
@@ -0,0 +1,212 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <memory>
+
+// [out.ptr], function template out_ptr
+// template<class Pointer = void, class Smart, class... Args>
+// auto out_ptr(Smart& s, Args&&... args); // since c++23
+
+#include <cassert>
+#include <memory>
+
+#include "../types.h"
+
+void test_get_int_p() {
+ auto get_int_p = [](int** pp) { *pp = new int{84}; };
+
+ // raw pointer
+ {
+ int* rPtr;
+
+ get_int_p(std::out_ptr<int*>(rPtr));
+ assert(*rPtr == 84);
+
+ delete rPtr;
+ }
+
+ // std::unique_ptr
+ {
+ std::unique_ptr<int> uPtr;
+
+ get_int_p(std::out_ptr(uPtr));
+ assert(*uPtr == 84);
+ }
+
+ // std::shared_ptr
+ {
+ std::shared_ptr<int> sPtr;
+
+ get_int_p(std::out_ptr(sPtr, [](auto* p) {
+ assert(*p == 84);
+
+ delete p;
+ }));
+ assert(*sPtr == 84);
+ }
+
+ // pointer-like ConstructiblePtr
+ {
+ ConstructiblePtr<int> cPtr;
+
+ get_int_p(std::out_ptr(cPtr));
+ assert(cPtr == 84);
+ }
+
+ // pointer-like ResettablePtr
+ {
+ ResettablePtr<int> rPtr{nullptr};
+
+ get_int_p(std::out_ptr(rPtr));
+ assert(rPtr == 84);
+ }
+
+ // NonConstructiblePtr
+ {
+ NonConstructiblePtr<int> nPtr;
+
+ get_int_p(std::out_ptr(nPtr));
+ assert(nPtr == 84);
+ }
+}
+
+void test_get_int_p_nullptr() {
+ auto get_int_p_nullptr = [](int** pp) { *pp = nullptr; };
+ // raw pointer
+ {
+ int* rPtr;
+
+ get_int_p_nullptr(std::out_ptr<int*>(rPtr));
+ assert(rPtr == nullptr);
+
+ delete rPtr;
+ }
+
+ // std::unique_ptr
+ {
+ std::unique_ptr<int> uPtr;
+
+ get_int_p_nullptr(std::out_ptr(uPtr));
+ assert(uPtr == nullptr);
+ }
+
+ // std::shared_ptr
+ {
+ std::shared_ptr<int> sPtr;
+
+ get_int_p_nullptr(std::out_ptr(sPtr, [](auto* p) {
+ assert(p == nullptr);
+
+ delete p;
+ }));
+ assert(sPtr == nullptr);
+ }
+}
+
+void test_get_int_void_p() {
+ auto get_int_void_p = [](void** pp) { *(reinterpret_cast<int**>(pp)) = new int{84}; };
+
+ // raw pointer
+ {
+ int* rPtr;
+
+ get_int_void_p(std::out_ptr(rPtr));
+ assert(*rPtr == 84);
+
+ delete rPtr;
+ }
+
+ // std::unique_ptr
+ {
+ std::unique_ptr<int> uPtr;
+
+ get_int_void_p(std::out_ptr(uPtr));
+ assert(*uPtr == 84);
+ }
+
+ // std::shared_ptr
+ {
+ std::shared_ptr<int> sPtr;
+
+ get_int_void_p(std::out_ptr(sPtr, [](auto* p) {
+ assert(*p == 84);
+
+ delete p;
+ }));
+ assert(*sPtr == 84);
+ }
+
+ // pointer-like ConstructiblePtr
+ {
+ ConstructiblePtr<int> cPtr;
+
+ get_int_void_p(std::out_ptr(cPtr));
+ assert(cPtr == 84);
+ }
+
+ // pointer-like ResettablePtr
+ {
+ ResettablePtr<int> rPtr{nullptr};
+
+ get_int_void_p(std::out_ptr(rPtr));
+ assert(rPtr == 84);
+ }
+
+ // NonConstructiblePtr
+ {
+ NonConstructiblePtr<int> nPtr;
+
+ get_int_void_p(std::out_ptr(nPtr));
+ assert(nPtr == 84);
+ }
+}
+
+void test_get_int_void_p_nullptr() {
+ auto get_int_void_p_nullptr = [](void** pp) { *pp = nullptr; };
+
+ // raw pointer
+ {
+ int* rPtr;
+
+ get_int_void_p_nullptr(std::out_ptr<int*>(rPtr));
+ assert(rPtr == nullptr);
+
+ delete rPtr;
+ }
+
+ // std::unique_ptr
+ {
+ std::unique_ptr<int> uPtr;
+
+ get_int_void_p_nullptr(std::out_ptr(uPtr));
+ assert(uPtr == nullptr);
+ }
+
+ // std::shared_ptr
+ {
+ std::shared_ptr<int> sPtr;
+
+ get_int_void_p_nullptr(std::out_ptr(sPtr, [](auto* p) {
+ assert(p == nullptr);
+
+ delete p;
+ }));
+ assert(sPtr == nullptr);
+ }
+}
+
+int main(int, char**) {
+ test_get_int_p();
+ test_get_int_p_nullptr();
+ test_get_int_void_p();
+ test_get_int_void_p_nullptr();
+
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.verify.cpp
index 3c51583421e76..2de75286307ad 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.verify.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.verify.cpp
@@ -16,6 +16,8 @@
#include <memory>
+#include "../types.h"
+
int main(int, char**) {
// `std::out_ptr<>` requires `std::shared_ptr<>` with a deleter.
{
@@ -27,5 +29,24 @@ int main(int, char**) {
auto outSPtr2 = std::out_ptr<int*>(sPtr);
}
+ // {
+ // DefaultDeleter<int> del;
+ // std::shared_ptr<int> sPtr;
+ // auto outSPtr1 = std::out_ptr(sPtr, del);
+ // auto outSPtr2 = std::out_ptr<int*>(sPtr, del);
+ // }
+
+ // {
+ // std::shared_ptr<int> sPtr;
+ // auto outSPtr1 = std::out_ptr(sPtr, CopyableMovableDeleter<int>{});
+ // auto outSPtr2 = std::out_ptr<int*>(sPtr, CopyableMovableDeleter<int>{});
+ // }
+
+ // {
+ // std::shared_ptr<int> sPtr;
+ // auto outSPtr1 = std::out_ptr(sPtr, NotCopyAbleNotMovableDeleter<int>{});
+ // auto outSPtr2 = std::out_ptr<int*>(sPtr, NotCopyAbleNotMovableDeleter<int>{});
+ // }
+
return 0;
}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/types.h b/libcxx/test/std/utilities/smartptr/adapt/types.h
index 0e2dad400308d..46d4ba379b0f1 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/types.h
+++ b/libcxx/test/std/utilities/smartptr/adapt/types.h
@@ -12,6 +12,29 @@
#include <type_traits>
#include <memory>
+template <typename T>
+class DefaultDeleter {
+ void operator()(T* p) const { delete p; }
+};
+
+template <typename T>
+struct CopyableMovableDeleter {
+ CopyableMovableDeleter() = default;
+ CopyableMovableDeleter(CopyableMovableDeleter const&) = default;
+ CopyableMovableDeleter(CopyableMovableDeleter&&) = default;
+
+ void operator()(T* p) const { delete p; }
+};
+
+template <typename T>
+struct NotCopyAbleNotMovableDeleter {
+ NotCopyAbleNotMovableDeleter() = default;
+ NotCopyAbleNotMovableDeleter(NotCopyAbleNotMovableDeleter const&) = delete; // not copyable
+ NotCopyAbleNotMovableDeleter(NotCopyAbleNotMovableDeleter&&) = delete; // not movable either!
+
+ void operator()(T* p) const { delete p; }
+};
+
struct ResetArg {};
// Custom pointer types.
>From af88c857d8f754c3712e4d32092241755dc5b8d4 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <zingam at outlook.com>
Date: Fri, 15 Dec 2023 18:55:16 +0200
Subject: [PATCH 08/23] Renamed directories
---
.../adapt/{inout.ptr => inout_ptr}/inout_ptr.general.pass.cpp | 0
.../smartptr/adapt/{inout.ptr => inout_ptr}/inout_ptr.verify.cpp | 0
.../adapt/{inout.ptr => inout_ptr}/inout_ptr_t.convert.pass.cpp | 0
.../adapt/{inout.ptr => inout_ptr}/inout_ptr_t.ctor.pass.cpp | 0
.../adapt/{inout.ptr => inout_ptr}/inout_ptr_t.verify.cpp | 0
.../smartptr/adapt/{out.ptr => out_ptr}/out_ptr.general.pass.cpp | 0
.../smartptr/adapt/{out.ptr => out_ptr}/out_ptr.verify.cpp | 0
.../adapt/{out.ptr => out_ptr}/out_ptr_t.convert.pass.cpp | 0
.../smartptr/adapt/{out.ptr => out_ptr}/out_ptr_t.ctor.pass.cpp | 0
.../smartptr/adapt/{out.ptr => out_ptr}/out_ptr_t.verify.cpp | 0
10 files changed, 0 insertions(+), 0 deletions(-)
rename libcxx/test/std/utilities/smartptr/adapt/{inout.ptr => inout_ptr}/inout_ptr.general.pass.cpp (100%)
rename libcxx/test/std/utilities/smartptr/adapt/{inout.ptr => inout_ptr}/inout_ptr.verify.cpp (100%)
rename libcxx/test/std/utilities/smartptr/adapt/{inout.ptr => inout_ptr}/inout_ptr_t.convert.pass.cpp (100%)
rename libcxx/test/std/utilities/smartptr/adapt/{inout.ptr => inout_ptr}/inout_ptr_t.ctor.pass.cpp (100%)
rename libcxx/test/std/utilities/smartptr/adapt/{inout.ptr => inout_ptr}/inout_ptr_t.verify.cpp (100%)
rename libcxx/test/std/utilities/smartptr/adapt/{out.ptr => out_ptr}/out_ptr.general.pass.cpp (100%)
rename libcxx/test/std/utilities/smartptr/adapt/{out.ptr => out_ptr}/out_ptr.verify.cpp (100%)
rename libcxx/test/std/utilities/smartptr/adapt/{out.ptr => out_ptr}/out_ptr_t.convert.pass.cpp (100%)
rename libcxx/test/std/utilities/smartptr/adapt/{out.ptr => out_ptr}/out_ptr_t.ctor.pass.cpp (100%)
rename libcxx/test/std/utilities/smartptr/adapt/{out.ptr => out_ptr}/out_ptr_t.verify.cpp (100%)
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr.general.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr.general.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.verify.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr.verify.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.verify.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr_t.convert.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr_t.convert.pass.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr_t.convert.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr_t.convert.pass.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr_t.ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr_t.ctor.pass.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr_t.ctor.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr_t.ctor.pass.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr_t.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr_t.verify.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/inout.ptr/inout_ptr_t.verify.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr_t.verify.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.general.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.general.pass.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.general.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.general.pass.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr.verify.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr_t.convert.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.convert.pass.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr_t.convert.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.convert.pass.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr_t.ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.ctor.pass.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr_t.ctor.pass.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.ctor.pass.cpp
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr_t.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.verify.cpp
similarity index 100%
rename from libcxx/test/std/utilities/smartptr/adapt/out.ptr/out_ptr_t.verify.cpp
rename to libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.verify.cpp
>From d7c04396da8d0c6b2270643a3a079e5cd95e887a Mon Sep 17 00:00:00 2001
From: Zingam <zingam at outlook.com>
Date: Sat, 16 Dec 2023 21:02:26 +0200
Subject: [PATCH 09/23] Addressed comments: Added `MoveOnlyDeleter` test
---
libcxx/include/__memory/out_ptr.h | 3 --
.../inout_ptr/inout_ptr.general.pass.cpp | 9 +++++
.../adapt/inout_ptr/inout_ptr_t.ctor.pass.cpp | 8 +++++
.../adapt/out_ptr/out_ptr.general.pass.cpp | 9 +++++
.../adapt/out_ptr/out_ptr_t.convert.pass.cpp | 1 -
.../adapt/out_ptr/out_ptr_t.ctor.pass.cpp | 8 +++++
.../test/std/utilities/smartptr/adapt/types.h | 35 +++++++++++--------
7 files changed, 55 insertions(+), 18 deletions(-)
diff --git a/libcxx/include/__memory/out_ptr.h b/libcxx/include/__memory/out_ptr.h
index 618fc372bd965..1938bef8f1c27 100644
--- a/libcxx/include/__memory/out_ptr.h
+++ b/libcxx/include/__memory/out_ptr.h
@@ -27,9 +27,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 23
-template <class _Tp>
-concept __resettable_adapted_ptr = requires(_Tp __ptr) { __ptr().reset(); };
-
template <class _Smart, class _Pointer, class... _Args>
class _LIBCPP_TEMPLATE_VIS out_ptr_t {
static_assert(!__is_specialization_v<_Smart, shared_ptr> || sizeof...(_Args) > 0,
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp
index 4114ab6ee7549..93ee6cf14eea2 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp
@@ -45,6 +45,15 @@ void test_replace_int_p() {
assert(*uPtr == 84);
}
+ {
+ MoveOnlyDeleter<int> del;
+ std::unique_ptr<int, MoveOnlyDeleter<int>> uPtr{new int{90}};
+
+ replace_int_p(std::inout_ptr(uPtr, std::move(del)));
+ assert(*uPtr == 84);
+ assert(uPtr.get_deleter().wasMoveInitilized == true);
+ }
+
// pointer-like ConstructiblePtr
{
ConstructiblePtr<int> cPtr(new int{90});
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr_t.ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr_t.ctor.pass.cpp
index 0a21a41539e43..1def6931441d3 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr_t.ctor.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr_t.ctor.pass.cpp
@@ -19,6 +19,7 @@
#include <memory>
#include "test_convertible.h"
+#include "../types.h"
int main(int, char**) {
{
@@ -29,6 +30,7 @@ int main(int, char**) {
static_assert(
!test_convertible<std::inout_ptr_t<std::unique_ptr<int>, int*>>(), "This constructor must be explicit");
}
+
{
auto deleter = [](auto* p) { delete p; };
std::unique_ptr<int, decltype(deleter)> uPtr;
@@ -39,5 +41,11 @@ int main(int, char**) {
"This constructor must be explicit");
}
+ {
+ std::unique_ptr<int, MoveOnlyDeleter<int>> uPtr;
+
+ std::inout_ptr_t<decltype(uPtr), int*, MoveOnlyDeleter<int>>{uPtr, MoveOnlyDeleter<int>{}};
+ }
+
return 0;
}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.general.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.general.pass.cpp
index 7fc1ed06a4d20..1f06a2206698f 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.general.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.general.pass.cpp
@@ -40,6 +40,15 @@ void test_get_int_p() {
assert(*uPtr == 84);
}
+ {
+ MoveOnlyDeleter<int> del;
+ std::unique_ptr<int, MoveOnlyDeleter<int>> uPtr;
+
+ get_int_p(std::out_ptr(uPtr, std::move(del)));
+ assert(*uPtr == 84);
+ assert(uPtr.get_deleter().wasMoveInitilized == true);
+ }
+
// std::shared_ptr
{
std::shared_ptr<int> sPtr;
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.convert.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.convert.pass.cpp
index 1e19d1ee5b4ec..168d0b99875a4 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.convert.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.convert.pass.cpp
@@ -20,7 +20,6 @@
#include <cassert>
#include <concepts>
#include <memory>
-#include <iostream>
int main(int, char**) {
{
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.ctor.pass.cpp
index 39604247216e8..0ec834cc2f354 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.ctor.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.ctor.pass.cpp
@@ -19,6 +19,7 @@
#include <memory>
#include "test_convertible.h"
+#include "../types.h"
int main(int, char**) {
{
@@ -28,6 +29,7 @@ int main(int, char**) {
static_assert(!test_convertible<std::out_ptr_t<std::unique_ptr<int>, int*>>(), "This constructor must be explicit");
}
+
{
std::unique_ptr<int, std::default_delete<int>> uPtr;
@@ -37,5 +39,11 @@ int main(int, char**) {
"This constructor must be explicit");
}
+ {
+ std::unique_ptr<int, MoveOnlyDeleter<int>> uPtr;
+
+ std::out_ptr_t<decltype(uPtr), int*, MoveOnlyDeleter<int>>{uPtr, MoveOnlyDeleter<int>{}};
+ }
+
return 0;
}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/types.h b/libcxx/test/std/utilities/smartptr/adapt/types.h
index 46d4ba379b0f1..330848803c478 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/types.h
+++ b/libcxx/test/std/utilities/smartptr/adapt/types.h
@@ -12,10 +12,7 @@
#include <type_traits>
#include <memory>
-template <typename T>
-class DefaultDeleter {
- void operator()(T* p) const { delete p; }
-};
+// Custom deleters.
template <typename T>
struct CopyableMovableDeleter {
@@ -26,6 +23,24 @@ struct CopyableMovableDeleter {
void operator()(T* p) const { delete p; }
};
+template <typename T>
+struct DefaultDeleter {
+ void operator()(T* p) const { delete p; }
+};
+
+template <typename T>
+struct MoveOnlyDeleter {
+ MoveOnlyDeleter() = default;
+ MoveOnlyDeleter(const MoveOnlyDeleter&) = delete;
+ MoveOnlyDeleter& operator=(const MoveOnlyDeleter&) = delete;
+ MoveOnlyDeleter(MoveOnlyDeleter&&) : wasMoveInitilized{true} {}
+ MoveOnlyDeleter& operator=(MoveOnlyDeleter&&) = default;
+
+ void operator()(T* p) const { delete p; }
+
+ bool wasMoveInitilized = false;
+};
+
template <typename T>
struct NotCopyAbleNotMovableDeleter {
NotCopyAbleNotMovableDeleter() = default;
@@ -35,8 +50,6 @@ struct NotCopyAbleNotMovableDeleter {
void operator()(T* p) const { delete p; }
};
-struct ResetArg {};
-
// Custom pointer types.
template <typename _Tp>
@@ -57,6 +70,8 @@ struct ConstructiblePtr {
static_assert(std::is_same_v<std::__pointer_of_t< ConstructiblePtr<int>>, int* >);
static_assert(std::is_constructible_v< ConstructiblePtr<int>, int* >);
+struct ResetArg {};
+
template <typename _Tp>
struct ResettablePtr {
using element_type = _Tp;
@@ -89,12 +104,4 @@ struct NonConstructiblePtr : public ResettablePtr<_Tp> {
static_assert(std::is_same_v<std::__pointer_of_t< NonConstructiblePtr<int>>, int* >);
static_assert(!std::is_constructible_v< NonConstructiblePtr<int>, int* >);
-// Custom types.
-
-struct SomeInt {
- int value;
-
- constexpr explicit SomeInt(int val = 0) : value{val} {}
-};
-
#endif // TEST_LIBCXX_UTILITIES_SMARTPTR_ADAPT_TYPES_H
>From 54c2a41eabdbc14462da5025962f5de973375aa8 Mon Sep 17 00:00:00 2001
From: Zingam <zingam at outlook.com>
Date: Sat, 16 Dec 2023 23:38:47 +0200
Subject: [PATCH 10/23] Tweaked convert.pass tests
---
.../adapt/inout_ptr/inout_ptr_t.convert.pass.cpp | 14 ++++++++++++++
.../adapt/out_ptr/out_ptr_t.convert.pass.cpp | 4 ++++
2 files changed, 18 insertions(+)
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr_t.convert.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr_t.convert.pass.cpp
index cee19c11c78c3..230402af07cfe 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr_t.convert.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr_t.convert.pass.cpp
@@ -22,6 +22,7 @@
#include <memory>
int main(int, char**) {
+ // operator Pointer*()
{
std::unique_ptr<int> uPtr = std::make_unique<int>(84);
@@ -32,6 +33,19 @@ int main(int, char**) {
assert(**pPtr == 84);
}
+
+ {
+ std::unique_ptr<int, std::default_delete<int>> uPtr = std::make_unique<int>(84);
+
+ const std::inout_ptr_t<decltype(uPtr), int*, std::default_delete<int>> ioPtr{uPtr, std::default_delete<int>{}};
+
+ static_assert(noexcept(ioPtr.operator int**()));
+ std::same_as<int**> decltype(auto) pPtr = ioPtr.operator int**();
+
+ assert(**pPtr == 84);
+ }
+
+ // operator void**()
{
std::unique_ptr<int> uPtr = std::make_unique<int>(84);
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.convert.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.convert.pass.cpp
index 168d0b99875a4..dff9ed93c3011 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.convert.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.convert.pass.cpp
@@ -22,6 +22,7 @@
#include <memory>
int main(int, char**) {
+ // operator Pointer*()
{
std::unique_ptr<int> uPtr;
@@ -32,6 +33,7 @@ int main(int, char**) {
assert(*pPtr == nullptr);
}
+
{
std::unique_ptr<int, std::default_delete<int>> uPtr;
@@ -42,6 +44,8 @@ int main(int, char**) {
assert(*pPtr == nullptr);
}
+
+ // operator void**()
{
std::unique_ptr<int> uPtr;
>From 1a4e2e86bd63f17038d4aa690850fc85fab631aa Mon Sep 17 00:00:00 2001
From: Zingam <zingam at outlook.com>
Date: Sun, 17 Dec 2023 00:08:41 +0200
Subject: [PATCH 11/23] Try to fix CI
---
.../utilities/smartptr/adapt/out_ptr/out_ptr_t.convert.pass.cpp | 2 +-
.../utilities/smartptr/adapt/out_ptr/out_ptr_t.ctor.pass.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.convert.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.convert.pass.cpp
index dff9ed93c3011..828a5d0ba31ea 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.convert.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.convert.pass.cpp
@@ -22,7 +22,7 @@
#include <memory>
int main(int, char**) {
- // operator Pointer*()
+ // operator Pointer*()
{
std::unique_ptr<int> uPtr;
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.ctor.pass.cpp
index 0ec834cc2f354..474ab3c162e90 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.ctor.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr_t.ctor.pass.cpp
@@ -29,7 +29,7 @@ int main(int, char**) {
static_assert(!test_convertible<std::out_ptr_t<std::unique_ptr<int>, int*>>(), "This constructor must be explicit");
}
-
+
{
std::unique_ptr<int, std::default_delete<int>> uPtr;
>From 378b37430d414db2506f8abad204187db4a33dde Mon Sep 17 00:00:00 2001
From: Zingam <zingam at outlook.com>
Date: Sun, 17 Dec 2023 01:05:40 +0200
Subject: [PATCH 12/23] Try to fix CI
---
.../smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp | 1 +
.../utilities/smartptr/adapt/out_ptr/out_ptr.general.pass.cpp | 1 +
2 files changed, 2 insertions(+)
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp
index 93ee6cf14eea2..3a3163d0ee40c 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp
@@ -16,6 +16,7 @@
#include <cassert>
#include <memory>
+#include <utility>
#include "../types.h"
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.general.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.general.pass.cpp
index 1f06a2206698f..6d2065dcc2b36 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.general.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.general.pass.cpp
@@ -16,6 +16,7 @@
#include <cassert>
#include <memory>
+#include <utility>
#include "../types.h"
>From 1515a3dabdc05cd0574e16d732a406f9a53775d1 Mon Sep 17 00:00:00 2001
From: Zingam <zingam at outlook.com>
Date: Sun, 17 Dec 2023 15:42:36 +0200
Subject: [PATCH 13/23] Refactored if constexpr else case
---
libcxx/include/__memory/inout_ptr.h | 7 +++----
libcxx/include/__memory/out_ptr.h | 8 ++------
.../smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp | 1 +
3 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/libcxx/include/__memory/inout_ptr.h b/libcxx/include/__memory/inout_ptr.h
index 18157b271cd75..4106da7508101 100644
--- a/libcxx/include/__memory/inout_ptr.h
+++ b/libcxx/include/__memory/inout_ptr.h
@@ -51,6 +51,7 @@ class _LIBCPP_TEMPLATE_VIS inout_ptr_t {
_LIBCPP_HIDE_FROM_ABI inout_ptr_t(const inout_ptr_t&) = delete;
_LIBCPP_HIDE_FROM_ABI ~inout_ptr_t() {
+ // LWG-3897 inout_ptr will not update raw pointer to null
if constexpr (!is_pointer_v<_Smart>) {
if (!__p_) {
return;
@@ -64,12 +65,10 @@ class _LIBCPP_TEMPLATE_VIS inout_ptr_t {
} else if constexpr (__resettable_smart_pointer_with_args<_Smart, _Pointer, _Args...>) {
std::apply([&](auto&&... __args) { __s_.reset(static_cast<_SP>(__p_), std::forward<_Args>(__args)...); },
std::move(__a_));
- } else if constexpr (is_constructible_v<_Smart, _SP, _Args...>) {
+ } else {
+ static_assert(is_constructible_v<_Smart, _SP, _Args...>);
std::apply([&](auto&&... __args) { __s_ = _Smart(static_cast<_SP>(__p_), std::forward<_Args>(__args)...); },
std::move(__a_));
- } else {
- static_assert(is_pointer_v<_Smart> || __resettable_smart_pointer_with_args<_Smart, _Pointer, _Args...> ||
- is_constructible_v<_Smart, _SP, _Args...>);
}
}
diff --git a/libcxx/include/__memory/out_ptr.h b/libcxx/include/__memory/out_ptr.h
index 1938bef8f1c27..9abbd81b01a92 100644
--- a/libcxx/include/__memory/out_ptr.h
+++ b/libcxx/include/__memory/out_ptr.h
@@ -56,14 +56,10 @@ class _LIBCPP_TEMPLATE_VIS out_ptr_t {
if constexpr (__resettable_smart_pointer_with_args<_Smart, _Pointer, _Args...>) {
std::apply([&](auto&&... __args) { __s_.reset(static_cast<_SP>(__p_), std::forward<_Args>(__args)...); },
std::move(__a_));
- } else if constexpr (is_constructible_v<_Smart, _SP, _Args...>) {
+ } else {
+ static_assert(is_constructible_v<_Smart, _SP, _Args...>);
std::apply([&](auto&&... __args) { __s_ = _Smart(static_cast<_SP>(__p_), std::forward<_Args>(__args)...); },
std::move(__a_));
- } else {
- // static_assert(__resettable_smart_pointer_with_args<_Smart, _Pointer, _Args...>);
- // static_assert(is_constructible_v<_Smart, _SP, _Args...>);
- static_assert(__resettable_smart_pointer_with_args<_Smart, _Pointer, _Args...> ||
- is_constructible_v<_Smart, _SP, _Args...>);
}
}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp
index 3a3163d0ee40c..312df25c40c0f 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.general.pass.cpp
@@ -91,6 +91,7 @@ void test_replace_int_p_with_nullptr() {
// raw pointer
{
+ // LWG-3897 inout_ptr will not update raw pointer to null
auto rPtr = new int{90};
replace_int_p_with_nullptr(std::inout_ptr<int*>(rPtr));
>From da7d5e53aead3e82e80db2c015779f329173443e Mon Sep 17 00:00:00 2001
From: Zingam <zingam at outlook.com>
Date: Sun, 17 Dec 2023 16:22:13 +0200
Subject: [PATCH 14/23] Refactored verify.cpp
---
.../adapt/inout_ptr/inout_ptr.verify.cpp | 31 +++++++++--
.../smartptr/adapt/out_ptr/out_ptr.verify.cpp | 53 +++++++++++--------
2 files changed, 60 insertions(+), 24 deletions(-)
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.verify.cpp
index eb296767085b7..8f25f4acf7d87 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.verify.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.verify.cpp
@@ -15,17 +15,42 @@
// auto inout_ptr(Smart& s, Args&&... args); // since c++23
#include <memory>
+#include <tuple>
+
+#include "../types.h"
int main(int, char**) {
// `std::inout_ptr<>` does not support `std::shared_ptr<>`.
{
std::shared_ptr<int> sPtr;
- // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed due to requirement '!__is_specialization_v<std::shared_ptr<int>, std::shared_ptr>'{{.*}}std::shared_ptr<> is not supported}}
- auto inoutUPtr1 = std::inout_ptr(sPtr);
+ // expected-error-re@*:* {{static assertion failed due to requirement '!__is_specialization_v<std::shared_ptr<int>, std::shared_ptr>'{{.*}}std::shared_ptr<> is not supported}}
+ std::ignore = std::inout_ptr(sPtr);
// expected-error@*:* {{no matching conversion for functional-style cast from 'std::shared_ptr<int>' to 'std::inout_ptr_t<shared_ptr<int>, _Ptr>' (aka 'inout_ptr_t<std::shared_ptr<int>, int *>'}}
- auto inoutUPtr2 = std::inout_ptr<int*>(sPtr);
+ std::ignore = std::inout_ptr<int*>(sPtr);
+ }
+
+#if 0
+
+ {
+ // CopyableMovableDeleter<int> del;
+ // std::unique_ptr<int> uPtr;
+
+ // -expected-error@*:* {{static assertion failed due to requirement 'is_constructible_v<std::unique_ptr<int, std::default_delete<int>>, int *, CopyableMovableDeleter<int> &>'}}
+ // -expected-error@*:* {{no matching constructor for initialization of 'std::unique_ptr<int>'}}
+ // std::ignore = std::inout_ptr(uPtr, del);
+ // std::ignore = std::inout_ptr<int*>(uPtr, del);
+ }
+
+ {
+ NotCopyAbleNotMovableDeleter<int> del;
+ std::unique_ptr<int> uPtr;
+
+ // e-xpected-error@*:* {{static assertion failed due to requirement 'is_constructible_v<std::unique_ptr<int, std::default_delete<int>>, int *, CopyableMovableDeleter<int> &>'}}
+ std::ignore = std::inout_ptr(uPtr, del);
+ std::ignore = std::inout_ptr<int*>(uPtr, del);
}
+#endif
return 0;
}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp
index 2de75286307ad..cf96a5c4aac44 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp
@@ -15,6 +15,7 @@
// auto out_ptr(Smart& s, Args&&... args); // since c++23
#include <memory>
+#include <tuple>
#include "../types.h"
@@ -23,30 +24,40 @@ int main(int, char**) {
{
std::shared_ptr<int> sPtr;
- // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed due to requirement '!__is_specialization_v<std::shared_ptr<int>, std::shared_ptr> || sizeof...(_Args) > 0'{{.*}}Specialization of std::shared_ptr<> requires a deleter.}}
- auto outSPtr1 = std::out_ptr(sPtr);
+ // expected-error-re@*:* {{static assertion failed due to requirement '!__is_specialization_v<std::shared_ptr<int>, std::shared_ptr> || sizeof...(_Args) > 0'{{.*}}Specialization of std::shared_ptr<> requires a deleter.}}
+ std::ignore = std::out_ptr(sPtr);
// expected-error@*:* {{no matching conversion for functional-style cast from 'std::shared_ptr<int>' to 'std::out_ptr_t<shared_ptr<int>, _Ptr>' (aka 'out_ptr_t<std::shared_ptr<int>, int *>')}}
- auto outSPtr2 = std::out_ptr<int*>(sPtr);
+ std::ignore = std::out_ptr<int*>(sPtr);
}
- // {
- // DefaultDeleter<int> del;
- // std::shared_ptr<int> sPtr;
- // auto outSPtr1 = std::out_ptr(sPtr, del);
- // auto outSPtr2 = std::out_ptr<int*>(sPtr, del);
- // }
-
- // {
- // std::shared_ptr<int> sPtr;
- // auto outSPtr1 = std::out_ptr(sPtr, CopyableMovableDeleter<int>{});
- // auto outSPtr2 = std::out_ptr<int*>(sPtr, CopyableMovableDeleter<int>{});
- // }
-
- // {
- // std::shared_ptr<int> sPtr;
- // auto outSPtr1 = std::out_ptr(sPtr, NotCopyAbleNotMovableDeleter<int>{});
- // auto outSPtr2 = std::out_ptr<int*>(sPtr, NotCopyAbleNotMovableDeleter<int>{});
- // }
+#if 0
+
+ {
+ DefaultDeleter<int> del;
+ std::unique_ptr<int> uPtr;
+
+ std::ignore = std::out_ptr(uPtr, del);
+ std::ignore = std::out_ptr<int*>(uPtr, del);
+ }
+
+ {
+ CopyableMovableDeleter<int> del;
+ std::shared_ptr<int> uPtr;
+
+ // expected-error@*:* {{static assertion failed due to requirement 'is_constructible_v<std::unique_ptr<int, std::default_delete<int>>, int *, CopyableMovableDeleter<int> &>'}}
+ std::ignore = std::out_ptr(uPtr, del);
+ // expected-error@*:* {{static assertion failed due to requirement 'is_constructible_v<std::unique_ptr<int, std::default_delete<int>>, int *, CopyableMovableDeleter<int> &>'}}
+ std::ignore = std::out_ptr<int*>(uPtr, del);
+ }
+
+ {
+ NotCopyAbleNotMovableDeleter<int> del;
+ std::shared_ptr<int> uPtr;
+
+ std::ignore = std::out_ptr(uPtr, del);
+ std::ignore = std::out_ptr<int*>(uPtr, del);
+ }
+#endif
return 0;
}
>From df87f89e3ec061f01681e640ed4373a67008ab2a Mon Sep 17 00:00:00 2001
From: Zingam <zingam at outlook.com>
Date: Sun, 17 Dec 2023 18:19:13 +0200
Subject: [PATCH 15/23] WIP
---
.../adapt/inout_ptr/inout_ptr.verify.cpp | 22 +++++++++----------
.../smartptr/adapt/out_ptr/out_ptr.verify.cpp | 9 ++++----
.../test/std/utilities/smartptr/adapt/types.h | 8 ++++---
3 files changed, 19 insertions(+), 20 deletions(-)
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.verify.cpp
index 8f25f4acf7d87..a2d1e363b16f5 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.verify.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.verify.cpp
@@ -30,26 +30,24 @@ int main(int, char**) {
std::ignore = std::inout_ptr<int*>(sPtr);
}
-#if 0
-
{
- // CopyableMovableDeleter<int> del;
- // std::unique_ptr<int> uPtr;
+ CopyableMovableDeleter<int> del;
+ std::unique_ptr<int, CopyableMovableDeleter<int>> uPtr;
- // -expected-error@*:* {{static assertion failed due to requirement 'is_constructible_v<std::unique_ptr<int, std::default_delete<int>>, int *, CopyableMovableDeleter<int> &>'}}
- // -expected-error@*:* {{no matching constructor for initialization of 'std::unique_ptr<int>'}}
- // std::ignore = std::inout_ptr(uPtr, del);
- // std::ignore = std::inout_ptr<int*>(uPtr, del);
+ std::ignore = std::inout_ptr(uPtr, del);
+ std::ignore = std::inout_ptr<int*>(uPtr, del);
}
{
NotCopyAbleNotMovableDeleter<int> del;
- std::unique_ptr<int> uPtr;
+ std::unique_ptr<int, NotCopyAbleNotMovableDeleter<int>> uPtr;
- // e-xpected-error@*:* {{static assertion failed due to requirement 'is_constructible_v<std::unique_ptr<int, std::default_delete<int>>, int *, CopyableMovableDeleter<int> &>'}}
- std::ignore = std::inout_ptr(uPtr, del);
- std::ignore = std::inout_ptr<int*>(uPtr, del);
+ // -expected-error@*:* {{static assertion failed due to requirement 'is_constructible_v<std::unique_ptr<int, NotCopyAbleNotMovableDeleter<int>>, int *, NotCopyAbleNotMovableDeleter<int> &>'}}
+ // -expected-error@*:* {{object of type 'NotCopyAbleNotMovableDeleter<int>' cannot be assigned because its copy assignment operator is implicitly deleted}}
+ std::ignore = std::inout_ptr(uPtr, std::move(del));
+ // std::ignore = std::inout_ptr<int*>(uPtr, del);
}
+#if 0
#endif
return 0;
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp
index cf96a5c4aac44..345b09bc6a9bf 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp
@@ -30,11 +30,9 @@ int main(int, char**) {
std::ignore = std::out_ptr<int*>(sPtr);
}
-#if 0
-
{
DefaultDeleter<int> del;
- std::unique_ptr<int> uPtr;
+ std::unique_ptr<int, DefaultDeleter<int>> uPtr;
std::ignore = std::out_ptr(uPtr, del);
std::ignore = std::out_ptr<int*>(uPtr, del);
@@ -42,7 +40,7 @@ int main(int, char**) {
{
CopyableMovableDeleter<int> del;
- std::shared_ptr<int> uPtr;
+ std::unique_ptr<int, CopyableMovableDeleter<int>> uPtr;
// expected-error@*:* {{static assertion failed due to requirement 'is_constructible_v<std::unique_ptr<int, std::default_delete<int>>, int *, CopyableMovableDeleter<int> &>'}}
std::ignore = std::out_ptr(uPtr, del);
@@ -50,9 +48,10 @@ int main(int, char**) {
std::ignore = std::out_ptr<int*>(uPtr, del);
}
+#if 0
{
NotCopyAbleNotMovableDeleter<int> del;
- std::shared_ptr<int> uPtr;
+ std::unique_ptr<int, NotCopyAbleNotMovableDeleter<int>> uPtr;
std::ignore = std::out_ptr(uPtr, del);
std::ignore = std::out_ptr<int*>(uPtr, del);
diff --git a/libcxx/test/std/utilities/smartptr/adapt/types.h b/libcxx/test/std/utilities/smartptr/adapt/types.h
index 330848803c478..425113a2a44cb 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/types.h
+++ b/libcxx/test/std/utilities/smartptr/adapt/types.h
@@ -16,9 +16,11 @@
template <typename T>
struct CopyableMovableDeleter {
- CopyableMovableDeleter() = default;
- CopyableMovableDeleter(CopyableMovableDeleter const&) = default;
- CopyableMovableDeleter(CopyableMovableDeleter&&) = default;
+ CopyableMovableDeleter() = default;
+ CopyableMovableDeleter(CopyableMovableDeleter const&) = default;
+ CopyableMovableDeleter& operator=(CopyableMovableDeleter const&) = default;
+ CopyableMovableDeleter(CopyableMovableDeleter&&) = default;
+ CopyableMovableDeleter& operator=(CopyableMovableDeleter&&) = default;
void operator()(T* p) const { delete p; }
};
>From 49fa86fa78d77eb74d4fe12b7ec53620b2bba37e Mon Sep 17 00:00:00 2001
From: Zingam <zingam at outlook.com>
Date: Sun, 17 Dec 2023 20:35:38 +0200
Subject: [PATCH 16/23] Cleanup
---
.../adapt/inout_ptr/inout_ptr.verify.cpp | 20 ---------------
.../smartptr/adapt/out_ptr/out_ptr.verify.cpp | 20 ---------------
.../test/std/utilities/smartptr/adapt/types.h | 25 -------------------
3 files changed, 65 deletions(-)
diff --git a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.verify.cpp
index a2d1e363b16f5..a5dabb92ab683 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.verify.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.verify.cpp
@@ -30,25 +30,5 @@ int main(int, char**) {
std::ignore = std::inout_ptr<int*>(sPtr);
}
- {
- CopyableMovableDeleter<int> del;
- std::unique_ptr<int, CopyableMovableDeleter<int>> uPtr;
-
- std::ignore = std::inout_ptr(uPtr, del);
- std::ignore = std::inout_ptr<int*>(uPtr, del);
- }
-
- {
- NotCopyAbleNotMovableDeleter<int> del;
- std::unique_ptr<int, NotCopyAbleNotMovableDeleter<int>> uPtr;
-
- // -expected-error@*:* {{static assertion failed due to requirement 'is_constructible_v<std::unique_ptr<int, NotCopyAbleNotMovableDeleter<int>>, int *, NotCopyAbleNotMovableDeleter<int> &>'}}
- // -expected-error@*:* {{object of type 'NotCopyAbleNotMovableDeleter<int>' cannot be assigned because its copy assignment operator is implicitly deleted}}
- std::ignore = std::inout_ptr(uPtr, std::move(del));
- // std::ignore = std::inout_ptr<int*>(uPtr, del);
- }
-#if 0
-#endif
-
return 0;
}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp
index 345b09bc6a9bf..5c48197ff1630 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp
@@ -38,25 +38,5 @@ int main(int, char**) {
std::ignore = std::out_ptr<int*>(uPtr, del);
}
- {
- CopyableMovableDeleter<int> del;
- std::unique_ptr<int, CopyableMovableDeleter<int>> uPtr;
-
- // expected-error@*:* {{static assertion failed due to requirement 'is_constructible_v<std::unique_ptr<int, std::default_delete<int>>, int *, CopyableMovableDeleter<int> &>'}}
- std::ignore = std::out_ptr(uPtr, del);
- // expected-error@*:* {{static assertion failed due to requirement 'is_constructible_v<std::unique_ptr<int, std::default_delete<int>>, int *, CopyableMovableDeleter<int> &>'}}
- std::ignore = std::out_ptr<int*>(uPtr, del);
- }
-
-#if 0
- {
- NotCopyAbleNotMovableDeleter<int> del;
- std::unique_ptr<int, NotCopyAbleNotMovableDeleter<int>> uPtr;
-
- std::ignore = std::out_ptr(uPtr, del);
- std::ignore = std::out_ptr<int*>(uPtr, del);
- }
-#endif
-
return 0;
}
diff --git a/libcxx/test/std/utilities/smartptr/adapt/types.h b/libcxx/test/std/utilities/smartptr/adapt/types.h
index 425113a2a44cb..3d8513084bd90 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/types.h
+++ b/libcxx/test/std/utilities/smartptr/adapt/types.h
@@ -14,22 +14,6 @@
// Custom deleters.
-template <typename T>
-struct CopyableMovableDeleter {
- CopyableMovableDeleter() = default;
- CopyableMovableDeleter(CopyableMovableDeleter const&) = default;
- CopyableMovableDeleter& operator=(CopyableMovableDeleter const&) = default;
- CopyableMovableDeleter(CopyableMovableDeleter&&) = default;
- CopyableMovableDeleter& operator=(CopyableMovableDeleter&&) = default;
-
- void operator()(T* p) const { delete p; }
-};
-
-template <typename T>
-struct DefaultDeleter {
- void operator()(T* p) const { delete p; }
-};
-
template <typename T>
struct MoveOnlyDeleter {
MoveOnlyDeleter() = default;
@@ -43,15 +27,6 @@ struct MoveOnlyDeleter {
bool wasMoveInitilized = false;
};
-template <typename T>
-struct NotCopyAbleNotMovableDeleter {
- NotCopyAbleNotMovableDeleter() = default;
- NotCopyAbleNotMovableDeleter(NotCopyAbleNotMovableDeleter const&) = delete; // not copyable
- NotCopyAbleNotMovableDeleter(NotCopyAbleNotMovableDeleter&&) = delete; // not movable either!
-
- void operator()(T* p) const { delete p; }
-};
-
// Custom pointer types.
template <typename _Tp>
>From 73c36a15b97f77a552874f2096fa98eb35d534a1 Mon Sep 17 00:00:00 2001
From: Zingam <zingam at outlook.com>
Date: Wed, 20 Dec 2023 08:33:36 +0200
Subject: [PATCH 17/23] Fixed test
---
.../utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp | 8 --------
1 file changed, 8 deletions(-)
diff --git a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp
index 5c48197ff1630..5796a55561ef7 100644
--- a/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp
+++ b/libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp
@@ -30,13 +30,5 @@ int main(int, char**) {
std::ignore = std::out_ptr<int*>(sPtr);
}
- {
- DefaultDeleter<int> del;
- std::unique_ptr<int, DefaultDeleter<int>> uPtr;
-
- std::ignore = std::out_ptr(uPtr, del);
- std::ignore = std::out_ptr<int*>(uPtr, del);
- }
-
return 0;
}
>From ae04dfbdb5f2bd31753885ada74306ddcfb22361 Mon Sep 17 00:00:00 2001
From: Zingam <zingam at outlook.com>
Date: Mon, 22 Jan 2024 13:04:21 +0200
Subject: [PATCH 18/23] Run generator script
---
libcxx/include/libcxx.imp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libcxx/include/libcxx.imp b/libcxx/include/libcxx.imp
index 8616f9639f4d9..d1f0e7b712c8d 100644
--- a/libcxx/include/libcxx.imp
+++ b/libcxx/include/libcxx.imp
@@ -523,6 +523,8 @@
{ include: [ "<__memory/concepts.h>", "private", "<memory>", "public" ] },
{ include: [ "<__memory/construct_at.h>", "private", "<memory>", "public" ] },
{ include: [ "<__memory/destruct_n.h>", "private", "<memory>", "public" ] },
+ { include: [ "<__memory/inout_ptr.h>", "private", "<memory>", "public" ] },
+ { include: [ "<__memory/out_ptr.h>", "private", "<memory>", "public" ] },
{ include: [ "<__memory/pointer_traits.h>", "private", "<memory>", "public" ] },
{ include: [ "<__memory/ranges_construct_at.h>", "private", "<memory>", "public" ] },
{ include: [ "<__memory/ranges_uninitialized_algorithms.h>", "private", "<memory>", "public" ] },
>From c0541c6e63f2688b3276ddea9689d84ffb1c7da4 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 29 Jan 2024 23:47:31 +0200
Subject: [PATCH 19/23] Updated release notes
---
libcxx/docs/ReleaseNotes/19.rst | 1 +
libcxx/docs/Status/Cxx23Issues.csv | 2 +-
libcxx/docs/Status/Cxx23Papers.csv | 2 +-
libcxx/docs/Status/Cxx2cIssues.csv | 2 +-
4 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/libcxx/docs/ReleaseNotes/19.rst b/libcxx/docs/ReleaseNotes/19.rst
index 17a0415a8ad43..84a4e3911fb49 100644
--- a/libcxx/docs/ReleaseNotes/19.rst
+++ b/libcxx/docs/ReleaseNotes/19.rst
@@ -38,6 +38,7 @@ What's New in Libc++ 19.0.0?
Implemented Papers
------------------
- P2637R3 - Member ``visit``
+- P1132R8 - ``out_ptr`` - a scalable output pointer abstraction
Improvements and New Features
diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv
index 2a18106b7832e..511c36c7a360f 100644
--- a/libcxx/docs/Status/Cxx23Issues.csv
+++ b/libcxx/docs/Status/Cxx23Issues.csv
@@ -192,7 +192,7 @@
"`3515 <https://wg21.link/LWG3515>`__","§[stacktrace.basic.nonmem]: ``operator<<`` should be less templatized", "November 2022","","",""
"`3545 <https://wg21.link/LWG3545>`__","``std::pointer_traits`` should be SFINAE-friendly", "November 2022","|Complete|","18.0",""
"`3569 <https://wg21.link/LWG3569>`__","``join_view`` fails to support ranges of ranges with non-default_initializable iterators", "November 2022","","","|ranges|"
-"`3594 <https://wg21.link/LWG3594>`__","``inout_ptr`` — inconsistent ``release()`` in destructor", "November 2022","|Complete|","18.0",""
+"`3594 <https://wg21.link/LWG3594>`__","``inout_ptr`` — inconsistent ``release()`` in destructor", "November 2022","|Complete|","19.0",""
"`3597 <https://wg21.link/LWG3597>`__","Unsigned integer types don't model advanceable", "November 2022","","","|ranges|"
"`3600 <https://wg21.link/LWG3600>`__","Making ``istream_iterator`` copy constructor trivial is an ABI break", "November 2022","","",""
"`3629 <https://wg21.link/LWG3629>`__","``make_error_code`` and ``make_error_condition`` are customization points","November 2022","|Complete|","16.0",""
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index f0fba1c3f8c96..9d83d7e089a68 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -13,7 +13,7 @@
"","","","","","",""
"`P0401R6 <https://wg21.link/P0401R6>`__","LWG","Providing size feedback in the Allocator interface","June 2021","|Complete|","15.0"
"`P0448R4 <https://wg21.link/P0448R4>`__","LWG","A strstream replacement using span<charT> as buffer","June 2021","",""
-"`P1132R8 <https://wg21.link/P1132R8>`__","LWG","out_ptr - a scalable output pointer abstraction","June 2021","|Complete|","18.0"
+"`P1132R8 <https://wg21.link/P1132R8>`__","LWG","out_ptr - a scalable output pointer abstraction","June 2021","|Complete|","19.0"
"`P1328R1 <https://wg21.link/P1328R1>`__","LWG","Making std::type_info::operator== constexpr","June 2021","|Complete|","17.0"
"`P1425R4 <https://wg21.link/P1425R4>`__","LWG","Iterators pair constructors for stack and queue","June 2021","|Complete|","14.0","|ranges|"
"`P1518R2 <https://wg21.link/P1518R2>`__","LWG","Stop overconstraining allocators in container deduction guides","June 2021","|Complete|","13.0"
diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index 326ff29920d53..36a19e18d711a 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -24,7 +24,7 @@
"`3749 <https://wg21.link/LWG3749>`__","``common_iterator`` should handle integer-class difference types","Kona November 2023","","",""
"`3809 <https://wg21.link/LWG3809>`__","Is ``std::subtract_with_carry_engine<uint16_t>`` supposed to work","Kona November 2023","","",""
"`3892 <https://wg21.link/LWG3892>`__","Incorrect formatting of nested ranges and tuples","Kona November 2023","|Complete|","17.0","|format|"
-"`3897 <https://wg21.link/LWG3897>`__","``inout_ptr`` will not update raw pointer to 0","Kona November 2023","|Complete|","18.0",""
+"`3897 <https://wg21.link/LWG3897>`__","``inout_ptr`` will not update raw pointer to 0","Kona November 2023","|Complete|","19.0",""
"`3946 <https://wg21.link/LWG3946>`__","The definition of ``const_iterator_t`` should be reworked","Kona November 2023","","",""
"`3947 <https://wg21.link/LWG3947>`__","Unexpected constraints on ``adjacent_transform_view::base()``","Kona November 2023","","","|ranges|"
"`3948 <https://wg21.link/LWG3948>`__","``possibly-const-range and as-const-pointer`` should be ``noexcept``","Kona November 2023","","","|ranges|"
>From 2902fe50c00f38a73e64b0381c01702bb012dadd Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 30 Jan 2024 00:13:03 +0200
Subject: [PATCH 20/23] Try to fix CI: added `#include <__utility/move.h>`
---
libcxx/include/__memory/inout_ptr.h | 1 +
libcxx/include/__memory/out_ptr.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/libcxx/include/__memory/inout_ptr.h b/libcxx/include/__memory/inout_ptr.h
index 4106da7508101..ddaa2e506fc7f 100644
--- a/libcxx/include/__memory/inout_ptr.h
+++ b/libcxx/include/__memory/inout_ptr.h
@@ -18,6 +18,7 @@
#include <__type_traits/is_same.h>
#include <__type_traits/is_specialization.h>
#include <__type_traits/is_void.h>
+#include <__utility/move.h>
#include <tuple>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/__memory/out_ptr.h b/libcxx/include/__memory/out_ptr.h
index 9abbd81b01a92..7ad7ac6d0876b 100644
--- a/libcxx/include/__memory/out_ptr.h
+++ b/libcxx/include/__memory/out_ptr.h
@@ -17,6 +17,7 @@
#include <__memory/unique_ptr.h>
#include <__type_traits/is_specialization.h>
#include <__type_traits/is_void.h>
+#include <__utility/move.h>
#include <tuple>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
>From 398914a59a352360b582e1dd1dc13e2098bbb888 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 30 Jan 2024 00:14:58 +0200
Subject: [PATCH 21/23] Try to fix CI: added `#include <__utility/forward.h>`
---
libcxx/include/__memory/inout_ptr.h | 1 +
libcxx/include/__memory/out_ptr.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/libcxx/include/__memory/inout_ptr.h b/libcxx/include/__memory/inout_ptr.h
index ddaa2e506fc7f..620685ca0428e 100644
--- a/libcxx/include/__memory/inout_ptr.h
+++ b/libcxx/include/__memory/inout_ptr.h
@@ -18,6 +18,7 @@
#include <__type_traits/is_same.h>
#include <__type_traits/is_specialization.h>
#include <__type_traits/is_void.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
#include <tuple>
diff --git a/libcxx/include/__memory/out_ptr.h b/libcxx/include/__memory/out_ptr.h
index 7ad7ac6d0876b..256e6334d51f3 100644
--- a/libcxx/include/__memory/out_ptr.h
+++ b/libcxx/include/__memory/out_ptr.h
@@ -17,6 +17,7 @@
#include <__memory/unique_ptr.h>
#include <__type_traits/is_specialization.h>
#include <__type_traits/is_void.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
#include <tuple>
>From fbc5a8186835e976c3daf1927310e0b1437db01e Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 30 Jan 2024 07:01:12 +0200
Subject: [PATCH 22/23] Added `__LIBCPP_PUSH_MACROS` and `__LIBCPP_POP_MACROS`
---
libcxx/include/__memory/inout_ptr.h | 5 +++++
libcxx/include/__memory/out_ptr.h | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/libcxx/include/__memory/inout_ptr.h b/libcxx/include/__memory/inout_ptr.h
index 620685ca0428e..b49940ca8bc25 100644
--- a/libcxx/include/__memory/inout_ptr.h
+++ b/libcxx/include/__memory/inout_ptr.h
@@ -26,6 +26,9 @@
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 23
@@ -100,4 +103,6 @@ _LIBCPP_HIDE_FROM_ABI auto inout_ptr(_Smart& __s, _Args&&... __args) {
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___INOUT_PTR_H
diff --git a/libcxx/include/__memory/out_ptr.h b/libcxx/include/__memory/out_ptr.h
index 256e6334d51f3..95a8b8a6fe83e 100644
--- a/libcxx/include/__memory/out_ptr.h
+++ b/libcxx/include/__memory/out_ptr.h
@@ -25,6 +25,9 @@
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 23
@@ -91,4 +94,6 @@ _LIBCPP_HIDE_FROM_ABI auto out_ptr(_Smart& __s, _Args&&... __args) {
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___OUT_PTR_H
>From cfd8356d12f8b6f7fe838cb137e6f28b4f6c3642 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 30 Jan 2024 07:04:04 +0200
Subject: [PATCH 23/23] Added `__LIBCPP_PUSH_MACROS` and `__LIBCPP_POP_MACROS`
---
libcxx/include/__memory/pointer_traits.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/libcxx/include/__memory/pointer_traits.h b/libcxx/include/__memory/pointer_traits.h
index 0168856851d2f..73d930b372267 100644
--- a/libcxx/include/__memory/pointer_traits.h
+++ b/libcxx/include/__memory/pointer_traits.h
@@ -27,6 +27,9 @@
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
// clang-format off
@@ -299,4 +302,6 @@ concept __resettable_smart_pointer_with_args = requires(_Smart __s, _Pointer __p
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___MEMORY_POINTER_TRAITS_H
More information about the cfe-commits
mailing list