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 ForwardIt> 15 // void uninitialized_default_construct(ForwardIt, ForwardIt); 16 17 #include <memory> 18 #include <cstdlib> 19 #include <cassert> 20 21 #include "test_macros.h" 22 #include "test_iterators.h" 23 24 struct Counted { 25 static int count; 26 static int constructed; 27 static void reset() { count = constructed = 0; } 28 explicit Counted() { ++count; ++constructed; } 29 Counted(Counted const&) { assert(false); } 30 ~Counted() { --count; } 31 friend void operator&(Counted) = delete; 32 }; 33 int Counted::count = 0; 34 int Counted::constructed = 0; 35 36 37 struct 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() { 43 ++constructed; 44 if (throw_after > 0 && --throw_after == 0) { 45 TEST_THROW(1); 46 } 47 ++count; 48 } 49 ThrowsCounted(ThrowsCounted const&) { assert(false); } 50 ~ThrowsCounted() { assert(count > 0); --count; } 51 friend void operator&(ThrowsCounted) = delete; 52 }; 53 int ThrowsCounted::count = 0; 54 int ThrowsCounted::constructed = 0; 55 int ThrowsCounted::throw_after = 0; 56 57 58 void test_ctor_throws() 59 { 60 #ifndef TEST_HAS_NO_EXCEPTIONS 61 using It = forward_iterator<ThrowsCounted*>; 62 const int N = 5; 63 alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {}; 64 ThrowsCounted* p = (ThrowsCounted*)pool; 65 try { 66 ThrowsCounted::throw_after = 4; 67 std::uninitialized_default_construct(It(p), It(p+N)); 68 assert(false); 69 } catch (...) {} 70 assert(ThrowsCounted::count == 0); 71 assert(ThrowsCounted::constructed == 4); // forth construction throws 72 #endif 73 } 74 75 void test_counted() 76 { 77 using It = forward_iterator<Counted*>; 78 const int N = 5; 79 alignas(Counted) char pool[sizeof(Counted)*N] = {}; 80 Counted* p = (Counted*)pool; 81 std::uninitialized_default_construct(It(p), It(p+1)); 82 assert(Counted::count == 1); 83 assert(Counted::constructed == 1); 84 std::uninitialized_default_construct(It(p+1), It(p+N)); 85 assert(Counted::count == 5); 86 assert(Counted::constructed == 5); 87 std::destroy(p, p+N); 88 assert(Counted::count == 0); 89 } 90 91 void test_value_initialized() 92 { 93 using It = forward_iterator<int*>; 94 const int N = 5; 95 int pool[N] = {-1, -1, -1, -1, -1}; 96 int* p = pool; 97 std::uninitialized_default_construct(It(p), It(p+1)); 98 assert(pool[0] == -1); 99 assert(pool[1] == -1); 100 std::uninitialized_default_construct(It(p+1), It(p+N)); 101 assert(pool[1] == -1); 102 assert(pool[2] == -1); 103 assert(pool[3] == -1); 104 assert(pool[4] == -1); 105 } 106 107 int main() 108 { 109 test_counted(); 110 test_value_initialized(); 111 test_ctor_throws(); 112 } 113