@@ -40,7 +40,7 @@ template<class ElemStorage> struct DynamicStorage final {
4040
4141template <class T > struct DynamicArrayOf final {
4242 using Element = T;
43- using Size = size_t ;
43+ using Count = size_t ;
4444 using Index = size_t ;
4545
4646 using Reference = Element&;
@@ -54,84 +54,91 @@ template<class T> struct DynamicArrayOf final {
5454 ~DynamicArrayOf () noexcept (std::is_nothrow_destructible_v<Element>) { destructSlice (amendSlice ()); }
5555
5656 DynamicArrayOf (const DynamicArrayOf& o) noexcept (std::is_nothrow_copy_constructible_v<Element>)
57- : m_storage(Storage::create(o._count ))
58- , m_count(o._count ) {
57+ : m_storage(Storage::create(o.m_count ))
58+ , m_count(o.m_count ) {
5959 copyConstructSlice (m_storage.pointer , o.slice ());
6060 }
6161 DynamicArrayOf& operator =(const DynamicArrayOf& o) noexcept (std::is_nothrow_copy_assignable_v<Element>) {
62- if (m_storage.capacity < o.count () ) {
62+ if (m_storage.capacity < o.m_count ) {
6363 *this = DynamicArrayOf (o);
6464 }
6565 else {
66- auto countDiff = m_count - o._count ;
66+ auto countDiff = m_count - o.m_count ;
6767 if (countDiff > 0 ) {
68- copyAssignSlice (amendBegin (), ConstSlice{o. begin (), o. begin () + m_count} );
69- copyConstructSlice ( storageEnd (), ConstSlice{o. begin () + m_count, o. end () });
68+ copyAssignSlice (amendBegin (), o. slice () );
69+ destructSlice (Slice{ amendBegin () + o. m_count , countDiff });
7070 }
7171 else {
72- copyAssignSlice (amendBegin (), o. slice () );
73- destructSlice (Slice{ amendBegin () + o. _count , amendEnd () });
72+ copyAssignSlice (amendBegin (), ConstSlice{o. begin (), m_count} );
73+ copyConstructSlice ( storageEnd (), ConstSlice{o. begin () + m_count, -countDiff });
7474 }
75- m_count = o.count () ;
75+ m_count = o.m_count ;
7676 }
7777 }
7878
79- DynamicArrayOf (DynamicArrayOf&& o) noexcept : m_storage(std::move(o)), m_count(o._count ) { o._count = 0 ; }
79+ DynamicArrayOf (DynamicArrayOf&& o) noexcept : m_storage(std::move(o)), m_count(o.m_count ) { o.m_count = 0 ; }
8080 DynamicArrayOf& operator =(DynamicArrayOf&& o) noexcept {
8181 destructSlice (amendSlice ());
82- m_storage = std::move (o);
83- m_count = o._count ;
84- o._count = 0 ;
82+ m_storage = std::move (o. m_storage );
83+ m_count = o.m_count ;
84+ o.m_count = 0 ;
8585 }
8686
87- [[nodiscard]] auto count () const -> Size { return m_count; }
88- [[nodiscard]] auto totalCapacity () const -> Size { return m_storage.capacity ; }
89- [[nodiscard]] auto unusedCapacity () const -> Size { return m_storage.capacity - m_count; }
87+ [[nodiscard]] constexpr auto isEmpty () const noexcept -> bool { return m_count == 0 ; }
88+ [[nodiscard]] auto count () const -> Count { return m_count; }
89+ [[nodiscard]] auto totalCapacity () const -> Count { return m_storage.capacity ; }
90+ [[nodiscard]] auto unusedCapacity () const -> Count { return m_storage.capacity - m_count; }
9091
91- [[nodiscard]] auto begin () const & noexcept -> ConstIterator {
92+ [[nodiscard]] auto begin () const noexcept -> ConstIterator {
9293 return std::launder (reinterpret_cast <const T*>(m_storage.pointer ));
9394 }
9495 // NOTE: end() is not laundered!
95- [[nodiscard]] auto end () const & noexcept -> ConstIterator {
96+ [[nodiscard]] auto end () const noexcept -> ConstIterator {
9697 return reinterpret_cast <const T*>(m_storage.pointer + m_count);
9798 }
98-
99- [[nodiscard]] auto operator [](Index index) const & noexcept -> ConstReference {
99+ [[nodiscard]] auto operator [](Index index) const noexcept -> ConstReference {
100100 return *std::launder (reinterpret_cast <const T*>(m_storage.pointer + index));
101101 }
102- [[nodiscard]] operator ConstSlice () const noexcept { return ConstSlice{begin (), end () }; }
102+ [[nodiscard]] operator ConstSlice () const noexcept { return ConstSlice{begin (), m_count }; }
103103
104104 [[nodiscard]] auto amendBegin () & noexcept -> Iterator {
105105 return std::launder (reinterpret_cast <T*>(m_storage.pointer ));
106106 }
107107 // NOTE: end() is not laundered!
108108 [[nodiscard]] auto amendEnd () & noexcept -> Iterator { return amendBegin () + m_count; }
109109
110- [[nodiscard]] auto amend () -> Slice { return Slice{amendBegin (), amendEnd ()}; }
110+ [[nodiscard]] auto amend () -> Slice { return Slice{amendBegin (), m_count}; }
111+
112+ void ensureCapacity (Count count) {
113+ if (totalCapacity () < size) growBy (size - totalCapacity ());
114+ }
115+ void ensureUnusedCapacity (Count count) {
116+ if (unusedCapacity () < count) growBy (count);
117+ }
111118
112119 void append (ConstSlice elems) {
113- if ( unusedCapacity () < elems. count ()) grow (elems.count ());
120+ ensureUnusedCapacity (elems.count ());
114121 copyConstructSlice (storageEnd (), elems);
115122 m_count += elems.count ();
116123 }
117124
118125 void pop () noexcept (std::is_nothrow_destructible_v<Element>) {
119- destructSlice (Slice{amendBegin () + m_count - 1 , amendEnd () });
126+ destructSlice (Slice{amendBegin () + m_count - 1 , 1 });
120127 m_count--;
121128 }
122129
123- void splice (Iterator it, Size removeCount, ConstSlice insertSlice) {
130+ void splice (Iterator it, Count removeCount, ConstSlice insertSlice) {
124131 auto offset = it - amendBegin ();
125132 auto insertCount = insertSlice.count ();
126133 auto remainCount = m_count - offset - removeCount;
127- auto remainSlice = Slice{it + removeCount, amendEnd () };
134+ auto remainSlice = Slice{it + removeCount, remainCount };
128135 // old: [ ..(offset)..,[it] ..(removeCount).., ..(remainCount)... ]
129136 // new: [ ..(offset)..,[it] ..(insertCount).., ..(remainCount)... ]
130137
131138 auto countDiff = insertCount - removeCount;
132139 if (unusedCapacity () < countDiff) { // not enough storage => arrange everything in new storage
133140 auto newStorage = grownStorage (countDiff);
134- moveConstructSlice (newStorage.pointer , Slice{amendBegin (), it });
141+ moveConstructSlice (newStorage.pointer , Slice{amendBegin (), offset });
135142 copyConstructSlice (newStorage.pointer + offset, insertSlice);
136143 moveConstructSlice (newStorage.pointer + offset + insertCount, remainSlice);
137144 destructSlice (amendSlice ());
@@ -140,7 +147,7 @@ template<class T> struct DynamicArrayOf final {
140147 else if (countDiff <= 0 ) { // shrinking
141148 copyAssignSlice (it, insertSlice);
142149 forwardMoveConstructSlice (it + insertCount, remainSlice);
143- destructSlice (Slice{amendEnd () + countDiff, amendEnd () });
150+ destructSlice (Slice{amendEnd () + countDiff, -countDiff });
144151 }
145152 else if (offset + insertCount <= m_count) { // parts of remainSlice is moved beyond end()
146153 moveConstructSlice (storageEnd (), remainSlice.slice (remainCount - countDiff, countDiff));
@@ -165,8 +172,8 @@ template<class T> struct DynamicArrayOf final {
165172 using StorageIterator = ElementStorage*;
166173 constexpr static auto element_size = sizeof (ElementStorage);
167174
168- auto byteSize () const -> Size { return m_count * element_size; }
169- auto storageEnd () -> StorageIterator { return m_storage.pointer + m_count; }
175+ [[nodiscard]] auto byteSize () const -> size_t { return m_count * element_size; }
176+ [[nodiscard]] auto storageEnd () -> StorageIterator { return m_storage.pointer + m_count; }
170177
171178 static void destructSlice (Slice slice) {
172179 for (auto & elem : slice) elem.~Element ();
@@ -222,14 +229,14 @@ template<class T> struct DynamicArrayOf final {
222229 for (auto & from : fromSlice) new (to++) Element (std::move (from));
223230 }
224231 }
225- auto grownStorage (int growBy) const -> Size {
232+ [[nodiscard]] auto grownStorage (int growBy) const -> Storage {
226233 auto cur = totalCapacity ();
227234 auto res = (cur << 1 ) - (cur >> 1 ) + (cur >> 4 ); // * 1.563
228235 if (res < 5 ) res = 5 ;
229236 if (res < totalCapacity () + growBy) res = totalCapacity () + growBy;
230237 return Storage::create (res);
231238 }
232- void grow (int by) {
239+ void growBy (int by) {
233240 auto newStorage = grownStorage (by);
234241 moveConstructSlice (newStorage.pointer , amendSlice ());
235242 destructSlice (amendSlice ());
@@ -238,7 +245,7 @@ template<class T> struct DynamicArrayOf final {
238245
239246private:
240247 Storage m_storage;
241- Size m_count;
248+ Count m_count;
242249};
243250
244251} // namespace array19
0 commit comments