Skip to content

Commit a695262

Browse files
committed
Add uninitialized_relocate_backward
1 parent 3308a96 commit a695262

File tree

3 files changed

+55
-8
lines changed

3 files changed

+55
-8
lines changed

source/containers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ target_sources(containers_test PRIVATE
240240
test/algorithms/partition.cpp
241241
test/algorithms/set.cpp
242242
test/algorithms/split.cpp
243+
test/algorithms/uninitialized.cpp
243244
test/algorithms/zip.cpp
244245
test/append.cpp
245246
test/array.cpp

source/containers/algorithms/uninitialized.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ export module containers.algorithms.uninitialized;
1212
import containers.algorithms.destroy_range;
1313
import containers.algorithms.copy_or_relocate_from;
1414
import containers.begin_end;
15+
import containers.bidirectional_iterator;
16+
import containers.bidirectional_range;
1517
import containers.data;
1618
import containers.iter_difference_t;
1719
import containers.iter_value_t;
@@ -91,22 +93,37 @@ export constexpr auto uninitialized_copy_no_overlap = []<range InputRange, itera
9193
}
9294
};
9395

96+
constexpr auto relocate_from(auto & it) {
97+
return [&] {
98+
if constexpr (std::is_reference_v<decltype(*it)>) {
99+
return bounded::relocate(*it);
100+
} else {
101+
return *it;
102+
}
103+
};
104+
}
105+
94106
export constexpr auto uninitialized_relocate = [](range auto && input, iterator auto output) {
95107
auto const last = containers::end(OPERATORS_FORWARD(input));
96108
for (auto it = containers::begin(OPERATORS_FORWARD(input)); it != last; ++it) {
97-
bounded::construct_at(*output, [&] {
98-
if constexpr (std::is_reference_v<decltype(*it)>) {
99-
return bounded::relocate(*it);
100-
} else {
101-
return *it;
102-
}
103-
});
109+
bounded::construct_at(*output, ::containers::relocate_from(it));
104110
++output;
105111
}
106112
return output;
107113
};
108114

109-
export constexpr auto uninitialized_relocate_no_overlap = []<range InputRange, iterator OutputIterator>(InputRange && source, OutputIterator out) {
115+
export constexpr auto uninitialized_relocate_backward = [](bidirectional_range auto && input, bidirectional_iterator auto output_last) {
116+
auto const first = containers::begin(OPERATORS_FORWARD(input));
117+
auto last = containers::end(OPERATORS_FORWARD(input));
118+
while (last != first) {
119+
--last;
120+
--output_last;
121+
bounded::construct_at(*output_last, ::containers::relocate_from(last));
122+
}
123+
return output_last;
124+
};
125+
126+
export constexpr auto uninitialized_relocate_no_overlap = []<range InputRange, iterator OutputIterator>(InputRange && source, OutputIterator out) -> OutputIterator {
110127
if constexpr (memcpyable<InputRange, OutputIterator>) {
111128
auto result = uninitialized_copy_no_overlap(source, out);
112129
::containers::destroy_range(source);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright David Stone 2023.
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// (See accompanying file LICENSE_1_0.txt or copy at
4+
// http://www.boost.org/LICENSE_1_0.txt)
5+
6+
export module containers.test.algorithms.uninitialized;
7+
8+
import containers.algorithms.uninitialized;
9+
10+
import containers.array;
11+
import containers.begin_end;
12+
import containers.subrange;
13+
14+
import bounded;
15+
16+
using namespace bounded::literal;
17+
18+
constexpr auto check_relocate_backward() {
19+
auto source = containers::array{0_bi, 1_bi, 2_bi, 3_bi};
20+
bounded::destroy(source[3_bi]);
21+
containers::uninitialized_relocate_backward(
22+
containers::subrange(containers::begin(source), containers::begin(source) + 3_bi),
23+
containers::end(source)
24+
);
25+
bounded::construct_at(source[0_bi], [] { return 3_bi; });
26+
constexpr auto expected = containers::array{3_bi, 0_bi, 1_bi, 2_bi};
27+
return source == expected;
28+
}
29+
static_assert(check_relocate_backward());

0 commit comments

Comments
 (0)