Skip to content

Commit 85cd3cd

Browse files
committed
Add C++17 uninitialized storage ops
1 parent f27c7ec commit 85cd3cd

File tree

1 file changed

+107
-2
lines changed

1 file changed

+107
-2
lines changed

platform/cxxsupport/mstd_memory

Lines changed: 107 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,19 @@
2323
* - For ARM C 5, C++11/14 features:
2424
* - std::align
2525
* - std::addressof
26+
* - std::uninitialized_copy_n
2627
* - std::unique_ptr, std::make_unique, std::default_delete
28+
* - For all toolchains, C++17 backports:
29+
* - mstd::uninitialized_default_construct, mstd::uninitialized_value_construct
30+
* - mstd::uninitialized_move, mstd::uninitialized_move_n
31+
* - mstd::destroy_at, mstd::destroy, mstd::destroy_n
2732
*/
2833

2934
#include <memory>
3035

3136
#include <mstd_type_traits>
37+
#include <mstd_utility> // std::pair
38+
#include <mstd_iterator> // std::iterator_traits
3239

3340
#ifdef __CC_ARM
3441

@@ -60,6 +67,19 @@ T *addressof(T &arg) noexcept
6067
return reinterpret_cast<T *>(const_cast<char *>(&reinterpret_cast<const volatile char &>(arg)));
6168
}
6269

70+
// [uninitialized.copy] - ARMCC has pre-C++11 uninitialized_copy
71+
template <class InputIterator, class Size, class ForwardIterator>
72+
ForwardIterator uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result) {
73+
for ( ; n > 0; ++result, (void) ++first, --n) {
74+
::new (static_cast<void*>(addressof(*result)))
75+
typename std::iterator_traits<ForwardIterator>::value_type(*first);
76+
}
77+
78+
return result;
79+
}
80+
81+
// [uninitialized.fill] - ARMCC has pre-C++11 uninitialized_fill and uninitialized_fill_n
82+
6383
// [unique.ptr]
6484
namespace impl
6585
{
@@ -496,12 +516,97 @@ bool operator>=(nullptr_t, const unique_ptr<T, D> &x) noexcept
496516
#endif // __CC_ARM
497517

498518
namespace mstd {
519+
using std::align;
499520
using std::allocator;
521+
using std::addressof;
522+
523+
// [uninitialized.construct.default] (C++17)
524+
template <class ForwardIterator, class Size>
525+
void uninitialized_default_construct(ForwardIterator first, ForwardIterator last) {
526+
for (; first != last; ++first) {
527+
::new (static_cast<void*>(addressof(*first)))
528+
typename std::iterator_traits<ForwardIterator>::value_type;
529+
}
530+
}
531+
532+
template <class ForwardIterator, class Size>
533+
ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n) {
534+
for (; n; ++first, --n) {
535+
::new (static_cast<void*>(addressof(*first)))
536+
typename std::iterator_traits<ForwardIterator>::value_type;
537+
}
538+
539+
return first;
540+
}
541+
542+
// [uninitialized.construct.value] (C++17)
543+
template <class ForwardIterator, class Size>
544+
void uninitialized_value_construct(ForwardIterator first, ForwardIterator last) {
545+
for (; first != last; ++first) {
546+
::new (static_cast<void*>(addressof(*first)))
547+
typename std::iterator_traits<ForwardIterator>::value_type();
548+
}
549+
}
550+
551+
template <class ForwardIterator, class Size>
552+
ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n) {
553+
for (; n; ++first, --n) {
554+
::new (static_cast<void*>(addressof(*first)))
555+
typename std::iterator_traits<ForwardIterator>::value_type();
556+
}
557+
558+
return first;
559+
}
560+
561+
// [uninitialized.move] (C++17)
562+
template <class InputIterator, class ForwardIterator>
563+
ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result) {
564+
for (; first != last; ++result, (void) ++first) {
565+
::new (static_cast<void*>(addressof(*result)))
566+
typename std::iterator_traits<ForwardIterator>::value_type(move(*first));
567+
}
568+
569+
return result;
570+
}
571+
572+
template <class InputIterator, class Size, class ForwardIterator>
573+
std::pair<InputIterator, ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result) {
574+
for ( ; n > 0; ++result, (void) ++first, --n) {
575+
::new (static_cast<void*>(addressof(*result)))
576+
typename std::iterator_traits<ForwardIterator>::value_type(std::move(*first));
577+
}
578+
579+
return { first, result };
580+
}
581+
500582
using std::uninitialized_copy;
583+
using std::uninitialized_copy_n;
501584
using std::uninitialized_fill;
502585
using std::uninitialized_fill_n;
503-
using std::addressof;
504-
using std::align;
586+
587+
// [specialized.destroy] (C++17)
588+
template <class T>
589+
void destroy_at(T *location)
590+
{
591+
location->~T();
592+
}
593+
594+
template <class ForwardIterator>
595+
void destroy(ForwardIterator first, ForwardIterator last)
596+
{
597+
for (; first != last; ++first) {
598+
destroy_at(addressof(*first));
599+
}
600+
}
601+
602+
template <class ForwardIterator, class Size>
603+
ForwardIterator destroy_n(ForwardIterator first, Size n)
604+
{
605+
for (; n > 0; (void)++first, --n) {
606+
destroy_at(addressof(*first));
607+
}
608+
return first;
609+
}
505610

506611
using std::default_delete;
507612
using std::unique_ptr;

0 commit comments

Comments
 (0)