//===----------------------------------------------------------------------===// // // 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 // // template // pair uninitialized_move_n(InputIt, Size, ForwardIt); #include #include #include #include "test_macros.h" #include "test_iterators.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() { assert(count > 0); --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(1); } ++count; x = 0; } ThrowsCounted(ThrowsCounted const&) { assert(false); } ~ThrowsCounted() { assert(count > 0); --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; 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 == 0); 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); #endif } void test_counted() { using It = input_iterator; using FIt = forward_iterator; 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(); }