1// -*- C++ -*- 2//===-- glue_memory_impl.h ------------------------------------------------===// 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#ifndef _PSTL_GLUE_MEMORY_IMPL_H 11#define _PSTL_GLUE_MEMORY_IMPL_H 12 13#include "utils.h" 14#include "algorithm_fwd.h" 15 16namespace std 17{ 18 19// [uninitialized.copy] 20 21template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator> 22__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 23uninitialized_copy(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result) 24{ 25 typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; 26 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; 27 typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; 28 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; 29 using namespace __pstl; 30 31 const auto __is_parallel = 32 __internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec); 33 const auto __is_vector = 34 __internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec); 35 36 return __internal::__invoke_if_else( 37 std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), 38 [&]() { 39 return __internal::__pattern_walk2_brick( 40 std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, 41 [__is_vector](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) { 42 return __internal::__brick_copy(__begin, __end, __res, __is_vector); 43 }, 44 __is_parallel); 45 }, 46 [&]() { 47 return __internal::__pattern_walk2(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, 48 [](_ReferenceType1 __val1, _ReferenceType2 __val2) { 49 ::new (std::addressof(__val2)) _ValueType2(__val1); 50 }, 51 __is_vector, __is_parallel); 52 }); 53} 54 55template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator> 56__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 57uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result) 58{ 59 typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; 60 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; 61 typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; 62 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; 63 using namespace __pstl; 64 65 const auto __is_parallel = 66 __internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec); 67 const auto __is_vector = 68 __internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec); 69 70 return __internal::__invoke_if_else( 71 std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), 72 [&]() { 73 return __internal::__pattern_walk2_brick_n( 74 std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, 75 [__is_vector](_InputIterator __begin, _Size __sz, _ForwardIterator __res) { 76 return __internal::__brick_copy_n(__begin, __sz, __res, __is_vector); 77 }, 78 __is_parallel); 79 }, 80 [&]() { 81 return __internal::__pattern_walk2_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, 82 [](_ReferenceType1 __val1, _ReferenceType2 __val2) { 83 ::new (std::addressof(__val2)) _ValueType2(__val1); 84 }, 85 __is_vector, __is_parallel); 86 }); 87} 88 89// [uninitialized.move] 90 91template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator> 92__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 93uninitialized_move(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result) 94{ 95 typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; 96 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; 97 typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; 98 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; 99 using namespace __pstl; 100 101 const auto __is_parallel = 102 __internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec); 103 const auto __is_vector = 104 __internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec); 105 106 return __internal::__invoke_if_else( 107 std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), 108 [&]() { 109 return __internal::__pattern_walk2_brick( 110 std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, 111 [__is_vector](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) { 112 return __internal::__brick_copy(__begin, __end, __res, __is_vector); 113 }, 114 __is_parallel); 115 }, 116 [&]() { 117 return __internal::__pattern_walk2(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, 118 [](_ReferenceType1 __val1, _ReferenceType2 __val2) { 119 ::new (std::addressof(__val2)) _ValueType2(std::move(__val1)); 120 }, 121 __is_vector, __is_parallel); 122 }); 123} 124 125template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator> 126__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 127uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result) 128{ 129 typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; 130 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; 131 typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; 132 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; 133 using namespace __pstl; 134 135 const auto __is_parallel = 136 __internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec); 137 const auto __is_vector = 138 __internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec); 139 140 return __internal::__invoke_if_else( 141 std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), 142 [&]() { 143 return __internal::__pattern_walk2_brick_n( 144 std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, 145 [__is_vector](_InputIterator __begin, _Size __sz, _ForwardIterator __res) { 146 return __internal::__brick_copy_n(__begin, __sz, __res, __is_vector); 147 }, 148 __is_parallel); 149 }, 150 [&]() { 151 return __internal::__pattern_walk2_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, 152 [](_ReferenceType1 __val1, _ReferenceType2 __val2) { 153 ::new (std::addressof(__val2)) _ValueType2(std::move(__val1)); 154 }, 155 __is_vector, __is_parallel); 156 }); 157} 158 159// [uninitialized.fill] 160 161template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> 162__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 163uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) 164{ 165 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 166 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; 167 using namespace __pstl; 168 169 const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 170 const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 171 172 __internal::__invoke_if_else(std::is_arithmetic<_ValueType>(), 173 [&]() { 174 __internal::__pattern_walk_brick( 175 std::forward<_ExecutionPolicy>(__exec), __first, __last, 176 [&__value, &__is_vector](_ForwardIterator __begin, _ForwardIterator __end) { 177 __internal::__brick_fill(__begin, __end, _ValueType(__value), __is_vector); 178 }, 179 __is_parallel); 180 }, 181 [&]() { 182 __internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, 183 __last, 184 [&__value](_ReferenceType __val) { 185 ::new (std::addressof(__val)) _ValueType(__value); 186 }, 187 __is_vector, __is_parallel); 188 }); 189} 190 191template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp> 192__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 193uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, const _Tp& __value) 194{ 195 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 196 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; 197 using namespace __pstl; 198 199 const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 200 const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 201 202 return __internal::__invoke_if_else( 203 std::is_arithmetic<_ValueType>(), 204 [&]() { 205 return __internal::__pattern_walk_brick_n( 206 std::forward<_ExecutionPolicy>(__exec), __first, __n, 207 [&__value, &__is_vector](_ForwardIterator __begin, _Size __count) { 208 return __internal::__brick_fill_n(__begin, __count, _ValueType(__value), __is_vector); 209 }, 210 __is_parallel); 211 }, 212 [&]() { 213 return __internal::__pattern_walk1_n( 214 std::forward<_ExecutionPolicy>(__exec), __first, __n, 215 [&__value](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(__value); }, __is_vector, 216 __is_parallel); 217 }); 218} 219 220// [specialized.destroy] 221 222template <class _ExecutionPolicy, class _ForwardIterator> 223__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 224destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) 225{ 226 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 227 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; 228 using namespace __pstl; 229 230 const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 231 const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 232 233 __internal::__invoke_if_not(std::is_trivially_destructible<_ValueType>(), [&]() { 234 __internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last, 235 [](_ReferenceType __val) { __val.~_ValueType(); }, __is_vector, __is_parallel); 236 }); 237} 238 239template <class _ExecutionPolicy, class _ForwardIterator, class _Size> 240__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 241destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) 242{ 243 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 244 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; 245 using namespace __pstl; 246 247 const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 248 const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 249 250 return __internal::__invoke_if_else( 251 std::is_trivially_destructible<_ValueType>(), [&]() { return std::next(__first, __n); }, 252 [&]() { 253 return __internal::__pattern_walk1_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, 254 [](_ReferenceType __val) { __val.~_ValueType(); }, __is_vector, 255 __is_parallel); 256 }); 257} 258 259// [uninitialized.construct.default] 260 261template <class _ExecutionPolicy, class _ForwardIterator> 262__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 263uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) 264{ 265 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 266 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; 267 using namespace __pstl; 268 269 const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 270 const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 271 272 __internal::__invoke_if_not(std::is_trivial<_ValueType>(), [&]() { 273 __internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last, 274 [](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; }, __is_vector, 275 __is_parallel); 276 }); 277} 278 279template <class _ExecutionPolicy, class _ForwardIterator, class _Size> 280__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 281uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) 282{ 283 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 284 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; 285 using namespace __pstl; 286 287 const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 288 const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 289 290 return __internal::__invoke_if_else(std::is_trivial<_ValueType>(), [&]() { return std::next(__first, __n); }, 291 [&]() { 292 return __internal::__pattern_walk1_n( 293 std::forward<_ExecutionPolicy>(__exec), __first, __n, 294 [](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; }, 295 __is_vector, __is_parallel); 296 }); 297} 298 299// [uninitialized.construct.value] 300 301template <class _ExecutionPolicy, class _ForwardIterator> 302__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 303uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) 304{ 305 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 306 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; 307 using namespace __pstl; 308 309 const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 310 const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 311 312 __internal::__invoke_if_else( 313 std::is_trivial<_ValueType>(), 314 [&]() { 315 __internal::__pattern_walk_brick(std::forward<_ExecutionPolicy>(__exec), __first, __last, 316 [__is_vector](_ForwardIterator __begin, _ForwardIterator __end) { 317 __internal::__brick_fill(__begin, __end, _ValueType(), __is_vector); 318 }, 319 __is_parallel); 320 }, 321 [&]() { 322 __internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last, 323 [](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(); }, 324 __is_vector, __is_parallel); 325 }); 326} 327 328template <class _ExecutionPolicy, class _ForwardIterator, class _Size> 329__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 330uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) 331{ 332 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 333 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; 334 using namespace __pstl; 335 336 const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 337 const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); 338 339 return __internal::__invoke_if_else( 340 std::is_trivial<_ValueType>(), 341 [&]() { 342 return __internal::__pattern_walk_brick_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, 343 [__is_vector](_ForwardIterator __begin, _Size __count) { 344 return __internal::__brick_fill_n(__begin, __count, 345 _ValueType(), __is_vector); 346 }, 347 __is_parallel); 348 }, 349 [&]() { 350 return __internal::__pattern_walk1_n( 351 std::forward<_ExecutionPolicy>(__exec), __first, __n, 352 [](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(); }, __is_vector, __is_parallel); 353 }); 354} 355 356} // namespace std 357 358#endif /* _PSTL_GLUE_MEMORY_IMPL_H */ 359