207 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// [inout.ptr], function template inout_ptr14// template<class Pointer = void, class Smart, class... Args>15// auto inout_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 the ownership of an `inout_ptr_t`-managed pointer for an API with a non-void pointer type.24// The API returns a new valid object.25void test_replace_int_p() {26 auto replace_int_p = [](int** pp) {27 assert(**pp == 90);28 29 delete *pp;30 *pp = new int{84};31 };32 33 // raw pointer34 {35 auto rPtr = new int{90};36 37 replace_int_p(std::inout_ptr<int*>(rPtr));38 assert(*rPtr == 84);39 40 delete rPtr;41 }42 43 // std::unique_ptr44 {45 auto uPtr = std::make_unique<int>(90);46 47 replace_int_p(std::inout_ptr(uPtr));48 assert(*uPtr == 84);49 }50 51 {52 MoveOnlyDeleter<int> del;53 std::unique_ptr<int, MoveOnlyDeleter<int>> uPtr{new int{90}};54 55 replace_int_p(std::inout_ptr(uPtr, std::move(del)));56 assert(*uPtr == 84);57 assert(uPtr.get_deleter().wasMoveInitialized == true);58 }59 60 // pointer-like ConstructiblePtr61 {62 ConstructiblePtr<int> cPtr(new int{90});63 64 replace_int_p(std::inout_ptr(cPtr));65 assert(cPtr == 84);66 }67 68 // pointer-like ResettablePtr69 {70 ResettablePtr<int> rPtr(new int{90});71 72 replace_int_p(std::inout_ptr(rPtr));73 assert(rPtr == 84);74 }75 76 // pointer-like NonConstructiblePtr77 {78 NonConstructiblePtr<int> nPtr;79 nPtr.reset(new int{90});80 81 replace_int_p(std::inout_ptr(nPtr));82 assert(nPtr == 84);83 }84}85 86// Test updating the ownership of an `inout_ptr_t`-managed pointer for an API with a non-void pointer type.87// The API returns `nullptr`.88void test_replace_int_p_with_nullptr() {89 auto replace_int_p_with_nullptr = [](int** pp) -> void {90 assert(**pp == 90);91 92 delete *pp;93 *pp = nullptr;94 };95 96 // raw pointer97 {98 // LWG-3897 inout_ptr will not update raw pointer to null99 auto rPtr = new int{90};100 101 replace_int_p_with_nullptr(std::inout_ptr<int*>(rPtr));102 assert(rPtr == nullptr);103 }104 105 // std::unique_ptr106 {107 auto uPtr = std::make_unique<int>(90);108 109 replace_int_p_with_nullptr(std::inout_ptr(uPtr));110 assert(uPtr == nullptr);111 }112}113 114// Test updating the ownership of an `inout_ptr_t`-managed pointer for an API with a void pointer type.115// The API returns a new valid object.116void test_replace_int_void_p() {117 auto replace_int_void_p = [](void** pp) {118 assert(*(static_cast<int*>(*pp)) == 90);119 120 delete static_cast<int*>(*pp);121 *pp = new int{84};122 };123 124 // raw pointer125 {126 auto rPtr = new int{90};127 128 replace_int_void_p(std::inout_ptr<int*>(rPtr));129 assert(*rPtr == 84);130 131 delete rPtr;132 }133 134 // std::unique_ptr135 {136 auto uPtr = std::make_unique<int>(90);137 138 replace_int_void_p(std::inout_ptr(uPtr));139 assert(*uPtr == 84);140 }141}142 143// Test updating the ownership of an `inout_ptr_t`-managed pointer for an API with a non-void pointer type.144// The API returns `nullptr`.145void test_replace_int_void_p_with_nullptr() {146 auto replace_int_void_p_with_nullptr = [](void** pp) {147 assert(*(static_cast<int*>(*pp)) == 90);148 149 delete static_cast<int*>(*pp);150 *pp = nullptr;151 };152 153 // raw pointer154 {155 auto rPtr = new int{90};156 157 replace_int_void_p_with_nullptr(std::inout_ptr<int*>(rPtr));158 assert(rPtr == nullptr);159 }160 161 // std::unique_ptr162 {163 auto uPtr = std::make_unique<int>(90);164 165 replace_int_void_p_with_nullptr(std::inout_ptr(uPtr));166 assert(uPtr == nullptr);167 }168}169 170// Test updating the ownership of an `inout_ptr_t`-managed pointer for an API with a void pointer type.171// The API returns a new valid object.172void test_replace_nullptr_with_int_p() {173 auto replace_nullptr_with_int_p = [](int** pp) {174 assert(*pp == nullptr);175 176 *pp = new int{84};177 };178 179 // raw pointer180 {181 int* rPtr = nullptr;182 183 replace_nullptr_with_int_p(std::inout_ptr<int*>(rPtr));184 assert(*rPtr == 84);185 186 delete rPtr;187 }188 189 // std::unique_ptr190 {191 std::unique_ptr<int> uPtr;192 193 replace_nullptr_with_int_p(std::inout_ptr(uPtr));194 assert(*uPtr == 84);195 }196}197 198int main(int, char**) {199 test_replace_int_p();200 test_replace_int_p_with_nullptr();201 test_replace_int_void_p();202 test_replace_int_void_p_with_nullptr();203 test_replace_nullptr_with_int_p();204 205 return 0;206}207