From addc5eebcfe9f35fbda07af78802ed8c9db2f9ec Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sat, 15 Dec 2012 23:21:59 +0000 Subject: [PATCH] Added static_vector::erase() and tests. [SVN r81990] --- .../extensions/index/static_vector.hpp | 46 +++++++++++++++++ test/static_vector.cpp | 49 +++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/include/boost/geometry/extensions/index/static_vector.hpp b/include/boost/geometry/extensions/index/static_vector.hpp index 11599461b..0e8205040 100644 --- a/include/boost/geometry/extensions/index/static_vector.hpp +++ b/include/boost/geometry/extensions/index/static_vector.hpp @@ -159,6 +159,33 @@ public: this->destroy(this->ptr(m_size)); } + void erase(iterator position) + { + // TODO change name of this macro + BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(difference_type dist = std::distance(this->begin(), position)); + BOOST_ASSERT_MSG(0 <= dist && dist < m_size, "invalid iterator"); + + this->move(position + 1, this->end(), position); // may throw + this->destroy(this->end() - 1); + --m_size; + } + + void erase(iterator first, iterator last) + { + // TODO change name of this macro + BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(difference_type distf = std::distance(this->begin(), first)); + BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(difference_type distl = std::distance(this->begin(), last)); + BOOST_ASSERT_MSG(0 <= distf && distf < m_size, "invalid iterator"); + BOOST_ASSERT_MSG(0 <= distl && distl < m_size, "invalid iterator"); + + difference_type n = std::distance(first, last); + BOOST_ASSERT_MSG(0 <= n, "invalid iterator"); + + this->move(last, this->end(), first); // may throw + this->destroy(this->end() - n, this->end()); + m_size -= n; + } + // basic template void assign(Iterator first, Iterator last) @@ -358,6 +385,25 @@ private: std::copy(first, last, dst); // may throw } + // move + + void move(iterator first, iterator last, iterator dst) + { + this->move_dispatch(first, last, dst, has_trivial_assign()); // may throw + } + + void move_dispatch(value_type * first, value_type * last, value_type * dst, + boost::true_type const& /*has_trivial_assign*/) + { + ::memmove(dst, first, sizeof(value_type) * std::distance(first, last)); + } + + void move_dispatch(value_type * first, value_type * last, value_type * dst, + boost::false_type const& /*has_trivial_assign*/) + { + std::copy(first, last, dst); // may throw + } + // uninitialized_copy template diff --git a/test/static_vector.cpp b/test/static_vector.cpp index 6e122d9b6..f8107f5c9 100644 --- a/test/static_vector.cpp +++ b/test/static_vector.cpp @@ -299,6 +299,50 @@ void test_iterators_nd() test_compare_ranges(s.rbegin(), s.rend(), v.begin(), v.end()); } +template +void test_erase_nd() +{ + static_vector s; + + for ( size_t i = 0 ; i < N ; ++i ) + s.push_back(T(i)); + + { + static_vector s1(s); + + for ( size_t i = 1 ; i < N ; ++i ) + { + BOOST_CHECK(s1.front() == T(i-1)); + s1.erase(s1.begin()); + BOOST_CHECK(s1.front() == T(i)); + } + BOOST_CHECK(s1.size() == 1); + } + + { + static_vector s1(s); + + for ( size_t i = N ; i > 1 ; --i ) + { + BOOST_CHECK(s1.back() == T(i-1)); + s1.erase(s1.end() - 1); + BOOST_CHECK(s1.back() == T(i-2)); + } + BOOST_CHECK(s1.size() == 1); + } + + { + static_vector s1(s); + + for ( size_t i = 1 ; i < N - 2 ; i += 3 ) + { + BOOST_CHECK(s1.front() == T(i-1)); + s1.erase(s1.begin(), s1.begin() + 3); + BOOST_CHECK(s1.front() == T(i+2)); + } + } +} + int test_main(int, char* []) { BOOST_CHECK(counting_value::count() == 0); @@ -348,5 +392,10 @@ int test_main(int, char* []) test_iterators_nd(); BOOST_CHECK(counting_value::count() == 0); + test_erase_nd(); + test_erase_nd(); + test_erase_nd(); + BOOST_CHECK(counting_value::count() == 0); + return 0; }