Home | History | Annotate | Download | only in uninitialized.construct.value
      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