diff options
author | Eric Fiselier <eric@efcs.ca> | 2016-07-24 03:51:39 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2016-07-24 03:51:39 +0000 |
commit | e4d9c316d2e7add22fb6640000f2f3a30ed31fc0 (patch) | |
tree | c596c395ab7336ea5b430c920c553cbb209fec2e /libcxx/test/std/utilities/memory/specialized.algorithms | |
parent | 8a9bb7baeb40fff34c8ddd664bde351e7aa3ea0b (diff) | |
download | bcm5719-llvm-e4d9c316d2e7add22fb6640000f2f3a30ed31fc0.tar.gz bcm5719-llvm-e4d9c316d2e7add22fb6640000f2f3a30ed31fc0.zip |
Implement P0040r3: Extending memory management tools
llvm-svn: 276544
Diffstat (limited to 'libcxx/test/std/utilities/memory/specialized.algorithms')
9 files changed, 871 insertions, 0 deletions
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp new file mode 100644 index 00000000000..2ad9d04e59b --- /dev/null +++ b/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class ForwardIt> +// void destroy(ForwardIt, ForwardIt); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" + +struct Counted { + static int count; + static void reset() { count = 0; } + Counted() { ++count; } + Counted(Counted const&) { ++count; } + ~Counted() { --count; } + friend void operator&(Counted) = delete; +}; +int Counted::count = 0; + +int main() +{ + using It = forward_iterator<Counted*>; + const int N = 5; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + std::uninitialized_fill(p, p+N, Counted()); + assert(Counted::count == 5); + std::destroy(p, p+1); + p += 1; + assert(Counted::count == 4); + std::destroy(It(p), It(p + 4)); + assert(Counted::count == 0); +} diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp new file mode 100644 index 00000000000..4d44e4eaf6a --- /dev/null +++ b/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class _Tp> +// void destroy_at(_Tp*); + +#include <memory> +#include <cstdlib> +#include <cassert> + +struct Counted { + static int count; + static void reset() { count = 0; } + Counted() { ++count; } + Counted(Counted const&) { ++count; } + ~Counted() { --count; } + friend void operator&(Counted) = delete; +}; +int Counted::count = 0; + +struct VCounted { + static int count; + static void reset() { count = 0; } + VCounted() { ++count; } + VCounted(VCounted const&) { ++count; } + virtual ~VCounted() { --count; } + friend void operator&(VCounted) = delete; +}; +int VCounted::count = 0; + +struct DCounted : VCounted { + friend void operator&(DCounted) = delete; +}; + +int main() +{ + { + void* mem1 = std::malloc(sizeof(Counted)); + void* mem2 = std::malloc(sizeof(Counted)); + assert(mem1 && mem2); + assert(Counted::count == 0); + Counted* ptr1 = ::new(mem1) Counted(); + Counted* ptr2 = ::new(mem2) Counted(); + assert(Counted::count == 2); + std::destroy_at(ptr1); + assert(Counted::count == 1); + std::destroy_at(ptr2); + assert(Counted::count == 0); + } + { + void* mem1 = std::malloc(sizeof(DCounted)); + void* mem2 = std::malloc(sizeof(DCounted)); + assert(mem1 && mem2); + assert(DCounted::count == 0); + DCounted* ptr1 = ::new(mem1) DCounted(); + DCounted* ptr2 = ::new(mem2) DCounted(); + assert(DCounted::count == 2); + assert(VCounted::count == 2); + std::destroy_at(ptr1); + assert(VCounted::count == 1); + std::destroy_at(ptr2); + assert(VCounted::count == 0); + } +} diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp new file mode 100644 index 00000000000..d1eaca558a7 --- /dev/null +++ b/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class ForwardIt, class Size> +// ForwardIt destroy_n(ForwardIt, Size s); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" + +struct Counted { + static int count; + static void reset() { count = 0; } + Counted() { ++count; } + Counted(Counted const&) { ++count; } + ~Counted() { --count; } + friend void operator&(Counted) = delete; +}; +int Counted::count = 0; + +int main() +{ + using It = forward_iterator<Counted*>; + const int N = 5; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + std::uninitialized_fill(p, p+N, Counted()); + assert(Counted::count == 5); + Counted* np = std::destroy_n(p, 1); + assert(np == p+1); + assert(Counted::count == 4); + p += 1; + It it = std::destroy_n(It(p), 4); + assert(it == It(p+4)); + assert(Counted::count == 0); +} diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp new file mode 100644 index 00000000000..6bdb49cad88 --- /dev/null +++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class ForwardIt> +// void uninitialized_default_construct(ForwardIt, ForwardIt); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "test_throw.h" + +struct Counted { + static int count; + static int constructed; + static void reset() { count = constructed = 0; } + explicit Counted() { ++count; ++constructed; } + Counted(Counted const&) { assert(false); } + ~Counted() { --count; } + friend void operator&(Counted) = delete; +}; +int Counted::count = 0; +int Counted::constructed = 0; + + +struct ThrowsCounted { + static int count; + static int constructed; + static int throw_after; + static void reset() { throw_after = count = constructed = 0; } + explicit ThrowsCounted() { + ++constructed; + if (throw_after > 0 && --throw_after == 0) { + test_throw<int>(); + } + ++count; + } + ThrowsCounted(ThrowsCounted const&) { assert(false); } + ~ThrowsCounted() { --count; } + friend void operator&(ThrowsCounted) = delete; +}; +int ThrowsCounted::count = 0; +int ThrowsCounted::constructed = 0; +int ThrowsCounted::throw_after = 0; + + +void test_ctor_throws() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + using It = forward_iterator<ThrowsCounted*>; + const int N = 5; + alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {}; + ThrowsCounted* p = (ThrowsCounted*)pool; + try { + ThrowsCounted::throw_after = 4; + std::uninitialized_default_construct(It(p), It(p+N)); + assert(false); + } catch (...) {} + assert(ThrowsCounted::count == 3); + assert(ThrowsCounted::constructed == 4); // forth construction throws + std::destroy(p, p+3); + assert(ThrowsCounted::count == 0); +#endif +} + +void test_counted() +{ + using It = forward_iterator<Counted*>; + const int N = 5; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + std::uninitialized_default_construct(It(p), It(p+1)); + assert(Counted::count == 1); + assert(Counted::constructed = 1); + std::uninitialized_default_construct(It(p+1), It(p+N)); + assert(Counted::count == 5); + assert(Counted::constructed == 5); + std::destroy(p, p+N); + assert(Counted::count == 0); +} + +void test_value_initialized() +{ + using It = forward_iterator<int*>; + const int N = 5; + int pool[N] = {-1, -1, -1, -1, -1}; + int* p = pool; + std::uninitialized_default_construct(It(p), It(p+1)); + assert(pool[0] == -1); + assert(pool[1] == -1); + std::uninitialized_default_construct(It(p+1), It(p+N)); + assert(pool[1] == -1); + assert(pool[2] == -1); + assert(pool[3] == -1); + assert(pool[4] == -1); +} + +int main() +{ + test_counted(); + test_value_initialized(); + test_ctor_throws(); +} diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp new file mode 100644 index 00000000000..f59ea8256c0 --- /dev/null +++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp @@ -0,0 +1,119 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class ForwardIt> +// void uninitialized_default_construct(ForwardIt, ForwardIt); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "test_throw.h" + +struct Counted { + static int count; + static int constructed; + static void reset() { count = constructed = 0; } + explicit Counted() { ++count; ++constructed; } + Counted(Counted const&) { assert(false); } + ~Counted() { --count; } + friend void operator&(Counted) = delete; +}; +int Counted::count = 0; +int Counted::constructed = 0; + + +struct ThrowsCounted { + static int count; + static int constructed; + static int throw_after; + static void reset() { throw_after = count = constructed = 0; } + explicit ThrowsCounted() { + ++constructed; + if (throw_after > 0 && --throw_after == 0) { + test_throw<int>(); + } + ++count; + } + ThrowsCounted(ThrowsCounted const&) { assert(false); } + ~ThrowsCounted() { --count; } + friend void operator&(ThrowsCounted) = delete; +}; +int ThrowsCounted::count = 0; +int ThrowsCounted::constructed = 0; +int ThrowsCounted::throw_after = 0; + +void test_ctor_throws() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + using It = forward_iterator<ThrowsCounted*>; + const int N = 5; + alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {}; + ThrowsCounted* p = (ThrowsCounted*)pool; + try { + ThrowsCounted::throw_after = 4; + std::uninitialized_default_construct_n(It(p), N); + assert(false); + } catch (...) {} + assert(ThrowsCounted::count == 3); + assert(ThrowsCounted::constructed == 4); // forth construction throws + std::destroy(p, p+3); + assert(ThrowsCounted::count == 0); +#endif +} + +void test_counted() +{ + using It = forward_iterator<Counted*>; + const int N = 5; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + It e = std::uninitialized_default_construct_n(It(p), 1); + assert(e == It(p+1)); + assert(Counted::count == 1); + assert(Counted::constructed = 1); + e = std::uninitialized_default_construct_n(It(p+1), 4); + assert(e == It(p+N)); + assert(Counted::count == 5); + assert(Counted::constructed == 5); + std::destroy(p, p+N); + assert(Counted::count == 0); +} + +void test_value_initialized() +{ + using It = forward_iterator<int*>; + const int N = 5; + int pool[N] = {-1, -1, -1, -1, -1}; + int* p = pool; + auto e = std::uninitialized_default_construct_n(It(p), 1); + assert(e == It(p+1)); + assert(pool[0] == -1); + assert(pool[1] == -1); + e = std::uninitialized_default_construct_n(It(p+1), 4); + assert(e == It(p+N)); + assert(pool[1] == -1); + assert(pool[2] == -1); + assert(pool[3] == -1); + assert(pool[4] == -1); +} + + +int main() +{ + test_counted(); + test_value_initialized(); + test_ctor_throws(); +} diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp new file mode 100644 index 00000000000..3f73b60a6e2 --- /dev/null +++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp @@ -0,0 +1,114 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class ForwardIt> +// void uninitialized_value_construct(ForwardIt, ForwardIt); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "test_throw.h" + +struct Counted { + static int count; + static int constructed; + static void reset() { count = constructed = 0; } + explicit Counted() { ++count; ++constructed; } + Counted(Counted const&) { assert(false); } + ~Counted() { --count; } + friend void operator&(Counted) = delete; +}; +int Counted::count = 0; +int Counted::constructed = 0; + + +struct ThrowsCounted { + static int count; + static int constructed; + static int throw_after; + static void reset() { throw_after = count = constructed = 0; } + explicit ThrowsCounted() { + ++constructed; + if (throw_after > 0 && --throw_after == 0) { + test_throw<int>(); + } + ++count; + } + ThrowsCounted(ThrowsCounted const&) { assert(false); } + ~ThrowsCounted() { --count; } + friend void operator&(ThrowsCounted) = delete; +}; +int ThrowsCounted::count = 0; +int ThrowsCounted::constructed = 0; +int ThrowsCounted::throw_after = 0; + +void test_ctor_throws() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + using It = forward_iterator<ThrowsCounted*>; + const int N = 5; + alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {}; + ThrowsCounted* p = (ThrowsCounted*)pool; + try { + ThrowsCounted::throw_after = 4; + std::uninitialized_value_construct(It(p), It(p+N)); + assert(false); + } catch (...) {} + assert(ThrowsCounted::count == 3); + assert(ThrowsCounted::constructed == 4); // forth construction throws + std::destroy(p, p+3); + assert(ThrowsCounted::count == 0); +#endif +} + +void test_counted() +{ + using It = forward_iterator<Counted*>; + const int N = 5; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + std::uninitialized_value_construct(It(p), It(p+1)); + assert(Counted::count == 1); + assert(Counted::constructed = 1); + std::uninitialized_value_construct(It(p+1), It(p+N)); + assert(Counted::count == 5); + assert(Counted::constructed == 5); + std::destroy(p, p+N); + assert(Counted::count == 0); +} + +void test_value_initialized() +{ + using It = forward_iterator<int*>; + const int N = 5; + int pool[N] = {-1, -1, -1, -1, -1}; + int* p = pool; + std::uninitialized_value_construct(It(p), It(p+1)); + assert(pool[0] == 0); + assert(pool[1] == -1); + std::uninitialized_value_construct(It(p+1), It(p+N)); + assert(pool[1] == 0); + assert(pool[2] == 0); + assert(pool[3] == 0); + assert(pool[4] == 0); +} + +int main() +{ + test_counted(); + test_value_initialized(); + test_ctor_throws(); +} diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp new file mode 100644 index 00000000000..65f9523f8c1 --- /dev/null +++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class ForwardIt> +// void uninitialized_value_construct(ForwardIt, ForwardIt); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "test_throw.h" + +struct Counted { + static int count; + static int constructed; + static void reset() { count = constructed = 0; } + explicit Counted() { ++count; ++constructed; } + Counted(Counted const&) { assert(false); } + ~Counted() { --count; } + friend void operator&(Counted) = delete; +}; +int Counted::count = 0; +int Counted::constructed = 0; + +struct ThrowsCounted { + static int count; + static int constructed; + static int throw_after; + static void reset() { throw_after = count = constructed = 0; } + explicit ThrowsCounted() { + ++constructed; + if (throw_after > 0 && --throw_after == 0) { + test_throw<int>(); + } + ++count; + } + ThrowsCounted(ThrowsCounted const&) { assert(false); } + ~ThrowsCounted() { --count; } + friend void operator&(ThrowsCounted) = delete; +}; +int ThrowsCounted::count = 0; +int ThrowsCounted::constructed = 0; +int ThrowsCounted::throw_after = 0; + +void test_ctor_throws() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + using It = forward_iterator<ThrowsCounted*>; + const int N = 5; + alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {}; + ThrowsCounted* p = (ThrowsCounted*)pool; + try { + ThrowsCounted::throw_after = 4; + std::uninitialized_value_construct_n(It(p), N); + assert(false); + } catch (...) {} + assert(ThrowsCounted::count == 3); + assert(ThrowsCounted::constructed == 4); // forth construction throws + std::destroy(p, p+3); + assert(ThrowsCounted::count == 0); +#endif +} + +void test_counted() +{ + using It = forward_iterator<Counted*>; + const int N = 5; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + It e = std::uninitialized_value_construct_n(It(p), 1); + assert(e == It(p+1)); + assert(Counted::count == 1); + assert(Counted::constructed = 1); + e = std::uninitialized_value_construct_n(It(p+1), 4); + assert(e == It(p+N)); + assert(Counted::count == 5); + assert(Counted::constructed == 5); + std::destroy(p, p+N); + assert(Counted::count == 0); +} + +void test_value_initialized() +{ + using It = forward_iterator<int*>; + const int N = 5; + int pool[N] = {-1, -1, -1, -1, -1}; + int* p = pool; + It e = std::uninitialized_value_construct_n(It(p), 1); + assert(e == It(p+1)); + assert(pool[0] == 0); + assert(pool[1] == -1); + e = std::uninitialized_value_construct_n(It(p+1), 4); + assert(e == It(p+N)); + assert(pool[1] == 0); + assert(pool[2] == 0); + assert(pool[3] == 0); + assert(pool[4] == 0); +} + +int main() +{ + test_counted(); + test_value_initialized(); +}
\ No newline at end of file diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp new file mode 100644 index 00000000000..51fb06b9a05 --- /dev/null +++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class InputIt, class ForwardIt> +// ForwardIt uninitialized_move(InputIt, InputIt, ForwardIt); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "test_throw.h" + +struct Counted { + static int count; + static int constructed; + static void reset() { count = constructed = 0; } + explicit Counted(int&& x) : value(x) { x = 0; ++count; ++constructed; } + Counted(Counted const&) { assert(false); } + ~Counted() { --count; } + friend void operator&(Counted) = delete; + int value; +}; +int Counted::count = 0; +int Counted::constructed = 0; + +struct ThrowsCounted { + static int count; + static int constructed; + static int throw_after; + static void reset() { throw_after = count = constructed = 0; } + explicit ThrowsCounted(int&& x) { + ++constructed; + if (throw_after > 0 && --throw_after == 0) { + test_throw<int>(); + } + ++count; + x = 0; + } + ThrowsCounted(ThrowsCounted const&) { assert(false); } + ~ThrowsCounted() { --count; } + friend void operator&(ThrowsCounted) = delete; +}; +int ThrowsCounted::count = 0; +int ThrowsCounted::constructed = 0; +int ThrowsCounted::throw_after = 0; + +void test_ctor_throws() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + using It = forward_iterator<ThrowsCounted*>; + const int N = 5; + int values[N] = {1, 2, 3, 4, 5}; + alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {}; + ThrowsCounted* p = (ThrowsCounted*)pool; + try { + ThrowsCounted::throw_after = 4; + std::uninitialized_move(values, values + N, It(p)); + assert(false); + } catch (...) {} + assert(ThrowsCounted::count == 3); + assert(ThrowsCounted::constructed == 4); // forth construction throws + assert(values[0] == 0); + assert(values[1] == 0); + assert(values[2] == 0); + assert(values[3] == 4); + assert(values[4] == 5); + std::destroy(p, p+3); + assert(ThrowsCounted::count == 0); +#endif +} + +void test_counted() +{ + using It = input_iterator<int*>; + using FIt = forward_iterator<Counted*>; + const int N = 5; + int values[N] = {1, 2, 3, 4, 5}; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + auto ret = std::uninitialized_move(It(values), It(values + 1), FIt(p)); + assert(ret == FIt(p +1)); + assert(Counted::constructed = 1); + assert(Counted::count == 1); + assert(p[0].value == 1); + assert(values[0] == 0); + ret = std::uninitialized_move(It(values+1), It(values+N), FIt(p+1)); + assert(ret == FIt(p + N)); + assert(Counted::count == 5); + assert(Counted::constructed == 5); + assert(p[1].value == 2); + assert(p[2].value == 3); + assert(p[3].value == 4); + assert(p[4].value == 5); + assert(values[1] == 0); + assert(values[2] == 0); + assert(values[3] == 0); + assert(values[4] == 0); + std::destroy(p, p+N); + assert(Counted::count == 0); +} + +int main() { + test_counted(); + test_ctor_throws(); +}
\ No newline at end of file diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp new file mode 100644 index 00000000000..58866e16551 --- /dev/null +++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp @@ -0,0 +1,120 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <memory> + +// template <class InputIt, class Size, class ForwardIt> +// pair<InputIt, ForwardIt> uninitialized_move_n(InputIt, Size, ForwardIt); + +#include <memory> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "test_throw.h" + +struct Counted { + static int count; + static int constructed; + static void reset() { count = constructed = 0; } + explicit Counted(int&& x) : value(x) { x = 0; ++count; ++constructed; } + Counted(Counted const&) { assert(false); } + ~Counted() { --count; } + friend void operator&(Counted) = delete; + int value; +}; +int Counted::count = 0; +int Counted::constructed = 0; + +struct ThrowsCounted { + static int count; + static int constructed; + static int throw_after; + static void reset() { throw_after = count = constructed = 0; } + explicit ThrowsCounted(int&& x) { + ++constructed; + if (throw_after > 0 && --throw_after == 0) { + test_throw<int>(); + } + ++count; + x = 0; + } + ThrowsCounted(ThrowsCounted const&) { assert(false); } + ~ThrowsCounted() { --count; } + friend void operator&(ThrowsCounted) = delete; +}; +int ThrowsCounted::count = 0; +int ThrowsCounted::constructed = 0; +int ThrowsCounted::throw_after = 0; + +void test_ctor_throws() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + using It = forward_iterator<ThrowsCounted*>; + const int N = 5; + int values[N] = {1, 2, 3, 4, 5}; + alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {}; + ThrowsCounted* p = (ThrowsCounted*)pool; + try { + ThrowsCounted::throw_after = 4; + std::uninitialized_move_n(values, N, It(p)); + assert(false); + } catch (...) {} + assert(ThrowsCounted::count == 3); + assert(ThrowsCounted::constructed == 4); // forth construction throws + assert(values[0] == 0); + assert(values[1] == 0); + assert(values[2] == 0); + assert(values[3] == 4); + assert(values[4] == 5); + std::destroy(p, p+3); + assert(ThrowsCounted::count == 0); +#endif +} + +void test_counted() +{ + using It = input_iterator<int*>; + using FIt = forward_iterator<Counted*>; + const int N = 5; + int values[N] = {1, 2, 3, 4, 5}; + alignas(Counted) char pool[sizeof(Counted)*N] = {}; + Counted* p = (Counted*)pool; + auto ret = std::uninitialized_move_n(It(values), 1, FIt(p)); + assert(ret.first == It(values +1)); + assert(ret.second == FIt(p +1)); + assert(Counted::constructed = 1); + assert(Counted::count == 1); + assert(p[0].value == 1); + assert(values[0] == 0); + ret = std::uninitialized_move_n(It(values+1), N-1, FIt(p+1)); + assert(ret.first == It(values+N)); + assert(ret.second == FIt(p + N)); + assert(Counted::count == 5); + assert(Counted::constructed == 5); + assert(p[1].value == 2); + assert(p[2].value == 3); + assert(p[3].value == 4); + assert(p[4].value == 5); + assert(values[1] == 0); + assert(values[2] == 0); + assert(values[3] == 0); + assert(values[4] == 0); + std::destroy(p, p+N); + assert(Counted::count == 0); +} + +int main() +{ + test_counted(); + test_ctor_throws(); +}
\ No newline at end of file |