folly::Singleton leak diagnostics utils
[folly.git] / folly / small_vector.h
index c33eb7454bae5ee8cddc3522e466e32a837b6779..b03eec05f3a3281ba3b73b05dba18d86300dab2b 100644 (file)
@@ -23,7 +23,7 @@
 #ifndef FOLLY_SMALL_VECTOR_H_
 #define FOLLY_SMALL_VECTOR_H_
 
-#include "Portability.h"
+#include <folly/Portability.h>
 
 #include <stdexcept>
 #include <cstdlib>
 #include <boost/mpl/count.hpp>
 #include <boost/mpl/max.hpp>
 
-#include "folly/Malloc.h"
+#include <folly/Malloc.h>
 
 #if defined(__GNUC__) && FOLLY_X64
-# include "folly/SmallLocks.h"
+# include <folly/SmallLocks.h>
 # define FB_PACK_ATTR FOLLY_PACK_ATTR
 # define FB_PACK_PUSH FOLLY_PACK_PUSH
 # define FB_PACK_POP FOLLY_PACK_POP
@@ -109,10 +109,9 @@ namespace detail {
     !FOLLY_IS_TRIVIALLY_COPYABLE(T)
   >::type
   moveToUninitialized(T* first, T* last, T* out) {
-    auto const count = last - first;
     std::size_t idx = 0;
     try {
-      for (; idx < count; ++first, ++idx) {
+      for (; first != last; ++first, ++idx) {
         new (&out[idx]) T(std::move(*first));
       }
     } catch (...) {
@@ -391,13 +390,16 @@ public:
     try {
       std::uninitialized_copy(o.begin(), o.end(), begin());
     } catch (...) {
-      if (this->isExtern()) u.freeHeap();
+      if (this->isExtern()) {
+        u.freeHeap();
+      }
       throw;
     }
     this->setSize(n);
   }
 
-  small_vector(small_vector&& o) {
+  small_vector(small_vector&& o)
+  noexcept(std::is_nothrow_move_constructible<Value>::value) {
     if (o.isExtern()) {
       swap(o);
     } else {
@@ -737,8 +739,9 @@ public:
   }
 
   iterator erase(const_iterator q1, const_iterator q2) {
+    if (q1 == q2) return unconst(q1);
     std::move(unconst(q2), end(), unconst(q1));
-    for (auto it = q1; it != end(); ++it) {
+    for (auto it = (end() - std::distance(q1, q2)); it != end(); ++it) {
       it->~value_type();
     }
     this->setSize(size() - (q2 - q1));
@@ -876,18 +879,31 @@ private:
     auto distance = std::distance(first, last);
     makeSize(distance);
     this->setSize(distance);
-
-    detail::populateMemForward(data(), distance,
-      [&] (void* p) { new (p) value_type(*first++); }
-    );
+    try {
+      detail::populateMemForward(data(), distance,
+        [&] (void* p) { new (p) value_type(*first++); }
+      );
+    } catch (...) {
+      if (this->isExtern()) {
+        u.freeHeap();
+      }
+      throw;
+    }
   }
 
   void doConstruct(size_type n, value_type const& val) {
     makeSize(n);
     this->setSize(n);
-    detail::populateMemForward(data(), n,
-      [&] (void* p) { new (p) value_type(val); }
-    );
+    try {
+      detail::populateMemForward(data(), n,
+        [&] (void* p) { new (p) value_type(val); }
+      );
+    } catch (...) {
+      if (this->isExtern()) {
+        u.freeHeap();
+      }
+      throw;
+    }
   }
 
   // The true_type means we should forward to the size_t,value_type