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