Commit 7fbfb758 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Fix small_vector::insert with non-random-access iterators

Summary:
[Folly] Fix `small_vector::insert` with non-random-access iterator arguments.

Closes https://github.com/facebook/folly/issues/1322.

Reviewed By: ot, terrelln

Differential Revision: D20150453

fbshipit-source-id: 184e748dcbb7cb60318b5f0a3104d9aeb8352d7b
parent 5ead8bc2
...@@ -97,9 +97,8 @@ class small_vector; ...@@ -97,9 +97,8 @@ class small_vector;
namespace detail { namespace detail {
/* /*
* Move objects in memory to the right into some uninitialized * Move objects in memory to the right into some uninitialized memory, where
* memory, where the region overlaps. Then call create(size_t) for each * the region overlaps. Then call create() for each hole in reverse order.
* "hole" passing it the offset of the hole from first.
* *
* This doesn't just use std::move_backward because move_backward only works * This doesn't just use std::move_backward because move_backward only works
* if all the memory is initialized to type T already. * if all the memory is initialized to type T already.
...@@ -148,11 +147,11 @@ moveObjectsRightAndCreate( ...@@ -148,11 +147,11 @@ moveObjectsRightAndCreate(
} }
for (; out > lastConstructed;) { for (; out > lastConstructed;) {
--out; --out;
new (out) T(create(out - first)); new (out) T(create());
} }
for (; out != first;) { for (; out != first;) {
--out; --out;
*out = create(out - first); *out = create();
} }
rollback.dismiss(); rollback.dismiss();
} }
...@@ -174,7 +173,7 @@ moveObjectsRightAndCreate( ...@@ -174,7 +173,7 @@ moveObjectsRightAndCreate(
T* const end = first - 1; T* const end = first - 1;
T* out = first + (realLast - lastConstructed) - 1; T* out = first + (realLast - lastConstructed) - 1;
for (; out != end; --out) { for (; out != end; --out) {
*out = create(out - first); *out = create();
} }
} }
...@@ -833,11 +832,7 @@ class small_vector : public detail::small_vector_base< ...@@ -833,11 +832,7 @@ class small_vector : public detail::small_vector_base<
data() + offset, data() + offset,
data() + size(), data() + size(),
data() + size() + 1, data() + size() + 1,
[&](size_t i) -> value_type&& { [&]() mutable -> value_type&& { return std::move(t); });
assert(i == 0);
(void)i;
return std::move(t);
});
this->setSize(size() + 1); this->setSize(size() + 1);
} }
return begin() + offset; return begin() + offset;
...@@ -856,11 +851,7 @@ class small_vector : public detail::small_vector_base< ...@@ -856,11 +851,7 @@ class small_vector : public detail::small_vector_base<
data() + offset, data() + offset,
data() + size(), data() + size(),
data() + size() + n, data() + size() + n,
[&](size_t i) -> value_type const& { [&]() mutable -> value_type const& { return val; });
assert(i < n);
(void)i;
return val;
});
this->setSize(size() + n); this->setSize(size() + n);
return begin() + offset; return begin() + offset;
} }
...@@ -990,10 +981,7 @@ class small_vector : public detail::small_vector_base< ...@@ -990,10 +981,7 @@ class small_vector : public detail::small_vector_base<
data() + offset, data() + offset,
data() + size(), data() + size(),
data() + size() + distance, data() + size() + distance,
[&](size_t i) -> it_ref { [&, in = last]() mutable -> it_ref { return *--in; });
assert(i < size_t(distance));
return *(first + i);
});
this->setSize(size() + distance); this->setSize(size() + distance);
return begin() + offset; return begin() + offset;
} }
......
...@@ -376,6 +376,16 @@ TEST(small_vector, InsertNontrivial) { ...@@ -376,6 +376,16 @@ TEST(small_vector, InsertNontrivial) {
EXPECT_EQ(v3[11].s, "asd"); EXPECT_EQ(v3[11].s, "asd");
} }
TEST(small_vecctor, InsertFromBidirectionalList) {
folly::small_vector<std::string> v(6, "asd");
std::list<std::string> l(6, "wat");
v.insert(v.end(), l.begin(), l.end());
EXPECT_EQ(v[0], "asd");
EXPECT_EQ(v[5], "asd");
EXPECT_EQ(v[6], "wat");
EXPECT_EQ(v[11], "wat");
}
TEST(small_vector, Swap) { TEST(small_vector, Swap) {
folly::small_vector<int, 10> somethingVec, emptyVec; folly::small_vector<int, 10> somethingVec, emptyVec;
somethingVec.push_back(1); somethingVec.push_back(1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment