Skip to content

Commit 3a48668

Browse files
committed
Add C++17 uninitialized storage ops
1 parent 8cedb11 commit 3a48668

File tree

1 file changed

+115
-2
lines changed

1 file changed

+115
-2
lines changed

platform/cxxsupport/mstd_memory

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,28 @@
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>
3237

38+
// Forward declarations
39+
namespace std
40+
{
41+
template <typename T1, typename T2>
42+
class pair;
43+
44+
template <class Iterator>
45+
struct iterator_traits;
46+
}
47+
3348
#ifdef __CC_ARM
3449

3550
#include <cstddef> // size_t, ptrdiff_t
@@ -60,6 +75,19 @@ T *addressof(T &arg) noexcept
6075
return reinterpret_cast<T *>(const_cast<char *>(&reinterpret_cast<const volatile char &>(arg)));
6176
}
6277

78+
// [uninitialized.copy] - ARMCC has pre-C++11 uninitialized_copy
79+
template <class InputIterator, class Size, class ForwardIterator>
80+
ForwardIterator uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result) {
81+
for ( ; n > 0; ++result, (void) ++first, --n) {
82+
::new (static_cast<void*>(addressof(*result)))
83+
typename std::iterator_traits<ForwardIterator>::value_type(*first);
84+
}
85+
86+
return result;
87+
}
88+
89+
// [uninitialized.fill] - ARMCC has pre-C++11 uninitialized_fill and uninitialized_fill_n
90+
6391
// [unique.ptr]
6492
namespace impl
6593
{
@@ -496,12 +524,97 @@ bool operator>=(nullptr_t, const unique_ptr<T, D> &x) noexcept
496524
#endif // __CC_ARM
497525

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

506619
using std::default_delete;
507620
using std::unique_ptr;

0 commit comments

Comments
 (0)