Implemented static_vector::insert(pos, first, last) for random access iterators.

Tests added.

[SVN r82024]
This commit is contained in:
Adam Wulkiewicz
2012-12-16 16:09:07 +00:00
parent 57c75071f9
commit 0ae51b1dbc
2 changed files with 123 additions and 26 deletions

View File

@@ -179,6 +179,8 @@ public:
}
else
{
// TODO - should following lines check for exception and revert to the old size?
this->uninitialized_fill(this->end(), *(this->end() - 1)); // may throw
++m_size; // update end
this->move_backward(position, this->end() - 2, this->end() - 1); // may throw
@@ -205,6 +207,8 @@ public:
{
difference_type to_move = std::distance(position, this->end());
// TODO - should following lines check for exception and revert to the old size?
if ( count < static_cast<size_type>(to_move) )
{
this->uninitialized_copy(this->end() - count, this->end(), this->end()); // may throw
@@ -223,6 +227,14 @@ public:
}
}
// basic
template <typename Iterator>
void insert(iterator position, Iterator first, Iterator last)
{
typedef typename boost::iterator_traversal<Iterator>::type traversal;
this->insert_dispatch(position, first, last, traversal());
}
// basic
void erase(iterator position)
{
@@ -257,7 +269,7 @@ public:
void assign(Iterator first, Iterator last)
{
typedef typename boost::iterator_traversal<Iterator>::type traversal;
assign_dispatch(first, last, traversal()); // may throw
this->assign_dispatch(first, last, traversal()); // may throw
}
// basic
@@ -370,10 +382,63 @@ public:
private:
// insert
template <typename Iterator>
void insert_dispatch(iterator position, Iterator first, Iterator last, boost::random_access_traversal_tag const&)
{
// TODO change name of this macro
BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(difference_type dist = std::distance(this->begin(), position));
// TODO dist < distance(begin(), end())
BOOST_ASSERT_MSG(0 <= dist && (sizeof(dist)<=sizeof(m_size)?((size_type)dist<=m_size):(dist<=(difference_type)m_size)), "invalid iterator");
difference_type count = std::distance(first, last);
BOOST_ASSERT_MSG(m_size + count <= Capacity, "size can't exceed the capacity");
//if ( Capacity < m_size + count ) throw std::bad_alloc();
if ( position == this->end() )
{
this->uninitialized_copy(first, last, position); // may throw
m_size += count; // update end
}
else
{
difference_type to_move = std::distance(position, this->end());
// TODO - should following lines check for exception and revert to the old size?
if ( count < to_move )
{
this->uninitialized_copy(this->end() - count, this->end(), this->end()); // may throw
m_size += count; // update end
this->move_backward(position, position + to_move - count, this->end() - count); // may throw
this->copy(first, last, position); // may throw
}
else
{
this->uninitialized_copy(first + to_move, last, this->end()); // may throw
m_size += count - to_move; // update end
this->uninitialized_copy(position, position + to_move, position + count); // may throw
m_size += to_move; // update end
this->copy(first, first + to_move, position) ; // may throw
}
}
}
template <typename Iterator, typename Traversal>
void insert_dispatch(iterator position, Iterator first, Iterator last, Traversal const& /*not_random_access*/)
{
BOOST_MPL_ASSERT_MSG(
(false),
THIS_ITERATOR_IS_NOT_YET_SUPPORTED,
(static_vector));
}
// assign
template <typename Iterator>
void assign_dispatch(Iterator first, Iterator last, boost::random_access_traversal_tag const&)
void assign_dispatch(Iterator first, Iterator last, boost::random_access_traversal_tag const& /*not_random_access*/)
{
size_type s = std::distance(first, last);

View File

@@ -344,47 +344,79 @@ void test_erase_nd()
}
template <typename T, size_t N>
void test_insert_nd(T const& v)
void test_insert_nd(T const& val)
{
size_t h = N/2;
static_vector<T, N> s;
static_vector<T, N> s, ss;
std::vector<T> v;
std::list<T> l;
for ( size_t i = 0 ; i < h ; ++i )
{
s.push_back(T(i));
{
static_vector<T, N> s1(s);
for ( size_t i = 0 ; i < h ; ++i )
s1.insert(s1.begin(), v);
BOOST_CHECK(s1.size() == 2*h);
for ( size_t i = 0 ; i < h ; ++i )
BOOST_CHECK(s1[i] == v);
for ( size_t i = 0 ; i < h ; ++i )
BOOST_CHECK(s1[i+h] == T(i));
}
{
static_vector<T, N> s1(s);
for ( size_t i = 0 ; i < h ; ++i )
s1.insert(s1.end(), v);
BOOST_CHECK(s1.size() == 2*h);
for ( size_t i = 0 ; i < h ; ++i )
BOOST_CHECK(s1[i] == T(i));
for ( size_t i = 0 ; i < h ; ++i )
BOOST_CHECK(s1[i+h] == v);
ss.push_back(T(100 + i));
v.push_back(T(100 + i));
l.push_back(T(100 + i));
}
// insert(pos, val)
{
for ( size_t i = 0 ; i <= h ; ++i )
{
static_vector<T, N> s1(s);
s1.insert(s1.begin() + i, val);
BOOST_CHECK(s1.size() == h+1);
for ( size_t j = 0 ; j < i ; ++j )
BOOST_CHECK(s1[j] == T(j));
BOOST_CHECK(s1[i] == val);
for ( size_t j = 0 ; j < h-i ; ++j )
BOOST_CHECK(s1[j+i+1] == T(j+i));
}
}
// insert(pos, n, val)
{
size_t n = size_t(h/1.5f);
for ( size_t i = 0 ; i <= h ; ++i )
{
static_vector<T, N> s1(s);
s1.insert(s1.begin() + i, n, v);
s1.insert(s1.begin() + i, n, val);
BOOST_CHECK(s1.size() == h+n);
for ( size_t j = 0 ; j < i ; ++j )
BOOST_CHECK(s1[j] == T(j));
for ( size_t j = 0 ; j < n ; ++j )
BOOST_CHECK(s1[j+i] == v);
BOOST_CHECK(s1[j+i] == val);
for ( size_t j = 0 ; j < h-i ; ++j )
BOOST_CHECK(s1[j+i+n] == T(j+i));
}
}
// insert(pos, first, last)
{
size_t n = size_t(h/1.5f);
for ( size_t i = 0 ; i <= h ; ++i )
{
static_vector<T, N> s1(s);
s1.insert(s1.begin() + i, ss.begin(), ss.begin() + n);
BOOST_CHECK(s1.size() == h+n);
for ( size_t j = 0 ; j < i ; ++j )
BOOST_CHECK(s1[j] == T(j));
for ( size_t j = 0 ; j < n ; ++j )
BOOST_CHECK(s1[j+i] == T(100 + j));
for ( size_t j = 0 ; j < h-i ; ++j )
BOOST_CHECK(s1[j+i+n] == T(j+i));
}
}
{
size_t n = size_t(h/1.5f);
for ( size_t i = 0 ; i <= h ; ++i )
{
static_vector<T, N> s1(s);
s1.insert(s1.begin() + i, v.begin(), v.begin() + n);
BOOST_CHECK(s1.size() == h+n);
for ( size_t j = 0 ; j < i ; ++j )
BOOST_CHECK(s1[j] == T(j));
for ( size_t j = 0 ; j < n ; ++j )
BOOST_CHECK(s1[j+i] == T(100 + j));
for ( size_t j = 0 ; j < h-i ; ++j )
BOOST_CHECK(s1[j+i+n] == T(j+i));
}