//===----------------------------------------------------------------------===// // // 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 // // [out.ptr], function template out_ptr // template // auto out_ptr(Smart& s, Args&&... args); // since c++23 #include #include #include #include "../types.h" // Test updating an `out_ptr_t`-managed pointer for an API with a non-void pointer type. // The API returns a new valid object. 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(rPtr)); assert(*rPtr == 84); delete rPtr; } // std::unique_ptr { std::unique_ptr uPtr; get_int_p(std::out_ptr(uPtr)); assert(*uPtr == 84); } { MoveOnlyDeleter del; std::unique_ptr> uPtr; get_int_p(std::out_ptr(uPtr, std::move(del))); assert(*uPtr == 84); assert(uPtr.get_deleter().wasMoveInitialized == true); } // std::shared_ptr { std::shared_ptr sPtr; get_int_p(std::out_ptr(sPtr, [](auto* p) { assert(*p == 84); delete p; })); assert(*sPtr == 84); } // pointer-like ConstructiblePtr { ConstructiblePtr cPtr; get_int_p(std::out_ptr(cPtr)); assert(cPtr == 84); } // pointer-like ResettablePtr { ResettablePtr rPtr{nullptr}; get_int_p(std::out_ptr(rPtr)); assert(rPtr == 84); } // NonConstructiblePtr { NonConstructiblePtr nPtr; get_int_p(std::out_ptr(nPtr)); assert(nPtr == 84); } } // Test updating an `out_ptr_t`-managed pointer for an API with a non-void pointer type. // The API returns `nullptr`. 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(rPtr)); assert(rPtr == nullptr); delete rPtr; } // std::unique_ptr { std::unique_ptr uPtr; get_int_p_nullptr(std::out_ptr(uPtr)); assert(uPtr == nullptr); } // std::shared_ptr { std::shared_ptr sPtr; get_int_p_nullptr(std::out_ptr(sPtr, [](auto* p) { assert(p == nullptr); delete p; })); assert(sPtr == nullptr); } } // Test updating an `out_ptr_t`-managed pointer for an API with a void pointer type. // The API returns a new valid object. void test_get_int_void_p() { auto get_int_void_p = [](void** pp) { *(reinterpret_cast(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 uPtr; get_int_void_p(std::out_ptr(uPtr)); assert(*uPtr == 84); } // std::shared_ptr { std::shared_ptr sPtr; get_int_void_p(std::out_ptr(sPtr, [](auto* p) { assert(*p == 84); delete p; })); assert(*sPtr == 84); } // pointer-like ConstructiblePtr { ConstructiblePtr cPtr; get_int_void_p(std::out_ptr(cPtr)); assert(cPtr == 84); } // pointer-like ResettablePtr { ResettablePtr rPtr{nullptr}; get_int_void_p(std::out_ptr(rPtr)); assert(rPtr == 84); } // NonConstructiblePtr { NonConstructiblePtr nPtr; get_int_void_p(std::out_ptr(nPtr)); assert(nPtr == 84); } } // Test updating an `out_ptr_t`-managed pointer for an API with a void pointer type. // The API returns `nullptr`. 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(rPtr)); assert(rPtr == nullptr); delete rPtr; } // std::unique_ptr { std::unique_ptr uPtr; get_int_void_p_nullptr(std::out_ptr(uPtr)); assert(uPtr == nullptr); } // std::shared_ptr { std::shared_ptr 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; }