//===----------------------------------------------------------------------===// // // 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 // // [inout.ptr], function template inout_ptr // template // auto inout_ptr(Smart& s, Args&&... args); // since c++23 #include #include #include #include "../types.h" // Test updating the ownership of an `inout_ptr_t`-managed pointer for an API with a non-void pointer type. // The API returns a new valid object. void test_replace_int_p() { auto replace_int_p = [](int** pp) { assert(**pp == 90); delete *pp; *pp = new int{84}; }; // raw pointer { auto rPtr = new int{90}; replace_int_p(std::inout_ptr(rPtr)); assert(*rPtr == 84); delete rPtr; } // std::unique_ptr { auto uPtr = std::make_unique(90); replace_int_p(std::inout_ptr(uPtr)); assert(*uPtr == 84); } { MoveOnlyDeleter del; std::unique_ptr> uPtr{new int{90}}; replace_int_p(std::inout_ptr(uPtr, std::move(del))); assert(*uPtr == 84); assert(uPtr.get_deleter().wasMoveInitialized == true); } // pointer-like ConstructiblePtr { ConstructiblePtr cPtr(new int{90}); replace_int_p(std::inout_ptr(cPtr)); assert(cPtr == 84); } // pointer-like ResettablePtr { ResettablePtr rPtr(new int{90}); replace_int_p(std::inout_ptr(rPtr)); assert(rPtr == 84); } // pointer-like NonConstructiblePtr { NonConstructiblePtr nPtr; nPtr.reset(new int{90}); replace_int_p(std::inout_ptr(nPtr)); assert(nPtr == 84); } } // Test updating the ownership of an `inout_ptr_t`-managed pointer for an API with a non-void pointer type. // The API returns `nullptr`. 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 { // LWG-3897 inout_ptr will not update raw pointer to null auto rPtr = new int{90}; replace_int_p_with_nullptr(std::inout_ptr(rPtr)); assert(rPtr == nullptr); } // std::unique_ptr { auto uPtr = std::make_unique(90); replace_int_p_with_nullptr(std::inout_ptr(uPtr)); assert(uPtr == nullptr); } } // Test updating the ownership of an `inout_ptr_t`-managed pointer for an API with a void pointer type. // The API returns a new valid object. void test_replace_int_void_p() { auto replace_int_void_p = [](void** pp) { assert(*(static_cast(*pp)) == 90); delete static_cast(*pp); *pp = new int{84}; }; // raw pointer { auto rPtr = new int{90}; replace_int_void_p(std::inout_ptr(rPtr)); assert(*rPtr == 84); delete rPtr; } // std::unique_ptr { auto uPtr = std::make_unique(90); replace_int_void_p(std::inout_ptr(uPtr)); assert(*uPtr == 84); } } // Test updating the ownership of an `inout_ptr_t`-managed pointer for an API with a non-void pointer type. // The API returns `nullptr`. void test_replace_int_void_p_with_nullptr() { auto replace_int_void_p_with_nullptr = [](void** pp) { assert(*(static_cast(*pp)) == 90); delete static_cast(*pp); *pp = nullptr; }; // raw pointer { auto rPtr = new int{90}; replace_int_void_p_with_nullptr(std::inout_ptr(rPtr)); assert(rPtr == nullptr); } // std::unique_ptr { auto uPtr = std::make_unique(90); replace_int_void_p_with_nullptr(std::inout_ptr(uPtr)); assert(uPtr == nullptr); } } // Test updating the ownership of an `inout_ptr_t`-managed pointer for an API with a void pointer type. // The API returns a new valid object. void test_replace_nullptr_with_int_p() { auto replace_nullptr_with_int_p = [](int** pp) { assert(*pp == nullptr); *pp = new int{84}; }; // raw pointer { int* rPtr = nullptr; replace_nullptr_with_int_p(std::inout_ptr(rPtr)); assert(*rPtr == 84); delete rPtr; } // std::unique_ptr { std::unique_ptr uPtr; replace_nullptr_with_int_p(std::inout_ptr(uPtr)); assert(*uPtr == 84); } } int main(int, char**) { 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; }