1//===----------------------------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is dual licensed under the MIT and the University of Illinois Open 6// Source Licenses. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10// UNSUPPORTED: c++98, c++03, c++11, c++14 11 12// <memory> 13 14// template <class InputIt, class Size, class ForwardIt> 15// pair<InputIt, ForwardIt> uninitialized_move_n(InputIt, Size, ForwardIt); 16 17#include <memory> 18#include <cstdlib> 19#include <cassert> 20 21#include "test_macros.h" 22#include "test_iterators.h" 23 24struct Counted { 25 static int count; 26 static int constructed; 27 static void reset() { count = constructed = 0; } 28 explicit Counted(int&& x) : value(x) { x = 0; ++count; ++constructed; } 29 Counted(Counted const&) { assert(false); } 30 ~Counted() { assert(count > 0); --count; } 31 friend void operator&(Counted) = delete; 32 int value; 33}; 34int Counted::count = 0; 35int Counted::constructed = 0; 36 37struct ThrowsCounted { 38 static int count; 39 static int constructed; 40 static int throw_after; 41 static void reset() { throw_after = count = constructed = 0; } 42 explicit ThrowsCounted(int&& x) { 43 ++constructed; 44 if (throw_after > 0 && --throw_after == 0) { 45 TEST_THROW(1); 46 } 47 ++count; 48 x = 0; 49 } 50 ThrowsCounted(ThrowsCounted const&) { assert(false); } 51 ~ThrowsCounted() { assert(count > 0); --count; } 52 friend void operator&(ThrowsCounted) = delete; 53}; 54int ThrowsCounted::count = 0; 55int ThrowsCounted::constructed = 0; 56int ThrowsCounted::throw_after = 0; 57 58void test_ctor_throws() 59{ 60#ifndef TEST_HAS_NO_EXCEPTIONS 61 using It = forward_iterator<ThrowsCounted*>; 62 const int N = 5; 63 int values[N] = {1, 2, 3, 4, 5}; 64 alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {}; 65 ThrowsCounted* p = (ThrowsCounted*)pool; 66 try { 67 ThrowsCounted::throw_after = 4; 68 std::uninitialized_move_n(values, N, It(p)); 69 assert(false); 70 } catch (...) {} 71 assert(ThrowsCounted::count == 0); 72 assert(ThrowsCounted::constructed == 4); // forth construction throws 73 assert(values[0] == 0); 74 assert(values[1] == 0); 75 assert(values[2] == 0); 76 assert(values[3] == 4); 77 assert(values[4] == 5); 78#endif 79} 80 81void test_counted() 82{ 83 using It = input_iterator<int*>; 84 using FIt = forward_iterator<Counted*>; 85 const int N = 5; 86 int values[N] = {1, 2, 3, 4, 5}; 87 alignas(Counted) char pool[sizeof(Counted)*N] = {}; 88 Counted* p = (Counted*)pool; 89 auto ret = std::uninitialized_move_n(It(values), 1, FIt(p)); 90 assert(ret.first == It(values +1)); 91 assert(ret.second == FIt(p +1)); 92 assert(Counted::constructed == 1); 93 assert(Counted::count == 1); 94 assert(p[0].value == 1); 95 assert(values[0] == 0); 96 ret = std::uninitialized_move_n(It(values+1), N-1, FIt(p+1)); 97 assert(ret.first == It(values+N)); 98 assert(ret.second == FIt(p + N)); 99 assert(Counted::count == 5); 100 assert(Counted::constructed == 5); 101 assert(p[1].value == 2); 102 assert(p[2].value == 3); 103 assert(p[3].value == 4); 104 assert(p[4].value == 5); 105 assert(values[1] == 0); 106 assert(values[2] == 0); 107 assert(values[3] == 0); 108 assert(values[4] == 0); 109 std::destroy(p, p+N); 110 assert(Counted::count == 0); 111} 112 113int main() 114{ 115 test_counted(); 116 test_ctor_throws(); 117}