1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef TEST_LIBCXX_UTILITIES_SMARTPTR_ADAPT_TYPES_H |
10 | #define TEST_LIBCXX_UTILITIES_SMARTPTR_ADAPT_TYPES_H |
11 | |
12 | #include <type_traits> |
13 | #include <memory> |
14 | |
15 | #include "test_macros.h" |
16 | |
17 | // Custom deleters. |
18 | |
19 | template <typename T> |
20 | struct MoveOnlyDeleter { |
21 | MoveOnlyDeleter() = default; |
22 | MoveOnlyDeleter(const MoveOnlyDeleter&) = delete; |
23 | MoveOnlyDeleter& operator=(const MoveOnlyDeleter&) = delete; |
24 | MoveOnlyDeleter(MoveOnlyDeleter&&) : wasMoveInitilized{true} {} |
25 | MoveOnlyDeleter& operator=(MoveOnlyDeleter&&) = default; |
26 | |
27 | void operator()(T* p) const { delete p; } |
28 | |
29 | bool wasMoveInitilized = false; |
30 | }; |
31 | |
32 | // Custom pointer types. |
33 | |
34 | template <typename T> |
35 | struct ConstructiblePtr { |
36 | using pointer = T*; |
37 | std::unique_ptr<T> ptr; |
38 | |
39 | ConstructiblePtr() = default; |
40 | explicit ConstructiblePtr(T* p) : ptr{p} {} |
41 | |
42 | auto operator==(T val) { return *ptr == val; } |
43 | |
44 | auto* get() const { return ptr.get(); } |
45 | |
46 | void release() { ptr.release(); } |
47 | }; |
48 | |
49 | LIBCPP_STATIC_ASSERT(std::is_same_v<std::__pointer_of_t< ConstructiblePtr<int>>, int* >); |
50 | static_assert(std::is_constructible_v< ConstructiblePtr<int>, int* >); |
51 | |
52 | struct ResetArg {}; |
53 | |
54 | template <typename T> |
55 | struct ResettablePtr { |
56 | using element_type = T; |
57 | std::unique_ptr<T> ptr; |
58 | |
59 | explicit ResettablePtr(T* p) : ptr{p} {} |
60 | |
61 | auto operator*() const { return *ptr; } |
62 | |
63 | auto operator==(T val) { return *ptr == val; } |
64 | |
65 | void reset() { ptr.reset(); } |
66 | void reset(T* p, ResetArg) { ptr.reset(p); } |
67 | |
68 | auto* get() const { return ptr.get(); } |
69 | |
70 | void release() { ptr.release(); } |
71 | }; |
72 | |
73 | LIBCPP_STATIC_ASSERT(std::is_same_v<std::__pointer_of_t< ResettablePtr<int>>, int* >); |
74 | static_assert(std::is_constructible_v< ResettablePtr<int>, int* >); |
75 | |
76 | template <typename T> |
77 | struct NonConstructiblePtr : public ResettablePtr<T> { |
78 | NonConstructiblePtr() : NonConstructiblePtr::ResettablePtr(nullptr) {}; |
79 | |
80 | void reset(T* p) { ResettablePtr<T>::ptr.reset(p); } |
81 | }; |
82 | |
83 | LIBCPP_STATIC_ASSERT(std::is_same_v<std::__pointer_of_t< NonConstructiblePtr<int>>, int* >); |
84 | static_assert(!std::is_constructible_v< NonConstructiblePtr<int>, int* >); |
85 | |
86 | #endif // TEST_LIBCXX_UTILITIES_SMARTPTR_ADAPT_TYPES_H |
87 | |