1 // -*- C++ -*- 2 //===-- uninitialized_construct.pass.cpp ----------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 // UNSUPPORTED: c++03, c++11, c++14 11 12 // Tests for uninitialized_default_construct, uninitialized_default_construct_n, 13 // uninitialized_value_construct, uninitialized_value_construct_n 14 15 #include "support/pstl_test_config.h" 16 17 #include <execution> 18 #include <memory> 19 20 #include "support/utils.h" 21 22 using namespace TestUtils; 23 24 // function of checking correctness for uninitialized.construct.value 25 template <typename T, typename Iterator> 26 bool 27 IsCheckValueCorrectness(Iterator begin, Iterator end) 28 { 29 for (; begin != end; ++begin) 30 { 31 if (*begin != T()) 32 { 33 return false; 34 } 35 } 36 return true; 37 } 38 39 struct test_uninit_construct 40 { 41 template <typename Policy, typename Iterator> 42 void 43 operator()(Policy&& exec, Iterator begin, Iterator end, size_t n, /*is_trivial<T>=*/std::false_type) 44 { 45 typedef typename std::iterator_traits<Iterator>::value_type T; 46 // it needs for cleaning memory that was filled by default constructors in unique_ptr<T[]> p(new T[n]) 47 // and for cleaning memory after last calling of uninitialized_value_construct_n. 48 // It is important for non-trivial types 49 std::destroy_n(exec, begin, n); 50 51 // reset counter of constructors 52 T::SetCount(0); 53 // run algorithm 54 std::uninitialized_default_construct(exec, begin, end); 55 // compare counter of constructors to length of container 56 EXPECT_TRUE(T::Count() == n, "wrong uninitialized_default_construct"); 57 // destroy objects for testing new algorithms on same memory 58 std::destroy(exec, begin, end); 59 60 std::uninitialized_default_construct_n(exec, begin, n); 61 EXPECT_TRUE(T::Count() == n, "wrong uninitialized_default_construct_n"); 62 std::destroy_n(exec, begin, n); 63 64 std::uninitialized_value_construct(exec, begin, end); 65 EXPECT_TRUE(T::Count() == n, "wrong uninitialized_value_construct"); 66 std::destroy(exec, begin, end); 67 68 std::uninitialized_value_construct_n(exec, begin, n); 69 EXPECT_TRUE(T::Count() == n, "wrong uninitialized_value_construct_n"); 70 } 71 72 template <typename Policy, typename Iterator> 73 void 74 operator()(Policy&& exec, Iterator begin, Iterator end, size_t n, /*is_trivial<T>=*/std::true_type) 75 { 76 typedef typename std::iterator_traits<Iterator>::value_type T; 77 78 std::uninitialized_default_construct(exec, begin, end); 79 std::destroy(exec, begin, end); 80 81 std::uninitialized_default_construct_n(exec, begin, n); 82 std::destroy_n(exec, begin, n); 83 84 std::uninitialized_value_construct(exec, begin, end); 85 // check correctness for uninitialized.construct.value 86 EXPECT_TRUE(IsCheckValueCorrectness<T>(begin, end), "wrong uninitialized_value_construct"); 87 std::destroy(exec, begin, end); 88 89 std::uninitialized_value_construct_n(exec, begin, n); 90 EXPECT_TRUE(IsCheckValueCorrectness<T>(begin, end), "wrong uninitialized_value_construct_n"); 91 std::destroy_n(exec, begin, n); 92 } 93 }; 94 95 template <typename T> 96 void 97 test_uninit_construct_by_type() 98 { 99 std::size_t N = 100000; 100 for (size_t n = 0; n <= N; n = n <= 16 ? n + 1 : size_t(3.1415 * n)) 101 { 102 std::unique_ptr<T[]> p(new T[n]); 103 invoke_on_all_policies(test_uninit_construct(), p.get(), std::next(p.get(), n), n, std::is_trivial<T>()); 104 } 105 } 106 107 int 108 main() 109 { 110 111 // for user-defined types 112 #if !_PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN 113 test_uninit_construct_by_type<Wrapper<int32_t>>(); 114 test_uninit_construct_by_type<Wrapper<std::vector<std::string>>>(); 115 #endif 116 117 // for trivial types 118 test_uninit_construct_by_type<int8_t>(); 119 test_uninit_construct_by_type<float64_t>(); 120 121 std::cout << done() << std::endl; 122 return 0; 123 } 124