You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

575 lines
18KB

  1. // Raw memory manipulators -*- C++ -*-
  2. // Copyright (C) 2020 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file bits/ranges_uninitialized.h
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{memory}
  23. */
  24. #ifndef _RANGES_UNINITIALIZED_H
  25. #define _RANGES_UNINITIALIZED_H 1
  26. #if __cplusplus > 201703L
  27. #if __cpp_lib_concepts
  28. #include <bits/ranges_algobase.h>
  29. namespace std _GLIBCXX_VISIBILITY(default)
  30. {
  31. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  32. namespace ranges
  33. {
  34. namespace __detail
  35. {
  36. template<typename _Tp>
  37. constexpr void*
  38. __voidify(_Tp& __obj) noexcept
  39. {
  40. return const_cast<void*>
  41. (static_cast<const volatile void*>(std::__addressof(__obj)));
  42. }
  43. template<typename _Iter>
  44. concept __nothrow_input_iterator
  45. = (input_iterator<_Iter>
  46. && is_lvalue_reference_v<iter_reference_t<_Iter>>
  47. && same_as<remove_cvref_t<iter_reference_t<_Iter>>,
  48. iter_value_t<_Iter>>);
  49. template<typename _Sent, typename _Iter>
  50. concept __nothrow_sentinel = sentinel_for<_Sent, _Iter>;
  51. template<typename _Range>
  52. concept __nothrow_input_range
  53. = (range<_Range>
  54. && __nothrow_input_iterator<iterator_t<_Range>>
  55. && __nothrow_sentinel<sentinel_t<_Range>, iterator_t<_Range>>);
  56. template<typename _Iter>
  57. concept __nothrow_forward_iterator
  58. = (__nothrow_input_iterator<_Iter>
  59. && forward_iterator<_Iter>
  60. && __nothrow_sentinel<_Iter, _Iter>);
  61. template<typename _Range>
  62. concept __nothrow_forward_range
  63. = (__nothrow_input_range<_Range>
  64. && __nothrow_forward_iterator<iterator_t<_Range>>);
  65. } // namespace __detail
  66. struct __destroy_fn
  67. {
  68. template<__detail::__nothrow_input_iterator _Iter,
  69. __detail::__nothrow_sentinel<_Iter> _Sent>
  70. requires destructible<iter_value_t<_Iter>>
  71. constexpr _Iter
  72. operator()(_Iter __first, _Sent __last) const noexcept;
  73. template<__detail::__nothrow_input_range _Range>
  74. requires destructible<range_value_t<_Range>>
  75. constexpr borrowed_iterator_t<_Range>
  76. operator()(_Range&& __r) const noexcept;
  77. };
  78. inline constexpr __destroy_fn destroy{};
  79. namespace __detail
  80. {
  81. template<typename _Iter>
  82. requires destructible<iter_value_t<_Iter>>
  83. struct _DestroyGuard
  84. {
  85. private:
  86. _Iter _M_first;
  87. const _Iter* _M_cur;
  88. public:
  89. explicit
  90. _DestroyGuard(const _Iter* __iter)
  91. : _M_first(*__iter), _M_cur(__iter)
  92. { }
  93. void
  94. release() noexcept
  95. { _M_cur = nullptr; }
  96. ~_DestroyGuard()
  97. {
  98. if (_M_cur != nullptr)
  99. ranges::destroy(std::move(_M_first), *_M_cur);
  100. }
  101. };
  102. template<typename _Iter>
  103. requires destructible<iter_value_t<_Iter>>
  104. && is_trivially_destructible_v<iter_value_t<_Iter>>
  105. struct _DestroyGuard<_Iter>
  106. {
  107. explicit
  108. _DestroyGuard(const _Iter*)
  109. { }
  110. void
  111. release() noexcept
  112. { }
  113. };
  114. } // namespace __detail
  115. struct __uninitialized_default_construct_fn
  116. {
  117. template<__detail::__nothrow_forward_iterator _Iter,
  118. __detail::__nothrow_sentinel<_Iter> _Sent>
  119. requires default_initializable<iter_value_t<_Iter>>
  120. _Iter
  121. operator()(_Iter __first, _Sent __last) const
  122. {
  123. using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
  124. if constexpr (is_trivially_default_constructible_v<_ValueType>)
  125. return ranges::next(__first, __last);
  126. else
  127. {
  128. auto __guard = __detail::_DestroyGuard(&__first);
  129. for (; __first != __last; ++__first)
  130. ::new (__detail::__voidify(*__first)) _ValueType;
  131. __guard.release();
  132. return __first;
  133. }
  134. }
  135. template<__detail::__nothrow_forward_range _Range>
  136. requires default_initializable<range_value_t<_Range>>
  137. borrowed_iterator_t<_Range>
  138. operator()(_Range&& __r) const
  139. {
  140. return (*this)(ranges::begin(__r), ranges::end(__r));
  141. }
  142. };
  143. inline constexpr __uninitialized_default_construct_fn
  144. uninitialized_default_construct{};
  145. struct __uninitialized_default_construct_n_fn
  146. {
  147. template<__detail::__nothrow_forward_iterator _Iter>
  148. requires default_initializable<iter_value_t<_Iter>>
  149. _Iter
  150. operator()(_Iter __first, iter_difference_t<_Iter> __n) const
  151. {
  152. using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
  153. if constexpr (is_trivially_default_constructible_v<_ValueType>)
  154. return ranges::next(__first, __n);
  155. else
  156. {
  157. auto __guard = __detail::_DestroyGuard(&__first);
  158. for (; __n > 0; ++__first, (void) --__n)
  159. ::new (__detail::__voidify(*__first)) _ValueType;
  160. __guard.release();
  161. return __first;
  162. }
  163. }
  164. };
  165. inline constexpr __uninitialized_default_construct_n_fn
  166. uninitialized_default_construct_n;
  167. struct __uninitialized_value_construct_fn
  168. {
  169. template<__detail::__nothrow_forward_iterator _Iter,
  170. __detail::__nothrow_sentinel<_Iter> _Sent>
  171. requires default_initializable<iter_value_t<_Iter>>
  172. _Iter
  173. operator()(_Iter __first, _Sent __last) const
  174. {
  175. using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
  176. if constexpr (is_trivial_v<_ValueType>
  177. && is_copy_assignable_v<_ValueType>)
  178. return ranges::fill(__first, __last, _ValueType());
  179. else
  180. {
  181. auto __guard = __detail::_DestroyGuard(&__first);
  182. for (; __first != __last; ++__first)
  183. ::new (__detail::__voidify(*__first)) _ValueType();
  184. __guard.release();
  185. return __first;
  186. }
  187. }
  188. template<__detail::__nothrow_forward_range _Range>
  189. requires default_initializable<range_value_t<_Range>>
  190. borrowed_iterator_t<_Range>
  191. operator()(_Range&& __r) const
  192. {
  193. return (*this)(ranges::begin(__r), ranges::end(__r));
  194. }
  195. };
  196. inline constexpr __uninitialized_value_construct_fn
  197. uninitialized_value_construct{};
  198. struct __uninitialized_value_construct_n_fn
  199. {
  200. template<__detail::__nothrow_forward_iterator _Iter>
  201. requires default_initializable<iter_value_t<_Iter>>
  202. _Iter
  203. operator()(_Iter __first, iter_difference_t<_Iter> __n) const
  204. {
  205. using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
  206. if constexpr (is_trivial_v<_ValueType>
  207. && is_copy_assignable_v<_ValueType>)
  208. return ranges::fill_n(__first, __n, _ValueType());
  209. else
  210. {
  211. auto __guard = __detail::_DestroyGuard(&__first);
  212. for (; __n > 0; ++__first, (void) --__n)
  213. ::new (__detail::__voidify(*__first)) _ValueType();
  214. __guard.release();
  215. return __first;
  216. }
  217. }
  218. };
  219. inline constexpr __uninitialized_value_construct_n_fn
  220. uninitialized_value_construct_n;
  221. template<typename _Iter, typename _Out>
  222. using uninitialized_copy_result = in_out_result<_Iter, _Out>;
  223. struct __uninitialized_copy_fn
  224. {
  225. template<input_iterator _Iter, sentinel_for<_Iter> _ISent,
  226. __detail::__nothrow_forward_iterator _Out,
  227. __detail::__nothrow_sentinel<_Out> _OSent>
  228. requires constructible_from<iter_value_t<_Out>, iter_reference_t<_Iter>>
  229. uninitialized_copy_result<_Iter, _Out>
  230. operator()(_Iter __ifirst, _ISent __ilast,
  231. _Out __ofirst, _OSent __olast) const
  232. {
  233. using _OutType = remove_reference_t<iter_reference_t<_Out>>;
  234. if constexpr (sized_sentinel_for<_ISent, _Iter>
  235. && sized_sentinel_for<_OSent, _Out>
  236. && is_trivial_v<_OutType>
  237. && is_nothrow_assignable_v<_OutType&,
  238. iter_reference_t<_Iter>>)
  239. {
  240. auto __d1 = __ilast - __ifirst;
  241. auto __d2 = __olast - __ofirst;
  242. return ranges::copy_n(std::move(__ifirst), std::min(__d1, __d2),
  243. __ofirst);
  244. }
  245. else
  246. {
  247. auto __guard = __detail::_DestroyGuard(&__ofirst);
  248. for (; __ifirst != __ilast && __ofirst != __olast;
  249. ++__ofirst, (void)++__ifirst)
  250. ::new (__detail::__voidify(*__ofirst)) _OutType(*__ifirst);
  251. __guard.release();
  252. return {std::move(__ifirst), __ofirst};
  253. }
  254. }
  255. template<input_range _IRange, __detail::__nothrow_forward_range _ORange>
  256. requires constructible_from<range_value_t<_ORange>,
  257. range_reference_t<_IRange>>
  258. uninitialized_copy_result<borrowed_iterator_t<_IRange>,
  259. borrowed_iterator_t<_ORange>>
  260. operator()(_IRange&& __inr, _ORange&& __outr) const
  261. {
  262. return (*this)(ranges::begin(__inr), ranges::end(__inr),
  263. ranges::begin(__outr), ranges::end(__outr));
  264. }
  265. };
  266. inline constexpr __uninitialized_copy_fn uninitialized_copy{};
  267. template<typename _Iter, typename _Out>
  268. using uninitialized_copy_n_result = in_out_result<_Iter, _Out>;
  269. struct __uninitialized_copy_n_fn
  270. {
  271. template<input_iterator _Iter, __detail::__nothrow_forward_iterator _Out,
  272. __detail::__nothrow_sentinel<_Out> _Sent>
  273. requires constructible_from<iter_value_t<_Out>, iter_reference_t<_Iter>>
  274. uninitialized_copy_n_result<_Iter, _Out>
  275. operator()(_Iter __ifirst, iter_difference_t<_Iter> __n,
  276. _Out __ofirst, _Sent __olast) const
  277. {
  278. using _OutType = remove_reference_t<iter_reference_t<_Out>>;
  279. if constexpr (sized_sentinel_for<_Sent, _Out>
  280. && is_trivial_v<_OutType>
  281. && is_nothrow_assignable_v<_OutType&,
  282. iter_reference_t<_Iter>>)
  283. {
  284. auto __d = __olast - __ofirst;
  285. return ranges::copy_n(std::move(__ifirst), std::min(__n, __d),
  286. __ofirst);
  287. }
  288. else
  289. {
  290. auto __guard = __detail::_DestroyGuard(&__ofirst);
  291. for (; __n > 0 && __ofirst != __olast;
  292. ++__ofirst, (void)++__ifirst, (void)--__n)
  293. ::new (__detail::__voidify(*__ofirst)) _OutType(*__ifirst);
  294. __guard.release();
  295. return {std::move(__ifirst), __ofirst};
  296. }
  297. }
  298. };
  299. inline constexpr __uninitialized_copy_n_fn uninitialized_copy_n{};
  300. template<typename _Iter, typename _Out>
  301. using uninitialized_move_result = in_out_result<_Iter, _Out>;
  302. struct __uninitialized_move_fn
  303. {
  304. template<input_iterator _Iter, sentinel_for<_Iter> _ISent,
  305. __detail::__nothrow_forward_iterator _Out,
  306. __detail::__nothrow_sentinel<_Out> _OSent>
  307. requires constructible_from<iter_value_t<_Out>,
  308. iter_rvalue_reference_t<_Iter>>
  309. uninitialized_move_result<_Iter, _Out>
  310. operator()(_Iter __ifirst, _ISent __ilast,
  311. _Out __ofirst, _OSent __olast) const
  312. {
  313. using _OutType = remove_reference_t<iter_reference_t<_Out>>;
  314. if constexpr (sized_sentinel_for<_ISent, _Iter>
  315. && sized_sentinel_for<_OSent, _Out>
  316. && is_trivial_v<_OutType>
  317. && is_nothrow_assignable_v<_OutType&,
  318. iter_rvalue_reference_t<_Iter>>)
  319. {
  320. auto __d1 = __ilast - __ifirst;
  321. auto __d2 = __olast - __ofirst;
  322. auto [__in, __out]
  323. = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
  324. std::min(__d1, __d2), __ofirst);
  325. return {std::move(__in).base(), __out};
  326. }
  327. else
  328. {
  329. auto __guard = __detail::_DestroyGuard(&__ofirst);
  330. for (; __ifirst != __ilast && __ofirst != __olast;
  331. ++__ofirst, (void)++__ifirst)
  332. ::new (__detail::__voidify(*__ofirst))
  333. _OutType(ranges::iter_move(__ifirst));
  334. __guard.release();
  335. return {std::move(__ifirst), __ofirst};
  336. }
  337. }
  338. template<input_range _IRange, __detail::__nothrow_forward_range _ORange>
  339. requires constructible_from<range_value_t<_ORange>,
  340. range_rvalue_reference_t<_IRange>>
  341. uninitialized_move_result<borrowed_iterator_t<_IRange>,
  342. borrowed_iterator_t<_ORange>>
  343. operator()(_IRange&& __inr, _ORange&& __outr) const
  344. {
  345. return (*this)(ranges::begin(__inr), ranges::end(__inr),
  346. ranges::begin(__outr), ranges::end(__outr));
  347. }
  348. };
  349. inline constexpr __uninitialized_move_fn uninitialized_move{};
  350. template<typename _Iter, typename _Out>
  351. using uninitialized_move_n_result = in_out_result<_Iter, _Out>;
  352. struct __uninitialized_move_n_fn
  353. {
  354. template<input_iterator _Iter, __detail::__nothrow_forward_iterator _Out,
  355. __detail::__nothrow_sentinel<_Out> _Sent>
  356. requires constructible_from<iter_value_t<_Out>,
  357. iter_rvalue_reference_t<_Iter>>
  358. uninitialized_move_n_result<_Iter, _Out>
  359. operator()(_Iter __ifirst, iter_difference_t<_Iter> __n,
  360. _Out __ofirst, _Sent __olast) const
  361. {
  362. using _OutType = remove_reference_t<iter_reference_t<_Out>>;
  363. if constexpr (sized_sentinel_for<_Sent, _Out>
  364. && is_trivial_v<_OutType>
  365. && is_nothrow_assignable_v<_OutType&,
  366. iter_rvalue_reference_t<_Iter>>)
  367. {
  368. auto __d = __olast - __ofirst;
  369. auto [__in, __out]
  370. = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
  371. std::min(__n, __d), __ofirst);
  372. return {std::move(__in).base(), __out};
  373. }
  374. else
  375. {
  376. auto __guard = __detail::_DestroyGuard(&__ofirst);
  377. for (; __n > 0 && __ofirst != __olast;
  378. ++__ofirst, (void)++__ifirst, (void)--__n)
  379. ::new (__detail::__voidify(*__ofirst))
  380. _OutType(ranges::iter_move(__ifirst));
  381. __guard.release();
  382. return {std::move(__ifirst), __ofirst};
  383. }
  384. }
  385. };
  386. inline constexpr __uninitialized_move_n_fn uninitialized_move_n{};
  387. struct __uninitialized_fill_fn
  388. {
  389. template<__detail::__nothrow_forward_iterator _Iter,
  390. __detail::__nothrow_sentinel<_Iter> _Sent, typename _Tp>
  391. requires constructible_from<iter_value_t<_Iter>, const _Tp&>
  392. _Iter
  393. operator()(_Iter __first, _Sent __last, const _Tp& __x) const
  394. {
  395. using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
  396. if constexpr (is_trivial_v<_ValueType>
  397. && is_nothrow_assignable_v<_ValueType&, const _Tp&>)
  398. return ranges::fill(__first, __last, __x);
  399. else
  400. {
  401. auto __guard = __detail::_DestroyGuard(&__first);
  402. for (; __first != __last; ++__first)
  403. ::new (__detail::__voidify(*__first)) _ValueType(__x);
  404. __guard.release();
  405. return __first;
  406. }
  407. }
  408. template<__detail::__nothrow_forward_range _Range, typename _Tp>
  409. requires constructible_from<range_value_t<_Range>, const _Tp&>
  410. borrowed_iterator_t<_Range>
  411. operator()(_Range&& __r, const _Tp& __x) const
  412. {
  413. return (*this)(ranges::begin(__r), ranges::end(__r), __x);
  414. }
  415. };
  416. inline constexpr __uninitialized_fill_fn uninitialized_fill{};
  417. struct __uninitialized_fill_n_fn
  418. {
  419. template<__detail::__nothrow_forward_iterator _Iter, typename _Tp>
  420. requires constructible_from<iter_value_t<_Iter>, const _Tp&>
  421. _Iter
  422. operator()(_Iter __first, iter_difference_t<_Iter> __n,
  423. const _Tp& __x) const
  424. {
  425. using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
  426. if constexpr (is_trivial_v<_ValueType>
  427. && is_nothrow_assignable_v<_ValueType&, const _Tp&>)
  428. return ranges::fill_n(__first, __n, __x);
  429. else
  430. {
  431. auto __guard = __detail::_DestroyGuard(&__first);
  432. for (; __n > 0; ++__first, (void)--__n)
  433. ::new (__detail::__voidify(*__first)) _ValueType(__x);
  434. __guard.release();
  435. return __first;
  436. }
  437. }
  438. };
  439. inline constexpr __uninitialized_fill_n_fn uninitialized_fill_n{};
  440. struct __construct_at_fn
  441. {
  442. template<typename _Tp, typename... _Args>
  443. requires requires {
  444. ::new (std::declval<void*>()) _Tp(std::declval<_Args>()...);
  445. }
  446. constexpr _Tp*
  447. operator()(_Tp* __location, _Args&&... __args) const
  448. noexcept(noexcept(std::construct_at(__location,
  449. std::forward<_Args>(__args)...)))
  450. {
  451. return std::construct_at(__location,
  452. std::forward<_Args>(__args)...);
  453. }
  454. };
  455. inline constexpr __construct_at_fn construct_at{};
  456. struct __destroy_at_fn
  457. {
  458. template<destructible _Tp>
  459. constexpr void
  460. operator()(_Tp* __location) const noexcept
  461. {
  462. if constexpr (is_array_v<_Tp>)
  463. ranges::destroy(ranges::begin(*__location), ranges::end(*__location));
  464. else
  465. __location->~_Tp();
  466. }
  467. };
  468. inline constexpr __destroy_at_fn destroy_at{};
  469. template<__detail::__nothrow_input_iterator _Iter,
  470. __detail::__nothrow_sentinel<_Iter> _Sent>
  471. requires destructible<iter_value_t<_Iter>>
  472. constexpr _Iter
  473. __destroy_fn::operator()(_Iter __first, _Sent __last) const noexcept
  474. {
  475. if constexpr (is_trivially_destructible_v<iter_value_t<_Iter>>)
  476. return ranges::next(std::move(__first), __last);
  477. else
  478. {
  479. for (; __first != __last; ++__first)
  480. ranges::destroy_at(std::__addressof(*__first));
  481. return __first;
  482. }
  483. }
  484. template<__detail::__nothrow_input_range _Range>
  485. requires destructible<range_value_t<_Range>>
  486. constexpr borrowed_iterator_t<_Range>
  487. __destroy_fn::operator()(_Range&& __r) const noexcept
  488. {
  489. return (*this)(ranges::begin(__r), ranges::end(__r));
  490. }
  491. struct __destroy_n_fn
  492. {
  493. template<__detail::__nothrow_input_iterator _Iter>
  494. requires destructible<iter_value_t<_Iter>>
  495. constexpr _Iter
  496. operator()(_Iter __first, iter_difference_t<_Iter> __n) const noexcept
  497. {
  498. if constexpr (is_trivially_destructible_v<iter_value_t<_Iter>>)
  499. return ranges::next(std::move(__first), __n);
  500. else
  501. {
  502. for (; __n > 0; ++__first, (void)--__n)
  503. ranges::destroy_at(std::__addressof(*__first));
  504. return __first;
  505. }
  506. }
  507. };
  508. inline constexpr __destroy_n_fn destroy_n{};
  509. }
  510. _GLIBCXX_END_NAMESPACE_VERSION
  511. } // namespace std
  512. #endif // concepts
  513. #endif // C++20
  514. #endif // _RANGES_UNINITIALIZED_H