From: Dmitry Pleshkov Date: Tue, 14 Mar 2017 06:33:57 +0000 (-0700) Subject: small_vector should not require a copy-ctr from its element type unless it needs it. X-Git-Tag: v2017.03.20.00~11 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=acbd8f4fd827e188dfb4209e35998fbe7ce9162a;p=folly.git small_vector should not require a copy-ctr from its element type unless it needs it. Summary: Use default constructor directly, instead of copying the element introduced by default parameter value. This behavior is compatible with `std::vector`. Reviewed By: ot, bixue2010, luciang Differential Revision: D4700611 fbshipit-source-id: d3bd82c46c2857f5abcbec5dd2a64aaa85eaefe4 --- diff --git a/folly/small_vector.h b/folly/small_vector.h index db36acc0..4ef59b67 100644 --- a/folly/small_vector.h +++ b/folly/small_vector.h @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -393,8 +394,12 @@ class small_vector constructImpl(il.begin(), il.end(), std::false_type()); } - explicit small_vector(size_type n, value_type const& t = value_type()) { - doConstruct(n, t); + explicit small_vector(size_type n) { + doConstruct(n, [&](void* p) { new (p) value_type(); }); + } + + small_vector(size_type n, value_type const& t) { + doConstruct(n, [&](void* p) { new (p) value_type(t); }); } template @@ -882,13 +887,12 @@ private: } } - void doConstruct(size_type n, value_type const& val) { + template + void doConstruct(size_type n, InitFunc&& func) { makeSize(n); this->setSize(n); try { - detail::populateMemForward(data(), n, - [&] (void* p) { new (p) value_type(val); } - ); + detail::populateMemForward(data(), n, std::forward(func)); } catch (...) { if (this->isExtern()) { u.freeHeap(); @@ -900,7 +904,7 @@ private: // The true_type means we should forward to the size_t,value_type // overload. void constructImpl(size_type n, value_type const& val, std::true_type) { - doConstruct(n, val); + doConstruct(n, [&](void* p) { new (p) value_type(val); }); } void makeSize(size_type size, value_type* v = nullptr) { diff --git a/folly/test/small_vector_test.cpp b/folly/test/small_vector_test.cpp index 0190cbb8..db63d491 100644 --- a/folly/test/small_vector_test.cpp +++ b/folly/test/small_vector_test.cpp @@ -832,3 +832,27 @@ TEST(small_vector, InputIterator) { ASSERT_EQ(smallV[i], expected[i]); } } + +TEST(small_vector, NoCopyCtor) { + struct Test { + Test() = default; + Test(const Test&) = delete; + Test(Test&&) = default; + + int field = 42; + }; + + small_vector test(10); + ASSERT_EQ(test.size(), 10); + for (const auto& element : test) { + EXPECT_EQ(element.field, 42); + } +} + +TEST(small_vector, ZeroInitializable) { + small_vector test(10); + ASSERT_EQ(test.size(), 10); + for (const auto& element : test) { + EXPECT_EQ(element, 0); + } +}