Skip to content

Commit 48c9cdd

Browse files
committed
Fix uninitialized_meow memcopy optimization
1 parent b1fbbdc commit 48c9cdd

File tree

5 files changed

+66
-2
lines changed
  • stl/inc
  • tests/std/tests
    • P0896R4_ranges_alg_uninitialized_copy_n
    • P0896R4_ranges_alg_uninitialized_copy
    • P0896R4_ranges_alg_uninitialized_move_n
    • P0896R4_ranges_alg_uninitialized_move

5 files changed

+66
-2
lines changed

stl/inc/memory

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ namespace ranges {
108108
_STL_INTERNAL_STATIC_ASSERT(constructible_from<iter_value_t<_Out>, iter_reference_t<_It>>);
109109

110110
if constexpr (is_same_v<_Se, _It> && _Ptr_copy_cat<_It, _Out>::_Really_trivial) {
111-
return _Copy_memcpy_common(_IFirst, _ILast, _OFirst, _OLast);
111+
return {_STD move(_ILast), _Copy_memcpy_common(_IFirst, _ILast, _OFirst, _OLast)};
112112
} else {
113113
_Uninitialized_backout _Backout{_STD move(_OFirst)};
114114

@@ -265,7 +265,7 @@ namespace ranges {
265265
_STL_INTERNAL_STATIC_ASSERT(constructible_from<iter_value_t<_Out>, iter_rvalue_reference_t<_It>>);
266266

267267
if constexpr (is_same_v<_Se, _It> && _Ptr_move_cat<_It, _Out>::_Really_trivial) {
268-
return _Copy_memcpy_common(_IFirst, _ILast, _OFirst, _OLast);
268+
return {_STD move(_ILast), _Copy_memcpy_common(_IFirst, _ILast, _OFirst, _OLast)};
269269
} else {
270270
_Uninitialized_backout _Backout{_STD move(_OFirst)};
271271

tests/std/tests/P0896R4_ranges_alg_uninitialized_copy/test.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,21 @@ struct throwing_test {
160160
}
161161
};
162162

163+
struct memcopy_test {
164+
static constexpr int expected_output[] = {13, 55, 12345};
165+
static constexpr int expected_input[] = {13, 55, 12345};
166+
167+
static void call() {
168+
// Validate only range overload (one is plenty since they both use the same backend)
169+
int input[] = {13, 55, 12345};
170+
int output[] = {-1, -1, -1};
171+
172+
ranges::uninitialized_copy(input, output);
173+
assert(ranges::equal(input, expected_input));
174+
assert(ranges::equal(output, expected_output));
175+
}
176+
};
177+
163178
template <test::ProxyRef IsProxy>
164179
using test_input = test::range<test::input, int_wrapper, test::Sized::no, test::CanDifference::no, test::Common::no,
165180
test::CanCompare::yes, IsProxy>;
@@ -174,4 +189,5 @@ int main() {
174189
instantiator::call<test_input<test::ProxyRef::yes>, test_output>();
175190
throwing_test::call<test_input<test::ProxyRef::no>, test_output>();
176191
throwing_test::call<test_input<test::ProxyRef::yes>, test_output>();
192+
memcopy_test::call();
177193
}

tests/std/tests/P0896R4_ranges_alg_uninitialized_copy_n/test.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,21 @@ struct throwing_test {
126126
}
127127
};
128128

129+
struct memcopy_test {
130+
static constexpr int expected_output[] = {13, 55, 12345, -1};
131+
static constexpr int expected_input[] = {13, 55, 12345, 42};
132+
133+
static void call() {
134+
// Validate only range overload (one is plenty since they both use the same backend)
135+
int input[] = {13, 55, 12345, 42};
136+
int output[] = {-1, -1, -1, -1};
137+
138+
ranges::uninitialized_copy_n(input, 3, output, output + 4);
139+
assert(ranges::equal(input, expected_input));
140+
assert(ranges::equal(output, expected_output));
141+
}
142+
};
143+
129144
template <test::ProxyRef IsProxy>
130145
using test_input = test::range<test::input, int_wrapper, test::Sized::no, test::CanDifference::no, test::Common::no,
131146
test::CanCompare::yes, IsProxy>;
@@ -140,4 +155,5 @@ int main() {
140155
instantiator::call<test_input<test::ProxyRef::yes>, test_output>();
141156
throwing_test::call<test_input<test::ProxyRef::no>, test_output>();
142157
throwing_test::call<test_input<test::ProxyRef::yes>, test_output>();
158+
memcopy_test::call();
143159
}

tests/std/tests/P0896R4_ranges_alg_uninitialized_move/test.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,21 @@ struct throwing_test {
154154
}
155155
};
156156

157+
struct memcopy_test {
158+
static constexpr int expected_output[] = {13, 55, 12345};
159+
static constexpr int expected_input[] = {13, 55, 12345};
160+
161+
static void call() {
162+
// Validate only range overload (one is plenty since they both use the same backend)
163+
int input[] = {13, 55, 12345};
164+
int output[] = {-1, -1, -1};
165+
166+
ranges::uninitialized_move(input, output);
167+
assert(ranges::equal(input, expected_input));
168+
assert(ranges::equal(output, expected_output));
169+
}
170+
};
171+
157172
template <test::ProxyRef IsProxy>
158173
using test_input = test::range<test::input, int_wrapper, test::Sized::no, test::CanDifference::no, test::Common::no,
159174
test::CanCompare::yes, IsProxy>;
@@ -168,4 +183,5 @@ int main() {
168183
instantiator::call<test_input<test::ProxyRef::yes>, test_output>();
169184
throwing_test::call<test_input<test::ProxyRef::no>, test_output>();
170185
throwing_test::call<test_input<test::ProxyRef::yes>, test_output>();
186+
memcopy_test::call();
171187
}

tests/std/tests/P0896R4_ranges_alg_uninitialized_move_n/test.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,21 @@ struct throwing_test {
128128
}
129129
};
130130

131+
struct memcopy_test {
132+
static constexpr int expected_output[] = {13, 55, 12345, -1};
133+
static constexpr int expected_input[] = {13, 55, 12345, 42};
134+
135+
static void call() {
136+
// Validate only range overload (one is plenty since they both use the same backend)
137+
int input[] = {13, 55, 12345, 42};
138+
int output[] = {-1, -1, -1, -1};
139+
140+
ranges::uninitialized_move_n(input, 3, output, output + 4);
141+
assert(ranges::equal(input, expected_input));
142+
assert(ranges::equal(output, expected_output));
143+
}
144+
};
145+
131146
template <test::ProxyRef IsProxy>
132147
using test_input = test::range<test::input, int_wrapper, test::Sized::no, test::CanDifference::no, test::Common::no,
133148
test::CanCompare::yes, IsProxy>;
@@ -142,4 +157,5 @@ int main() {
142157
instantiator::call<test_input<test::ProxyRef::yes>, test_output>();
143158
throwing_test::call<test_input<test::ProxyRef::no>, test_output>();
144159
throwing_test::call<test_input<test::ProxyRef::yes>, test_output>();
160+
memcopy_test::call();
145161
}

0 commit comments

Comments
 (0)