//===----------------------------------------------------------------------===// // // 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 // //===----------------------------------------------------------------------===// // // shared_ptr // template // shared_ptr make_shared(Args&&... args); // T is not an array #include #include #include "count_new.h" #include "operator_hijacker.h" #include "test_macros.h" struct A { static int count; A(int i, char c) : int_(i), char_(c) {++count;} A(const A& a) : int_(a.int_), char_(a.char_) {++count;} ~A() {--count;} int get_int() const {return int_;} char get_char() const {return char_;} A* operator& () = delete; private: int int_; char char_; }; int A::count = 0; struct Foo { Foo() = default; virtual ~Foo() = default; }; #ifdef _LIBCPP_VERSION struct Result {}; static Result theFunction() { return Result(); } static int resultDeletorCount; static void resultDeletor(Result (*pf)()) { assert(pf == theFunction); ++resultDeletorCount; } void test_pointer_to_function() { { // https://llvm.org/PR27566 std::shared_ptr x(&theFunction, &resultDeletor); std::shared_ptr y(theFunction, resultDeletor); } assert(resultDeletorCount == 2); } #else // _LIBCPP_VERSION void test_pointer_to_function() {} #endif // _LIBCPP_VERSION template void test(const T &t0) { { T t1 = t0; std::shared_ptr p0 = std::make_shared(t0); std::shared_ptr p1 = std::make_shared(t1); assert(*p0 == t0); assert(*p1 == t1); } { const T t1 = t0; std::shared_ptr p0 = std::make_shared(t0); std::shared_ptr p1 = std::make_shared(t1); assert(*p0 == t0); assert(*p1 == t1); } } int main(int, char**) { int nc = globalMemCounter.outstanding_new; { int i = 67; char c = 'e'; std::shared_ptr p = std::make_shared(i, c); assert(globalMemCounter.checkOutstandingNewEq(nc+1)); assert(A::count == 1); assert(p->get_int() == 67); assert(p->get_char() == 'e'); } { // https://llvm.org/PR24137 std::shared_ptr p1 = std::make_shared(); assert(p1.get()); std::shared_ptr p2 = std::make_shared(); assert(p2.get()); } test_pointer_to_function(); #if TEST_STD_VER >= 11 nc = globalMemCounter.outstanding_new; { char c = 'e'; std::shared_ptr p = std::make_shared(67, c); assert(globalMemCounter.checkOutstandingNewEq(nc+1)); assert(A::count == 1); assert(p->get_int() == 67); assert(p->get_char() == 'e'); } #endif assert(A::count == 0); // Make sure std::make_shared handles badly-behaved types properly { std::shared_ptr p1 = std::make_shared(); std::shared_ptr p2 = std::make_shared(operator_hijacker()); assert(p1 != nullptr); assert(p2 != nullptr); } test(true); test(3); test(5.0); return 0; }