// Copyright (C) 2016-2017 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . // { dg-options "-std=gnu++17" } #include #include #include #include #include #include int del_count = 0; int ctor_count = 0; int throw_after = 0; struct DelCount { ~DelCount() { ++del_count; } }; struct ThrowAfterN { ThrowAfterN() { if (++ctor_count == throw_after) { std::ostringstream os; os << "ThrowAfterN(), ctor_count: " << ctor_count << " throw_after: " << throw_after << std::endl; throw std::runtime_error(os.str()); } } ThrowAfterN(ThrowAfterN&&) { if (++ctor_count == throw_after) { std::ostringstream os; os << "ThrowAfterN(), ctor_count: " << ctor_count << " throw_after: " << throw_after << std::endl; throw std::runtime_error(os.str()); } } DelCount dc; }; void test01() { char test_data[] = "123456"; std::uninitialized_default_construct(std::begin(test_data), std::end(test_data)); VERIFY(std::string(test_data) == "123456"); } void test02() { char test_data[] = "123456"; std::uninitialized_value_construct(std::begin(test_data), std::end(test_data)); VERIFY(std::string(test_data, 6) == std::string("\0\0\0\0\0\0", 6)); } void test03() { char test_data[] = "123456"; auto end = std::uninitialized_default_construct_n(std::begin(test_data), 6); VERIFY(std::string(test_data) == "123456"); VERIFY( end == test_data + 6 ); } void test04() { char test_data[] = "123456"; auto end = std::uninitialized_value_construct_n(std::begin(test_data), 5); VERIFY(std::string(test_data, 6) == std::string("\0\0\0\0\0" "6", 6)); VERIFY( end == test_data + 5 ); } void test05() { del_count = 0; DelCount* x = (DelCount*)malloc(sizeof(DelCount)); new (x) DelCount; std::destroy_at(&x[0]); VERIFY(del_count == 1); del_count = 0; free(x); } void test06() { del_count = 0; DelCount* x = (DelCount*)malloc(sizeof(DelCount)*10); for (int i = 0; i < 10; ++i) new (x+i) DelCount; std::destroy(x, x+10); VERIFY(del_count == 10); del_count = 0; free(x); } void test07() { del_count = 0; DelCount* x = (DelCount*)malloc(sizeof(DelCount)*10); for (int i = 0; i < 10; ++i) new (x+i) DelCount; auto end = std::destroy_n(x, 10); VERIFY(del_count == 10); VERIFY( end == x + 10 ); del_count = 0; free(x); } void test08() { std::vector> source; for (int i = 0; i < 10; ++i) source.push_back(std::make_unique(i)); std::unique_ptr* target = (std::unique_ptr*)malloc(sizeof(std::unique_ptr)*10); std::uninitialized_move(source.begin(), source.end(), target); for (const auto& x : source) VERIFY(!x); for (int i = 0; i < 10; ++i) VERIFY(bool(*(target+i))); auto end = std::destroy_n(target, 10); VERIFY( end == target + 10 ); free(target); } void test09() { std::vector> source; for (int i = 0; i < 10; ++i) source.push_back(std::make_unique(i)); std::unique_ptr* target = (std::unique_ptr*)malloc(sizeof(std::unique_ptr)*10); auto end = std::uninitialized_move_n(source.begin(), 10, target); VERIFY( end.first == source.begin() + 10 ); VERIFY( end.second == target + 10 ); for (const auto& x : source) VERIFY(!x); for (int i = 0; i < 10; ++i) VERIFY(bool(*(target+i))); auto end2 = std::destroy_n(target, 10); VERIFY( end2 == target + 10 ); free(target); } void test10() { char* x = (char*)malloc(sizeof(char)*10); for (int i = 0; i < 10; ++i) new (x+i) char; std::destroy(x, x+10); free(x); } void test11() { char* x = (char*)malloc(sizeof(char)*10); for (int i = 0; i < 10; ++i) new (x+i) char; auto end = std::destroy_n(x, 10); VERIFY( end == x + 10 ); free(x); } void test12() { throw_after = 5; del_count = 0; ctor_count = 0; ThrowAfterN* target = (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10); try { std::uninitialized_default_construct(target, target+10); } catch (...) { } free(target); VERIFY(ctor_count == 5); VERIFY(del_count == 5); throw_after = 0; del_count = 0; ctor_count = 0; } void test13() { throw_after = 5; del_count = 0; ctor_count = 0; ThrowAfterN* target = (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10); try { std::uninitialized_value_construct(target, target+10); } catch (...) { } free(target); VERIFY(ctor_count == 5); VERIFY(del_count == 5); throw_after = 0; del_count = 0; ctor_count = 0; } void test14() { throw_after = 5; del_count = 0; ctor_count = 0; ThrowAfterN* target = (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10); try { std::uninitialized_default_construct_n(target, 10); } catch (...) { } free(target); VERIFY(ctor_count == 5); VERIFY(del_count == 5); throw_after = 0; del_count = 0; ctor_count = 0; } void test15() { throw_after = 5; del_count = 0; ctor_count = 0; ThrowAfterN* target = (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10); try { std::uninitialized_value_construct_n(target, 10); } catch (...) { } free(target); VERIFY(ctor_count == 5); VERIFY(del_count == 5); throw_after = 0; del_count = 0; ctor_count = 0; } void test16() { std::vector source(10); del_count = 0; ctor_count = 0; throw_after = 5; throw_after = 5; ThrowAfterN* target = (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10); try { std::uninitialized_move(source.begin(), source.end(), target); } catch (...) { } free(target); VERIFY(ctor_count == 5); VERIFY(del_count == 5); throw_after = 0; del_count = 0; ctor_count = 0; } void test17() { std::vector source(10); del_count = 0; ctor_count = 0; throw_after = 5; ThrowAfterN* target = (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10); try { std::uninitialized_move_n(source.begin(), 10, target); } catch (...) { } free(target); VERIFY(ctor_count == 5); VERIFY(del_count == 5); throw_after = 0; del_count = 0; ctor_count = 0; } void test18() { char test_source[] = "123456"; char test_target[] = "000000"; std::uninitialized_move(std::begin(test_source), std::end(test_source), test_target); VERIFY(std::string(test_target) == "123456"); } void test19() { char test_source[] = "123456"; char test_target[] = "000000"; auto end = std::uninitialized_move_n(std::begin(test_source), 6, test_target); VERIFY(std::string(test_target) == "123456"); VERIFY( end.first == test_source + 6 ); VERIFY( end.second == test_target + 6 ); } int main() { test01(); test02(); test03(); test04(); test05(); test06(); test07(); test08(); test09(); test10(); test11(); test12(); test13(); test14(); test15(); test16(); test17(); test18(); test19(); }