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