blob: 5062a3d1ebff21e6ca36863f4beb6a0ec20f0558 [file] [log] [blame]
// { dg-do run { target c++20 } }
// { dg-add-options no_pch }
// C++20 20.11.3.7 shared_ptr Creation [util.smartptr.shared.create]
#include <memory>
#ifndef __cpp_lib_shared_ptr_arrays
# error "Feature-test macro for make_shared arrays missing in <memory>"
#elif __cpp_lib_shared_ptr_arrays < 201707L
# error "Feature-test macro for make_shared arrays has wrong value in <memory>"
#endif
#include <testsuite_hooks.h>
int counter = 0;
template<typename T>
struct Alloc : std::allocator<T>
{
Alloc() = default;
template<typename U>
Alloc(const Alloc<U>&) { }
T* allocate(std::size_t n)
{
++counter;
return std::allocator<T>::allocate(n);
}
};
void
test01()
{
Alloc<int> a;
std::shared_ptr<int[]> p1 = std::allocate_shared<int[]>(a, 24);
VERIFY( counter == 1 );
VERIFY( p1[23] == 0 );
std::shared_ptr<int[48]> p2 = std::allocate_shared<int[48]>(a);
VERIFY( counter == 2 );
VERIFY( p2[47] == 0 );
std::shared_ptr<int[][12]> p3 = std::allocate_shared<int[][12]>(a, 3);
VERIFY( counter == 3 );
VERIFY( p3[2][11] == 0 );
std::shared_ptr<int[4][5]> p4 = std::allocate_shared<int[4][5]>(a);
VERIFY( counter == 4 );
VERIFY( p4[3][4] == 0 );
}
void
test02()
{
std::shared_ptr<int[]> p1 = std::make_shared<int[]>(24);
VERIFY( p1[23] == 0 );
std::shared_ptr<int[48]> p2 = std::make_shared<int[48]>();
VERIFY( p2[47] == 0 );
std::shared_ptr<int[][12]> p3 = std::make_shared<int[][12]>(3);
VERIFY( p3[2][11] == 0 );
std::shared_ptr<int[4][5]> p4 = std::make_shared<int[4][5]>();
VERIFY( p4[3][4] == 0 );
}
#include <vector>
#include <cstdint>
std::vector<std::uintptr_t> addresses;
void
test03()
{
// Verify construction and destruction order
struct Addressed
{
Addressed() { addresses.push_back(me()); }
~Addressed() { VERIFY( addresses.back() == me() ); addresses.pop_back(); }
std::uintptr_t me() const { return reinterpret_cast<std::uintptr_t>(this); }
};
auto check = [](auto shptr) {
std::uintptr_t last = 0;
for (auto a : addresses)
{
VERIFY( a > last );
last = a;
}
shptr.reset();
return addresses.empty();
};
VERIFY( check(std::make_shared<Addressed[][2]>(3)) );
VERIFY( check(std::make_shared<Addressed[4][2]>()) );
}
void
test04()
{
// Verify initial value
auto p1 = std::make_shared<int[]>(3, 9);
VERIFY( p1[0] == 9 && p1[1] == 9 && p1[2] == 9 );
auto p2 = std::make_shared<int[2]>(4);
VERIFY( p2[0] == 4 && p2[1] == 4 );
auto p3 = std::make_shared<int[][3]>(10, {1,2,3});
const auto& p3_0 = p3[0];
VERIFY( p3_0[0] == 1 && p3_0[1] == 2 && p3_0[2] == 3 );
for (int i = 1; i < 10; ++i)
for (int j = 0; j < 3; ++j)
VERIFY( p3[i][j] == p3_0[j] );
auto p4 = std::make_shared<int[10][3]>({4,5,6});
const auto& p4_0 = p4[0];
VERIFY( p4_0[0] == 4 && p4_0[1] == 5 && p4_0[2] == 6 );
for (int i = 1; i < 10; ++i)
for (int j = 0; j < 3; ++j)
VERIFY( p4[i][j] == p4_0[j] );
auto p5 = std::make_shared<int[][3][2]>(10, {{1,2},{3,4},{5,6}});
const auto& p5_0 = p5[0];
VERIFY( p5_0[0][0] == 1 && p5_0[0][1] == 2 );
VERIFY( p5_0[1][0] == 3 && p5_0[1][1] == 4 );
VERIFY( p5_0[2][0] == 5 && p5_0[2][1] == 6 );
for (int i = 1; i < 10; ++i)
for (int j = 0; j < 3; ++j)
for (int k = 0; k < 2; ++k)
VERIFY( p5[i][j][k] == p5_0[j][k] );
auto p6 = std::make_shared<int[4][3][2]>({{7,8},{9,10},{11,12}});
const auto& p6_0 = p6[0];
VERIFY( p6_0[0][0] == 7 && p6_0[0][1] == 8 );
VERIFY( p6_0[1][0] == 9 && p6_0[1][1] == 10 );
VERIFY( p6_0[2][0] == 11 && p6_0[2][1] == 12 );
for (int i = 1; i < 4; ++i)
for (int j = 0; j < 3; ++j)
for (int k = 0; k < 2; ++k)
VERIFY( p6[i][j][k] == p6_0[j][k] );
}
void
test05()
{
// Examples from the standard
using namespace std;
// Example 2
{
shared_ptr<double[]> p = make_shared<double[]>(1024);
// shared_ptr to a value-initialized double[1024]
for (int i = 0; i < 1024; ++i)
VERIFY( p[i] == 0.0 );
shared_ptr<double[][2][2]> q = make_shared<double[][2][2]>(6);
// shared_ptr to a value-initialized double[6][2][2]
for (int i = 0; i < 6; ++i)
for (auto& j : q[i])
for (auto& k : j)
VERIFY( k == 0.0 );
}
// Example 3
{
shared_ptr<double[1024]> p = make_shared<double[1024]>();
// shared_ptr to a value-initialized double[1024]
for (int i = 0; i < 1024; ++i)
VERIFY( p[i] == 0.0 );
shared_ptr<double[6][2][2]> q = make_shared<double[6][2][2]>();
// shared_ptr to a value-initialized double[6][2][2]
for (int i = 0; i < 6; ++i)
for (auto& j : q[i])
for (auto& k : j)
VERIFY( k == 0.0 );
}
// Example 4
{
shared_ptr<double[]> p = make_shared<double[]>(1024, 1.0);
// shared_ptr to a double[1024], where each element is 1.0
for (int i = 0; i < 1024; ++i)
VERIFY( p[i] == 1.0 );
shared_ptr<double[][2]> q = make_shared<double[][2]>(6, {1.0, 0.0});
// shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0}
for (int i = 0; i < 6; ++i)
VERIFY( q[i][0] == 1.0 && q[i][1] == 0.0 );
shared_ptr<vector<int>[]> r = make_shared<vector<int>[]>(4, {1, 2});
// shared_ptr to a vector<int>[4], where each vector has contents {1, 2}
for (int i = 0; i < 4; ++i)
VERIFY( r[i] == vector<int>({1, 2}) );
}
// Example 5
{
shared_ptr<double[1024]> p = make_shared<double[1024]>(1.0);
// shared_ptr to a double[1024], where each element is 1.0
for (int i = 0; i < 1024; ++i)
VERIFY( p[i] == 1.0 );
shared_ptr<double[6][2]> q = make_shared<double[6][2]>({1.0, 0.0});
// shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0}
for (int i = 0; i < 6; ++i)
VERIFY( q[i][0] == 1.0 && q[i][1] == 0.0 );
shared_ptr<vector<int>[4]> r = make_shared<vector<int>[4]>({1, 2});
// shared_ptr to a vector<int>[4], where each vector has contents {1, 2}
for (int i = 0; i < 4; ++i)
VERIFY( r[i] == vector<int>({1, 2}) );
}
}
int
main()
{
test01();
test02();
test03();
test04();
test05();
}