231 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++2010 11// <memory>12 13// [out.ptr], function template out_ptr14// template<class Pointer = void, class Smart, class... Args>15// auto out_ptr(Smart& s, Args&&... args); // since c++2316 17#include <cassert>18#include <memory>19#include <utility>20 21#include "../types.h"22 23// Test updating an `out_ptr_t`-managed pointer for an API with a non-void pointer type.24// The API returns a new valid object.25void test_get_int_p() {26 auto get_int_p = [](int** pp) { *pp = new int{84}; };27 28 // raw pointer29 {30 int* rPtr;31 32 get_int_p(std::out_ptr<int*>(rPtr));33 assert(*rPtr == 84);34 35 delete rPtr;36 }37 38 // std::unique_ptr39 {40 std::unique_ptr<int> uPtr;41 42 get_int_p(std::out_ptr(uPtr));43 assert(*uPtr == 84);44 }45 46 {47 MoveOnlyDeleter<int> del;48 std::unique_ptr<int, MoveOnlyDeleter<int>> uPtr;49 50 get_int_p(std::out_ptr(uPtr, std::move(del)));51 assert(*uPtr == 84);52 assert(uPtr.get_deleter().wasMoveInitialized == true);53 }54 55 // std::shared_ptr56 {57 std::shared_ptr<int> sPtr;58 59 get_int_p(std::out_ptr(sPtr, [](auto* p) {60 assert(*p == 84);61 62 delete p;63 }));64 assert(*sPtr == 84);65 }66 67 // pointer-like ConstructiblePtr68 {69 ConstructiblePtr<int> cPtr;70 71 get_int_p(std::out_ptr(cPtr));72 assert(cPtr == 84);73 }74 75 // pointer-like ResettablePtr76 {77 ResettablePtr<int> rPtr{nullptr};78 79 get_int_p(std::out_ptr(rPtr));80 assert(rPtr == 84);81 }82 83 // NonConstructiblePtr84 {85 NonConstructiblePtr<int> nPtr;86 87 get_int_p(std::out_ptr(nPtr));88 assert(nPtr == 84);89 }90}91 92// Test updating an `out_ptr_t`-managed pointer for an API with a non-void pointer type.93// The API returns `nullptr`.94void test_get_int_p_nullptr() {95 auto get_int_p_nullptr = [](int** pp) { *pp = nullptr; };96 // raw pointer97 {98 int* rPtr;99 100 get_int_p_nullptr(std::out_ptr<int*>(rPtr));101 assert(rPtr == nullptr);102 103 delete rPtr;104 }105 106 // std::unique_ptr107 {108 std::unique_ptr<int> uPtr;109 110 get_int_p_nullptr(std::out_ptr(uPtr));111 assert(uPtr == nullptr);112 }113 114 // std::shared_ptr115 {116 std::shared_ptr<int> sPtr;117 118 get_int_p_nullptr(std::out_ptr(sPtr, [](auto* p) {119 assert(p == nullptr);120 121 delete p;122 }));123 assert(sPtr == nullptr);124 }125}126 127// Test updating an `out_ptr_t`-managed pointer for an API with a void pointer type.128// The API returns a new valid object.129void test_get_int_void_p() {130 auto get_int_void_p = [](void** pp) { *(reinterpret_cast<int**>(pp)) = new int{84}; };131 132 // raw pointer133 {134 int* rPtr;135 136 get_int_void_p(std::out_ptr(rPtr));137 assert(*rPtr == 84);138 139 delete rPtr;140 }141 142 // std::unique_ptr143 {144 std::unique_ptr<int> uPtr;145 146 get_int_void_p(std::out_ptr(uPtr));147 assert(*uPtr == 84);148 }149 150 // std::shared_ptr151 {152 std::shared_ptr<int> sPtr;153 154 get_int_void_p(std::out_ptr(sPtr, [](auto* p) {155 assert(*p == 84);156 157 delete p;158 }));159 assert(*sPtr == 84);160 }161 162 // pointer-like ConstructiblePtr163 {164 ConstructiblePtr<int> cPtr;165 166 get_int_void_p(std::out_ptr(cPtr));167 assert(cPtr == 84);168 }169 170 // pointer-like ResettablePtr171 {172 ResettablePtr<int> rPtr{nullptr};173 174 get_int_void_p(std::out_ptr(rPtr));175 assert(rPtr == 84);176 }177 178 // NonConstructiblePtr179 {180 NonConstructiblePtr<int> nPtr;181 182 get_int_void_p(std::out_ptr(nPtr));183 assert(nPtr == 84);184 }185}186 187// Test updating an `out_ptr_t`-managed pointer for an API with a void pointer type.188// The API returns `nullptr`.189void test_get_int_void_p_nullptr() {190 auto get_int_void_p_nullptr = [](void** pp) { *pp = nullptr; };191 192 // raw pointer193 {194 int* rPtr;195 196 get_int_void_p_nullptr(std::out_ptr<int*>(rPtr));197 assert(rPtr == nullptr);198 199 delete rPtr;200 }201 202 // std::unique_ptr203 {204 std::unique_ptr<int> uPtr;205 206 get_int_void_p_nullptr(std::out_ptr(uPtr));207 assert(uPtr == nullptr);208 }209 210 // std::shared_ptr211 {212 std::shared_ptr<int> sPtr;213 214 get_int_void_p_nullptr(std::out_ptr(sPtr, [](auto* p) {215 assert(p == nullptr);216 217 delete p;218 }));219 assert(sPtr == nullptr);220 }221}222 223int main(int, char**) {224 test_get_int_p();225 test_get_int_p_nullptr();226 test_get_int_void_p();227 test_get_int_void_p_nullptr();228 229 return 0;230}231