Implemented LWG Issue #149 (range insertion now returns an iterator) & cleaned up insertion code in most containers

[SVN r80348]
This commit is contained in:
Ion Gaztañaga
2012-09-01 11:01:03 +00:00
parent 011f1fb181
commit 3c256c2282
29 changed files with 1659 additions and 1476 deletions

View File

@@ -12,6 +12,8 @@
#define BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINER_HPP
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/pair.hpp>
#include <boost/container/detail/mpl.hpp>
#include <functional>
#include <iostream>
#include <algorithm>
@@ -20,6 +22,24 @@ namespace boost{
namespace container {
namespace test{
template< class T1, class T2>
bool CheckEqual( const T1 &t1, const T2 &t2
, typename boost::container::container_detail::enable_if_c
<!boost::container::container_detail::is_pair<T1>::value &&
!boost::container::container_detail::is_pair<T2>::value
>::type* = 0)
{ return t1 == t2; }
template< class Pair1, class Pair2>
bool CheckEqual( const Pair1 &pair1, const Pair2 &pair2
, typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_pair<Pair1>::value &&
boost::container::container_detail::is_pair<Pair2>::value
>::type* = 0)
{
return CheckEqual(pair1.first, pair2.first) && CheckEqual(pair1.second, pair2.second);
}
//Function to check if both containers are equal
template<class MyBoostCont
,class MyStdCont>
@@ -38,10 +58,13 @@ bool CheckEqualContainers(const MyBoostCont *boostcont, const MyStdCont *stdcont
}
std::size_t i = 0;
for(; itboost != itboostend; ++itboost, ++itstd, ++i){
value_type val(*itstd);
if(!CheckEqual(*itstd, *itboost))
return false;
/* value_type val(*itstd);
const value_type &v = *itboost;
if(v != val)
return false;
return false;*/
}
return true;
}

View File

@@ -63,7 +63,7 @@ bool deque_copyable_only(V1 *cntdeque, V2 *stddeque, container_detail::true_type
typedef typename V1::value_type IntType;
std::size_t size = cntdeque->size();
stddeque->insert(stddeque->end(), 50, 1);
cntdeque->insert(cntdeque->end(), 50, 1);
cntdeque->insert(cntdeque->end(), 50, IntType(1));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
{
IntType move_me(1);

View File

@@ -0,0 +1,80 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2012-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_TEST_FORWARD_TO_INPUT_ITERATOR_HPP
#define BOOST_CONTAINER_TEST_FORWARD_TO_INPUT_ITERATOR_HPP
#include <iterator>
namespace boost{
namespace container {
namespace test{
template<class FwdIterator>
class input_iterator_wrapper
: public std::iterator< std::input_iterator_tag
, typename std::iterator_traits<FwdIterator>::value_type
, typename std::iterator_traits<FwdIterator>::difference_type
, typename std::iterator_traits<FwdIterator>::pointer
, typename std::iterator_traits<FwdIterator>::reference
>
{
FwdIterator m_it;
public:
input_iterator_wrapper()
: m_it(0)
{}
explicit input_iterator_wrapper(FwdIterator it)
: m_it(it)
{}
//Default copy constructor...
//input_iterator_wrapper(const input_iterator_wrapper&);
//Default assignment...
//input_iterator_wrapper &operator=(const input_iterator_wrapper&);
//Default destructor...
//~input_iterator_wrapper();
typename std::iterator_traits<FwdIterator>::reference operator*() const
{ return *m_it; }
typename std::iterator_traits<FwdIterator>::pointer operator->() const
{ return m_it.operator->(); }
input_iterator_wrapper& operator++()
{ ++m_it; return *this; }
input_iterator_wrapper operator++(int )
{
input_iterator_wrapper tmp(m_it);
++m_it;
return tmp;
}
friend bool operator==(const input_iterator_wrapper &left, const input_iterator_wrapper &right)
{ return left.m_it == right.m_it; }
friend bool operator!=(const input_iterator_wrapper &left, const input_iterator_wrapper &right)
{ return left.m_it != right.m_it; }
};
template<class FwdIterator>
input_iterator_wrapper<FwdIterator> make_input_from_forward_iterator(const FwdIterator &it)
{ return input_iterator_wrapper<FwdIterator>(it); }
} //namespace test{
} //namespace container {
} //namespace boost{
#endif //BOOST_CONTAINER_TEST_FORWARD_TO_INPUT_ITERATOR_HPP

View File

@@ -18,6 +18,7 @@
#include <vector>
#include <functional>
#include "print_container.hpp"
#include "input_from_forward_iterator.hpp"
#include <boost/move/move.hpp>
#include <string>
@@ -177,7 +178,20 @@ int list_test (bool copied_allocators_equal = true)
aux_vect2[i] = -1;
}
boostlist->assign(boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(&aux_vect[50]));
,boost::make_move_iterator(&aux_vect[50]));
stdlist->assign(&aux_vect2[0], &aux_vect2[50]);
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = boost::move(move_me);
}
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
boostlist->assign(boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[0]))
,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[50])));
stdlist->assign(&aux_vect2[0], &aux_vect2[50]);
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
}
@@ -206,10 +220,36 @@ int list_test (bool copied_allocators_equal = true)
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
boostlist->insert(boostlist->begin()
typename MyBoostList::iterator old_begin = boostlist->begin();
typename MyBoostList::iterator it_insert =
boostlist->insert(boostlist->begin()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(&aux_vect[50]));
if(it_insert != boostlist->begin() || std::distance(it_insert, old_begin) != 50)
return 1;
stdlist->insert(stdlist->begin(), &aux_vect2[0], &aux_vect2[50]);
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = boost::move(move_me);
}
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
old_begin = boostlist->begin();
it_insert = boostlist->insert(boostlist->end()
,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[0]))
,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[50])));
if(std::distance(it_insert, boostlist->end()) != 50)
return 1;
stdlist->insert(stdlist->end(), &aux_vect2[0], &aux_vect2[50]);
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
}
boostlist->unique();

View File

@@ -73,6 +73,12 @@ class movable_int
int get_int() const
{ return m_int; }
friend bool operator==(const movable_int &l, int r)
{ return l.get_int() == r; }
friend bool operator==(int l, const movable_int &r)
{ return l == r.get_int(); }
private:
int m_int;
};
@@ -144,6 +150,12 @@ class movable_and_copyable_int
int get_int() const
{ return m_int; }
friend bool operator==(const movable_and_copyable_int &l, int r)
{ return l.get_int() == r; }
friend bool operator==(int l, const movable_and_copyable_int &r)
{ return l == r.get_int(); }
private:
int m_int;
};
@@ -202,6 +214,12 @@ class copyable_int
int get_int() const
{ return m_int; }
friend bool operator==(const copyable_int &l, int r)
{ return l.get_int() == r; }
friend bool operator==(int l, const copyable_int &r)
{ return l == r.get_int(); }
private:
int m_int;
};
@@ -256,10 +274,17 @@ class non_copymovable_int
int get_int() const
{ return m_int; }
friend bool operator==(const non_copymovable_int &l, int r)
{ return l.get_int() == r; }
friend bool operator==(int l, const non_copymovable_int &r)
{ return l == r.get_int(); }
private:
int m_int;
};
} //namespace test {
} //namespace container {
} //namespace boost {

View File

@@ -88,13 +88,13 @@ int set_test ()
IntType move_me(i);
aux_vect3[i] = boost::move(move_me);
}
/*
MyBoostSet *boostset3 = MyBoostSet
MyBoostSet *boostset3 = new MyBoostSet
( ordered_unique_range
, boost::make_move_iterator(&aux_vect[0])
, boost::make_move_iterator(aux_vect + 50));
MyStdSet *stdset3 = new MyStdSet(aux_vect2, aux_vect2 + 50);
MyBoostMultiSet *boostmultiset3 = MyBoostMultiSet
MyBoostMultiSet *boostmultiset3 = new MyBoostMultiSet
( ordered_range
, boost::make_move_iterator(&aux_vect3[0])
, boost::make_move_iterator(aux_vect3 + 50));
@@ -108,15 +108,15 @@ int set_test ()
std::cout << "Error in construct<MyBoostMultiSet>(MyBoostMultiSet3)" << std::endl;
return 1;
}
*/
delete boostset2;
delete boostmultiset2;
delete stdset2;
delete stdmultiset2;
//delete boostset3;
//delete boostmultiset3;
//delete stdset3;
//delete stdmultiset3;
delete boostset3;
delete boostmultiset3;
delete stdset3;
delete stdmultiset3;
}
int i, j;

View File

@@ -8,6 +8,9 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_TEST_VECTOR_TEST_HEADER
#define BOOST_CONTAINER_TEST_VECTOR_TEST_HEADER
#include <boost/container/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
@@ -24,6 +27,7 @@
#include <string>
#include <vector>
#include "emplace_test.hpp"
#include "input_from_forward_iterator.hpp"
namespace boost{
namespace container {
@@ -133,10 +137,11 @@ int vector_test()
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
boostvector->insert(boostvector->end()
typename MyBoostVector::iterator insert_it =
boostvector->insert(boostvector->end()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(aux_vect + 50));
if(std::size_t(std::distance(insert_it, boostvector->end())) != 50) return 1;
stdvector->insert(stdvector->end(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
@@ -156,9 +161,30 @@ int vector_test()
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
boostvector->insert(boostvector->begin()
typename MyBoostVector::iterator insert_it =
boostvector->insert(boostvector->begin()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(aux_vect + 50));
if(boostvector->begin() != insert_it) return 1;
stdvector->insert(stdvector->begin(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
for(int i = 0; i < 50; ++i){
IntType new_int(-1);
aux_vect[i] = boost::move(new_int);
}
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
//Now try with input iterators instead
insert_it = boostvector->insert(boostvector->begin()
// ,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[0]))
// ,boost::make_move_iterator(make_input_from_forward_iterator(aux_vect + 50))
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(aux_vect + 50)
);
if(boostvector->begin() != insert_it) return 1;
stdvector->insert(stdvector->begin(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
}
@@ -204,12 +230,20 @@ int vector_test()
//Test insertion from list
{
std::list<int> l(50, int(1));
boostvector->insert(boostvector->begin(), l.begin(), l.end());
typename MyBoostVector::iterator it_insert =
boostvector->insert(boostvector->begin(), l.begin(), l.end());
if(boostvector->begin() != it_insert) return 1;
stdvector->insert(stdvector->begin(), l.begin(), l.end());
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->assign(l.begin(), l.end());
stdvector->assign(l.begin(), l.end());
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->clear();
stdvector->clear();
boostvector->assign(make_input_from_forward_iterator(l.begin()), make_input_from_forward_iterator(l.end()));
stdvector->assign(l.begin(), l.end());
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
}
/*
std::size_t cap = boostvector->capacity();
@@ -252,3 +286,6 @@ int vector_test()
} //namespace boost{
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_TEST_VECTOR_TEST_HEADER