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_value_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() { assert(count > 0); --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 void test_ctor_throws() 58 { 59 #ifndef TEST_HAS_NO_EXCEPTIONS 60 using It = forward_iterator<ThrowsCounted*>; 61 const int N = 5; 62 alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {}; 63 ThrowsCounted* p = (ThrowsCounted*)pool; 64 try { 65 ThrowsCounted::throw_after = 4; 66 std::uninitialized_value_construct(It(p), It(p+N)); 67 assert(false); 68 } catch (...) {} 69 assert(ThrowsCounted::count == 0); 70 assert(ThrowsCounted::constructed == 4); // forth construction throws 71 #endif 72 } 73 74 void test_counted() 75 { 76 using It = forward_iterator<Counted*>; 77 const int N = 5; 78 alignas(Counted) char pool[sizeof(Counted)*N] = {}; 79 Counted* p = (Counted*)pool; 80 std::uninitialized_value_construct(It(p), It(p+1)); 81 assert(Counted::count == 1); 82 assert(Counted::constructed == 1); 83 std::uninitialized_value_construct(It(p+1), It(p+N)); 84 assert(Counted::count == 5); 85 assert(Counted::constructed == 5); 86 std::destroy(p, p+N); 87 assert(Counted::count == 0); 88 } 89 90 void test_value_initialized() 91 { 92 using It = forward_iterator<int*>; 93 const int N = 5; 94 int pool[N] = {-1, -1, -1, -1, -1}; 95 int* p = pool; 96 std::uninitialized_value_construct(It(p), It(p+1)); 97 assert(pool[0] == 0); 98 assert(pool[1] == -1); 99 std::uninitialized_value_construct(It(p+1), It(p+N)); 100 assert(pool[1] == 0); 101 assert(pool[2] == 0); 102 assert(pool[3] == 0); 103 assert(pool[4] == 0); 104 } 105 106 int main() 107 { 108 test_counted(); 109 test_value_initialized(); 110 test_ctor_throws(); 111 } 112