Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/base
diff options
context:
space:
mode:
authorYuri Gorshenin <y@maps.me>2016-04-21 20:52:24 +0300
committerYuri Gorshenin <y@maps.me>2016-04-22 11:50:16 +0300
commitb47ba8becda1711c1de2f4728c40b2f5d73e5033 (patch)
tree0f63f3cfab815f3ddc1a7c8d12baf55f73c1c73b /base
parentb997138491a566207fee05e79d385ca6e0a8a908 (diff)
[base] Fixed buffer_vector to support moveable-only types.
Diffstat (limited to 'base')
-rw-r--r--base/base_tests/buffer_vector_test.cpp13
-rw-r--r--base/buffer_vector.hpp257
2 files changed, 150 insertions, 120 deletions
diff --git a/base/base_tests/buffer_vector_test.cpp b/base/base_tests/buffer_vector_test.cpp
index b63f3c929f..96a0a62a25 100644
--- a/base/base_tests/buffer_vector_test.cpp
+++ b/base/base_tests/buffer_vector_test.cpp
@@ -3,6 +3,7 @@
#include "base/buffer_vector.hpp"
#include "base/string_utils.hpp"
+#include "std/unique_ptr.hpp"
namespace
{
@@ -351,3 +352,15 @@ UNIT_TEST(BufferVector_EraseIf)
v.erase_if([] (int x) { return true; });
TEST_EQUAL(v.size(), 0, ());
}
+
+UNIT_TEST(BufferVector_OnlyMoveableItems)
+{
+ buffer_vector<unique_ptr<size_t>, 4> v;
+
+ for (size_t i = 0; i < 10; ++i)
+ v.emplace_back(make_unique<size_t>(i));
+
+ TEST_EQUAL(v.size(), 10, ());
+ for (size_t i = 0; i < 10; ++i)
+ TEST_EQUAL(*v[i], i, ());
+}
diff --git a/base/buffer_vector.hpp b/base/buffer_vector.hpp
index fbf6a7d928..646d41ef3e 100644
--- a/base/buffer_vector.hpp
+++ b/base/buffer_vector.hpp
@@ -70,17 +70,15 @@ public:
assign(initList.begin(), initList.end());
}
- template <typename IterT>
- buffer_vector(IterT beg, IterT end) : m_size(0)
+ template <typename TIt>
+ buffer_vector(TIt beg, TIt end) : m_size(0)
{
assign(beg, end);
}
- buffer_vector(buffer_vector<T, N> const &) = default;
- buffer_vector & operator=(buffer_vector<T, N> const &) = default;
+ buffer_vector(buffer_vector const &) = default;
- buffer_vector(buffer_vector<T, N> && rhs)
- : m_size(rhs.m_size), m_dynamic(move(rhs.m_dynamic))
+ buffer_vector(buffer_vector && rhs) : m_size(rhs.m_size), m_dynamic(move(rhs.m_dynamic))
{
if (!IsDynamic())
MoveStatic(rhs);
@@ -88,7 +86,9 @@ public:
rhs.m_size = 0;
}
- buffer_vector & operator=(buffer_vector<T, N> && rhs)
+ buffer_vector & operator=(buffer_vector const & rhs) = default;
+
+ buffer_vector & operator=(buffer_vector && rhs)
{
m_size = rhs.m_size;
m_dynamic = move(rhs.m_dynamic);
@@ -106,38 +106,40 @@ public:
append(v.begin(), v.end());
}
- template <typename IterT>
- void append(IterT beg, IterT end)
+ template <typename TIt>
+ void append(TIt beg, TIt end)
{
if (IsDynamic())
+ {
m_dynamic.insert(m_dynamic.end(), beg, end);
- else
+ return;
+ }
+
+ while (beg != end)
{
- while (beg != end)
+ if (m_size == N)
{
- if (m_size == N)
- {
- m_dynamic.reserve(N * 2);
- SwitchToDynamic();
- while (beg != end)
- m_dynamic.push_back(*beg++);
- break;
- }
- m_static[m_size++] = *beg++;
+ m_dynamic.reserve(N * 2);
+ SwitchToDynamic();
+ while (beg != end)
+ m_dynamic.push_back(*beg++);
+ break;
}
+ m_static[m_size++] = *beg++;
}
}
- template <typename IterT>
- void assign(IterT beg, IterT end)
+ template <typename TIt>
+ void assign(TIt beg, TIt end)
{
if (IsDynamic())
- m_dynamic.assign(beg, end);
- else
{
- m_size = 0;
- append(beg, end);
+ m_dynamic.assign(beg, end);
+ return;
}
+
+ m_size = 0;
+ append(beg, end);
}
void reserve(size_t n)
@@ -149,41 +151,45 @@ public:
void resize_no_init(size_t n)
{
if (IsDynamic())
+ {
m_dynamic.resize(n);
+ return;
+ }
+
+ if (n <= N)
+ {
+ m_size = n;
+ }
else
{
- if (n <= N)
- m_size = n;
- else
- {
- m_dynamic.reserve(n);
- SwitchToDynamic();
- m_dynamic.resize(n);
- ASSERT_EQUAL(m_dynamic.size(), n, ());
- }
+ m_dynamic.reserve(n);
+ SwitchToDynamic();
+ m_dynamic.resize(n);
+ ASSERT_EQUAL(m_dynamic.size(), n, ());
}
}
void resize(size_t n, T c = T())
{
if (IsDynamic())
+ {
m_dynamic.resize(n, c);
+ return;
+ }
+
+ if (n <= N)
+ {
+ for (size_t i = m_size; i < n; ++i)
+ m_static[i] = c;
+ m_size = n;
+ }
else
{
- if (n <= N)
- {
- for (size_t i = m_size; i < n; ++i)
- m_static[i] = c;
- m_size = n;
- }
- else
- {
- m_dynamic.reserve(n);
- size_t const oldSize = m_size;
- SwitchToDynamic();
- m_dynamic.insert(m_dynamic.end(), n - oldSize, c);
- ASSERT_EQUAL(m_dynamic.size(), n, ());
- }
+ m_dynamic.reserve(n);
+ size_t const oldSize = m_size;
+ SwitchToDynamic();
+ m_dynamic.insert(m_dynamic.end(), n - oldSize, c);
+ ASSERT_EQUAL(m_dynamic.size(), n, ());
}
}
@@ -192,14 +198,13 @@ public:
if (IsDynamic())
{
m_dynamic.clear();
+ return;
}
- else
- {
- // here we have to call destructors of objects inside
- for (size_t i = 0; i < m_size; ++i)
- m_static[i] = T();
- m_size = 0;
- }
+
+ // here we have to call destructors of objects inside
+ for (size_t i = 0; i < m_size; ++i)
+ m_static[i] = T();
+ m_size = 0;
}
/// @todo Here is some inconsistencies:
@@ -212,22 +217,22 @@ public:
{
if (IsDynamic())
{
- ASSERT ( !m_dynamic.empty(), () );
+ ASSERT(!m_dynamic.empty(), ());
return &m_dynamic[0];
}
- else
- return &m_static[0];
+
+ return &m_static[0];
}
T * data()
{
if (IsDynamic())
{
- ASSERT ( !m_dynamic.empty(), () );
+ ASSERT(!m_dynamic.empty(), ());
return &m_dynamic[0];
}
- else
- return &m_static[0];
+
+ return &m_static[0];
}
//@}
@@ -272,7 +277,7 @@ public:
return *(begin() + i);
}
- void swap(buffer_vector<T, N> & rhs)
+ void swap(buffer_vector & rhs)
{
m_dynamic.swap(rhs.m_dynamic);
Swap(m_size, rhs.m_size);
@@ -283,101 +288,110 @@ public:
void push_back(T const & t)
{
if (IsDynamic())
+ {
m_dynamic.push_back(t);
+ return;
+ }
+
+ if (m_size < N)
+ {
+ m_static[m_size++] = t;
+ }
else
{
- if (m_size < N)
- m_static[m_size++] = t;
- else
- {
- ASSERT_EQUAL(m_size, N, ());
- SwitchToDynamic();
- m_dynamic.push_back(t);
- ASSERT_EQUAL(m_dynamic.size(), N + 1, ());
- }
+ ASSERT_EQUAL(m_size, N, ());
+ SwitchToDynamic();
+ m_dynamic.push_back(t);
+ ASSERT_EQUAL(m_dynamic.size(), N + 1, ());
}
}
void push_back(T && t)
{
if (IsDynamic())
+ {
m_dynamic.push_back(move(t));
+ return;
+ }
+
+ if (m_size < N)
+ {
+ Swap(m_static[m_size++], t);
+ }
else
{
- if (m_size < N)
- Swap(m_static[m_size++], t);
- else
- {
- ASSERT_EQUAL(m_size, N, ());
- SwitchToDynamic();
- m_dynamic.push_back(move(t));
- ASSERT_EQUAL(m_dynamic.size(), N + 1, ());
- }
+ ASSERT_EQUAL(m_size, N, ());
+ SwitchToDynamic();
+ m_dynamic.push_back(move(t));
+ ASSERT_EQUAL(m_dynamic.size(), N + 1, ());
}
}
void pop_back()
{
if (IsDynamic())
- m_dynamic.pop_back();
- else
{
- ASSERT_GREATER(m_size, 0, ());
- --m_size;
+ m_dynamic.pop_back();
+ return;
}
+
+ ASSERT_GREATER(m_size, 0, ());
+ --m_size;
}
template <class... Args>
void emplace_back(Args &&... args)
{
if (IsDynamic())
- m_dynamic.emplace_back(args...);
+ {
+ m_dynamic.emplace_back(forward<Args>(args)...);
+ return;
+ }
+
+ if (m_size < N)
+ {
+ value_type v(forward<Args>(args)...);
+ Swap(v, m_static[m_size++]);
+ }
else
{
- if (m_size < N)
- {
- value_type v(args...);
- Swap(v, m_static[m_size++]);
- }
- else
- {
- ASSERT_EQUAL(m_size, N, ());
- SwitchToDynamic();
- m_dynamic.emplace_back(args...);
- ASSERT_EQUAL(m_dynamic.size(), N + 1, ());
- }
+ ASSERT_EQUAL(m_size, N, ());
+ SwitchToDynamic();
+ m_dynamic.emplace_back(forward<Args>(args)...);
+ ASSERT_EQUAL(m_dynamic.size(), N + 1, ());
}
}
- template <typename IterT> void insert(const_iterator where, IterT beg, IterT end)
+ template <typename TIt> void insert(const_iterator where, TIt beg, TIt end)
{
ptrdiff_t const pos = where - data();
ASSERT_GREATER_OR_EQUAL(pos, 0, ());
ASSERT_LESS_OR_EQUAL(pos, static_cast<ptrdiff_t>(size()), ());
if (IsDynamic())
+ {
m_dynamic.insert(m_dynamic.begin() + pos, beg, end);
- else
+ return;
+ }
+
+ size_t const n = end - beg;
+ if (m_size + n <= N)
{
- size_t const n = end - beg;
- if (m_size + n <= N)
- {
- if (pos != m_size)
- for (ptrdiff_t i = m_size - 1; i >= pos; --i)
- Swap(m_static[i], m_static[i + n]);
+ if (pos != m_size)
+ for (ptrdiff_t i = m_size - 1; i >= pos; --i)
+ Swap(m_static[i], m_static[i + n]);
- m_size += n;
- T * writableWhere = &m_static[0] + pos;
- ASSERT_EQUAL(where, writableWhere, ());
- while (beg != end)
- *(writableWhere++) = *(beg++);
- }
- else
- {
- m_dynamic.reserve(m_size + n);
- SwitchToDynamic();
- m_dynamic.insert(m_dynamic.begin() + pos, beg, end);
- }
+ m_size += n;
+ T * writableWhere = &m_static[0] + pos;
+ ASSERT_EQUAL(where, writableWhere, ());
+ while (beg != end)
+ *(writableWhere++) = *(beg++);
+ }
+ else
+ {
+ m_dynamic.reserve(m_size + n);
+ SwitchToDynamic();
+ m_dynamic.insert(m_dynamic.begin() + pos, beg, end);
}
}
@@ -401,9 +415,12 @@ private:
{
ASSERT_NOT_EQUAL(m_size, static_cast<size_t>(USE_DYNAMIC), ());
ASSERT_EQUAL(m_dynamic.size(), 0, ());
- m_dynamic.insert(m_dynamic.end(), m_size, T());
+ m_dynamic.reserve(m_size);
for (size_t i = 0; i < m_size; ++i)
- Swap(m_static[i], m_dynamic[i]);
+ {
+ m_dynamic.emplace_back();
+ Swap(m_static[i], m_dynamic.back());
+ }
m_size = USE_DYNAMIC;
}
};