Merged for Boost 1.48

[SVN r74161]
This commit is contained in:
Ion Gaztañaga
2011-08-30 15:49:49 +00:00
parent f5db9a8d1f
commit 38805868fc
59 changed files with 8071 additions and 0 deletions
+34
View File
@@ -0,0 +1,34 @@
# Boost Container Library Test Jamfile
# (C) Copyright Ion Gaztanaga 2009.
# Use, modification and distribution are subject to 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)
# Adapted from John Maddock's TR1 Jamfile.v2
# Copyright John Maddock 2005.
# Use, modification and distribution are subject to 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)
# this rule enumerates through all the sources and invokes
# the run rule for each source, the result is a list of all
# the run rules, which we can pass on to the test_suite rule:
rule test_all
{
local all_rules = ;
for local fileb in [ glob *.cpp ]
{
all_rules += [ run $(fileb)
: # additional args
: # test-files
: # requirements
] ;
}
return $(all_rules) ;
}
test-suite container_test : [ test_all r ] ;
+76
View File
@@ -0,0 +1,76 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006. 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_CHECK_EQUAL_CONTAINERS_HPP
#define BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINERS_HPP
#include <boost/container/detail/config_begin.hpp>
#include <functional>
#include <iostream>
#include <algorithm>
namespace boost{
namespace container {
namespace test{
//Function to check if both containers are equal
template<class MyBoostCont
,class MyStdCont>
bool CheckEqualContainers(MyBoostCont *boostcont, MyStdCont *stdcont)
{
if(boostcont->size() != stdcont->size())
return false;
typedef typename MyBoostCont::value_type value_type;
typename MyBoostCont::iterator itboost(boostcont->begin()), itboostend(boostcont->end());
typename MyStdCont::iterator itstd(stdcont->begin());
typename MyStdCont::size_type dist = (typename MyStdCont::size_type)std::distance(itboost, itboostend);
if(dist != boostcont->size()){
return false;
}
std::size_t i = 0;
for(; itboost != itboostend; ++itboost, ++itstd, ++i){
value_type val(*itstd);
const value_type &v = *itboost;
if(v != val)
return false;
}
return true;
}
template<class MyBoostCont
,class MyStdCont>
bool CheckEqualPairContainers(MyBoostCont *boostcont, MyStdCont *stdcont)
{
if(boostcont->size() != stdcont->size())
return false;
typedef typename MyBoostCont::key_type key_type;
typedef typename MyBoostCont::mapped_type mapped_type;
typename MyBoostCont::iterator itboost(boostcont->begin()), itboostend(boostcont->end());
typename MyStdCont::iterator itstd(stdcont->begin());
for(; itboost != itboostend; ++itboost, ++itstd){
if(itboost->first != key_type(itstd->first))
return false;
if(itboost->second != mapped_type(itstd->second))
return false;
}
return true;
}
} //namespace test{
} //namespace container {
} //namespace boost{
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINERS_HPP
+295
View File
@@ -0,0 +1,295 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
#include <deque>
#include <iostream>
#include <functional>
#include <list>
#include <boost/container/deque.hpp>
#include "print_container.hpp"
#include "check_equal_containers.hpp"
#include "dummy_test_allocator.hpp"
#include "movable_int.hpp"
#include <boost/move/move.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <string>
#include "emplace_test.hpp"
#include "vector_test.hpp"
using namespace boost::container;
//Explicit instantiation to detect compilation errors
template class boost::container::deque
< test::movable_and_copyable_int
, test::dummy_test_allocator<test::movable_and_copyable_int> >;
//Function to check if both sets are equal
template<class V1, class V2>
bool deque_copyable_only(V1 *, V2 *, containers_detail::false_type)
{
return true;
}
//Function to check if both sets are equal
template<class V1, class V2>
bool deque_copyable_only(V1 *cntdeque, V2 *stddeque, containers_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);
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
{
IntType move_me(1);
stddeque->insert(stddeque->begin()+size/2, 50, 1);
cntdeque->insert(cntdeque->begin()+size/2, 50, boost::move(move_me));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
}
{
IntType move_me(2);
cntdeque->assign(cntdeque->size()/2, boost::move(move_me));
stddeque->assign(stddeque->size()/2, 2);
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
}
{
IntType move_me(1);
stddeque->clear();
cntdeque->clear();
stddeque->insert(stddeque->begin(), 50, 1);
cntdeque->insert(cntdeque->begin(), 50, boost::move(move_me));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
stddeque->insert(stddeque->begin()+20, 50, 1);
cntdeque->insert(cntdeque->begin()+20, 50, boost::move(move_me));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
stddeque->insert(stddeque->begin()+20, 20, 1);
cntdeque->insert(cntdeque->begin()+20, 20, boost::move(move_me));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
}
{
IntType move_me(1);
stddeque->clear();
cntdeque->clear();
stddeque->insert(stddeque->end(), 50, 1);
cntdeque->insert(cntdeque->end(), 50, boost::move(move_me));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
stddeque->insert(stddeque->end()-20, 50, 1);
cntdeque->insert(cntdeque->end()-20, 50, boost::move(move_me));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
stddeque->insert(stddeque->end()-20, 20, 1);
cntdeque->insert(cntdeque->end()-20, 20, boost::move(move_me));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
}
return true;
}
//Test recursive structures
class recursive_deque
{
public:
int id_;
deque<recursive_deque> deque_;
};
template<class IntType>
bool do_test()
{
//Test for recursive types
{
deque<recursive_deque> recursive_deque_deque;
}
{
//Now test move semantics
deque<recursive_deque> original;
deque<recursive_deque> move_ctor(boost::move(original));
deque<recursive_deque> move_assign;
move_assign = boost::move(move_ctor);
move_assign.swap(original);
}
//Alias deque types
typedef deque<IntType> MyCntDeque;
typedef std::deque<int> MyStdDeque;
const int max = 100;
try{
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyCntDeque *cntdeque = new MyCntDeque;
MyStdDeque *stddeque = new MyStdDeque;
//Compare several shared memory deque operations with std::deque
int i;
for(i = 0; i < max*100; ++i){
IntType move_me(i);
cntdeque->insert(cntdeque->end(), boost::move(move_me));
stddeque->insert(stddeque->end(), i);
}
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
cntdeque->clear();
stddeque->clear();
for(i = 0; i < max*100; ++i){
IntType move_me(i);
cntdeque->push_back(boost::move(move_me));
stddeque->push_back(i);
}
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
cntdeque->clear();
stddeque->clear();
for(i = 0; i < max*100; ++i){
IntType move_me(i);
cntdeque->push_front(boost::move(move_me));
stddeque->push_front(i);
}
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
typename MyCntDeque::iterator it;
typename MyCntDeque::const_iterator cit = it;
cntdeque->erase(cntdeque->begin()++);
stddeque->erase(stddeque->begin()++);
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
cntdeque->erase(cntdeque->begin());
stddeque->erase(stddeque->begin());
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
{
//Initialize values
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me (-1);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
cntdeque->insert(cntdeque->end()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(aux_vect + 50));
stddeque->insert(stddeque->end(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
for(int i = 0, j = static_cast<int>(cntdeque->size()); i < j; ++i){
cntdeque->erase(cntdeque->begin());
stddeque->erase(stddeque->begin());
}
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
}
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
cntdeque->insert(cntdeque->begin()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(aux_vect + 50));
stddeque->insert(stddeque->begin(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
}
if(!deque_copyable_only(cntdeque, stddeque
,containers_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
return false;
}
cntdeque->erase(cntdeque->begin());
stddeque->erase(stddeque->begin());
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
for(i = 0; i < max; ++i){
IntType move_me(i);
cntdeque->insert(cntdeque->begin(), boost::move(move_me));
stddeque->insert(stddeque->begin(), i);
}
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
//Test insertion from list
{
std::list<int> l(50, int(1));
cntdeque->insert(cntdeque->begin(), l.begin(), l.end());
stddeque->insert(stddeque->begin(), l.begin(), l.end());
if(!test::CheckEqualContainers(cntdeque, stddeque)) return 1;
cntdeque->assign(l.begin(), l.end());
stddeque->assign(l.begin(), l.end());
if(!test::CheckEqualContainers(cntdeque, stddeque)) return 1;
}
cntdeque->resize(100);
stddeque->resize(100);
if(!test::CheckEqualContainers(cntdeque, stddeque)) return 1;
cntdeque->resize(200);
stddeque->resize(200);
if(!test::CheckEqualContainers(cntdeque, stddeque)) return 1;
delete cntdeque;
delete stddeque;
}
catch(std::exception &ex){
std::cout << ex.what() << std::endl;
return false;
}
std::cout << std::endl << "Test OK!" << std::endl;
return true;
}
int main ()
{
if(!do_test<int>())
return 1;
if(!do_test<test::movable_int>())
return 1;
{
typedef deque<int> MyDeque;
typedef deque<test::movable_int> MyMoveDeque;
typedef deque<test::movable_and_copyable_int> MyCopyMoveDeque;
typedef deque<test::copyable_int> MyCopyDeque;
if(test::vector_test<MyDeque>())
return 1;
if(test::vector_test<MyMoveDeque>())
return 1;
if(test::vector_test<MyCopyMoveDeque>())
return 1;
if(test::vector_test<MyCopyDeque>())
return 1;
}
const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE);
if(!boost::container::test::test_emplace
< deque<test::EmplaceInt>, Options>())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>
+157
View File
@@ -0,0 +1,157 @@
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. 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_DUMMY_TEST_ALLOCATOR_HPP
#define BOOST_CONTAINER_DUMMY_TEST_ALLOCATOR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/allocation_type.hpp>
#include <boost/assert.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/version_type.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
#include <stdexcept>
#include <cassert>
//!\file
//!Describes an allocator to test expand capabilities
namespace boost {
namespace container {
namespace test {
//This allocator just allows two allocations. The first one will return
//mp_buffer + m_offset configured in the constructor. The second one
//will return mp_buffer.
template<class T>
class dummy_test_allocator
{
private:
typedef dummy_test_allocator<T> self_t;
typedef void * aux_pointer_t;
typedef const void * cvoid_ptr;
template<class T2>
dummy_test_allocator& operator=(const dummy_test_allocator<T2>&);
dummy_test_allocator& operator=(const dummy_test_allocator&);
public:
typedef T value_type;
typedef T * pointer;
typedef const T * const_pointer;
typedef typename containers_detail::add_reference
<value_type>::type reference;
typedef typename containers_detail::add_reference
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
// typedef boost::container::version_type<dummy_test_allocator, 2> version;
template<class T2>
struct rebind
{ typedef dummy_test_allocator<T2> other; };
//!Default constructor. Never throws
dummy_test_allocator()
{}
//!Constructor from other dummy_test_allocator. Never throws
dummy_test_allocator(const dummy_test_allocator &)
{}
//!Constructor from related dummy_test_allocator. Never throws
template<class T2>
dummy_test_allocator(const dummy_test_allocator<T2> &)
{}
pointer address(reference value)
{ return pointer(addressof(value)); }
const_pointer address(const_reference value) const
{ return const_pointer(addressof(value)); }
pointer allocate(size_type, cvoid_ptr = 0)
{ return 0; }
void deallocate(const pointer &, size_type)
{ }
template<class Convertible>
void construct(pointer, const Convertible &)
{}
void destroy(pointer)
{}
size_type max_size() const
{ return 0; }
friend void swap(self_t &, self_t &)
{}
//Experimental version 2 dummy_test_allocator functions
std::pair<pointer, bool>
allocation_command(boost::container::allocation_type,
size_type,
size_type,
size_type &, const pointer & = 0)
{ return std::pair<pointer, bool>(pointer(0), true); }
//!Returns maximum the number of objects the previously allocated memory
//!pointed by p can hold.
size_type size(const pointer &) const
{ return 0; }
//!Allocates just one object. Memory allocated with this function
//!must be deallocated only with deallocate_one().
//!Throws boost::container::bad_alloc if there is no enough memory
pointer allocate_one()
{ return pointer(0); }
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated
//!with other functions different from allocate_one(). Never throws
void deallocate_one(const pointer &)
{}
};
//!Equality test for same type of dummy_test_allocator
template<class T> inline
bool operator==(const dummy_test_allocator<T> &,
const dummy_test_allocator<T> &)
{ return false; }
//!Inequality test for same type of dummy_test_allocator
template<class T> inline
bool operator!=(const dummy_test_allocator<T> &,
const dummy_test_allocator<T> &)
{ return true; }
} //namespace test {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_DUMMY_TEST_ALLOCATOR_HPP
+625
View File
@@ -0,0 +1,625 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008. 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_EMPLACE_TEST_HPP
#define BOOST_CONTAINER_TEST_EMPLACE_TEST_HPP
#include <iostream>
#include <typeinfo>
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/move/move.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/aligned_storage.hpp>
namespace boost{
namespace container {
namespace test{
class EmplaceInt
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(EmplaceInt)
public:
EmplaceInt(int a = 0, int b = 0, int c = 0, int d = 0, int e = 0)
: a_(a), b_(b), c_(c), d_(d), e_(e)
{}
EmplaceInt(BOOST_RV_REF(EmplaceInt) o)
: a_(o.a_), b_(o.b_), c_(o.c_), d_(o.d_), e_(o.e_)
{}
EmplaceInt& operator=(BOOST_RV_REF(EmplaceInt) o)
{
this->a_ = o.a_;
this->b_ = o.b_;
this->c_ = o.c_;
this->d_ = o.d_;
this->e_ = o.e_;
return *this;
}
friend bool operator==(const EmplaceInt &l, const EmplaceInt &r)
{
return l.a_ == r.a_ &&
l.b_ == r.b_ &&
l.c_ == r.c_ &&
l.d_ == r.d_ &&
l.e_ == r.e_;
}
friend bool operator<(const EmplaceInt &l, const EmplaceInt &r)
{ return l.sum() < r.sum(); }
friend bool operator>(const EmplaceInt &l, const EmplaceInt &r)
{ return l.sum() > r.sum(); }
friend bool operator!=(const EmplaceInt &l, const EmplaceInt &r)
{ return !(l == r); }
friend std::ostream &operator <<(std::ostream &os, const EmplaceInt &v)
{
os << "EmplaceInt: " << v.a_ << ' ' << v.b_ << ' ' << v.c_ << ' ' << v.d_ << ' ' << v.e_;
return os;
}
~EmplaceInt()
{ a_ = b_ = c_ = d_ = e_ = 0; }
//private:
int sum() const
{ return this->a_ + this->b_ + this->c_ + this->d_ + this->e_; }
int a_, b_, c_, d_, e_;
int padding[6];
};
} //namespace test {
namespace test {
enum EmplaceOptions{
EMPLACE_BACK = 1 << 0,
EMPLACE_FRONT = 1 << 1,
EMPLACE_BEFORE = 1 << 2,
EMPLACE_AFTER = 1 << 3,
EMPLACE_ASSOC = 1 << 4,
EMPLACE_HINT = 1 << 5,
EMPLACE_ASSOC_PAIR = 1 << 6,
EMPLACE_HINT_PAIR = 1 << 7
};
template<class Container>
bool test_expected_container(const Container &ec, const EmplaceInt *Expected, unsigned int only_first_n)
{
typedef typename Container::const_iterator const_iterator;
const_iterator itb(ec.begin()), ite(ec.end());
unsigned int cur = 0;
if(only_first_n > ec.size()){
return false;
}
for(; itb != ite && only_first_n--; ++itb, ++cur){
const EmplaceInt & cr = *itb;
if(cr != Expected[cur]){
return false;
}
}
return true;
}
template<class Container>
bool test_expected_container(const Container &ec, const std::pair<EmplaceInt, EmplaceInt> *Expected, unsigned int only_first_n)
{
typedef typename Container::const_iterator const_iterator;
const_iterator itb(ec.begin()), ite(ec.end());
unsigned int cur = 0;
if(only_first_n > ec.size()){
return false;
}
for(; itb != ite && only_first_n--; ++itb, ++cur){
if(itb->first != Expected[cur].first){
std::cout << "Error in first: " << itb->first << ' ' << Expected[cur].first << std::endl;
return false;
}
else if(itb->second != Expected[cur].second){
std::cout << "Error in second: " << itb->second << ' ' << Expected[cur].second << std::endl;
return false;
}
}
return true;
}
static EmplaceInt expected [10];
typedef std::pair<EmplaceInt, EmplaceInt> EmplaceIntPair;
static boost::aligned_storage<sizeof(EmplaceIntPair)*10>::type pair_storage;
static EmplaceIntPair* initialize_emplace_int_pair()
{
EmplaceIntPair* ret = reinterpret_cast<EmplaceIntPair*>(&pair_storage);
for(unsigned int i = 0; i != 10; ++i){
new(&ret->first)EmplaceInt();
new(&ret->second)EmplaceInt();
}
return ret;
}
static EmplaceIntPair * expected_pair = initialize_emplace_int_pair();
template<class Container>
bool test_emplace_back(containers_detail::true_)
{
std::cout << "Starting test_emplace_back." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
{
new(&expected [0]) EmplaceInt();
new(&expected [1]) EmplaceInt(1);
new(&expected [2]) EmplaceInt(1, 2);
new(&expected [3]) EmplaceInt(1, 2, 3);
new(&expected [4]) EmplaceInt(1, 2, 3, 4);
new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
Container c;
c.emplace_back();
if(!test_expected_container(c, &expected[0], 1))
return false;
c.emplace_back(1);
if(!test_expected_container(c, &expected[0], 2))
return false;
c.emplace_back(1, 2);
if(!test_expected_container(c, &expected[0], 3))
return false;
c.emplace_back(1, 2, 3);
if(!test_expected_container(c, &expected[0], 4))
return false;
c.emplace_back(1, 2, 3, 4);
if(!test_expected_container(c, &expected[0], 5))
return false;
c.emplace_back(1, 2, 3, 4, 5);
if(!test_expected_container(c, &expected[0], 6))
return false;
}
return true;
}
template<class Container>
bool test_emplace_back(containers_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_front(containers_detail::true_)
{
std::cout << "Starting test_emplace_front." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
{
new(&expected [0]) EmplaceInt(1, 2, 3, 4, 5);
new(&expected [1]) EmplaceInt(1, 2, 3, 4);
new(&expected [2]) EmplaceInt(1, 2, 3);
new(&expected [3]) EmplaceInt(1, 2);
new(&expected [4]) EmplaceInt(1);
new(&expected [5]) EmplaceInt();
Container c;
c.emplace_front();
if(!test_expected_container(c, &expected[0] + 5, 1))
return false;
c.emplace_front(1);/*
if(!test_expected_container(c, &expected[0] + 4, 2))
return false;
c.emplace_front(1, 2);
if(!test_expected_container(c, &expected[0] + 3, 3))
return false;
c.emplace_front(1, 2, 3);
if(!test_expected_container(c, &expected[0] + 2, 4))
return false;
c.emplace_front(1, 2, 3, 4);
if(!test_expected_container(c, &expected[0] + 1, 5))
return false;
c.emplace_front(1, 2, 3, 4, 5);
if(!test_expected_container(c, &expected[0] + 0, 6))
return false;*/
}
return true;
}
template<class Container>
bool test_emplace_front(containers_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_before(containers_detail::true_)
{
std::cout << "Starting test_emplace_before." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
{
new(&expected [0]) EmplaceInt();
new(&expected [1]) EmplaceInt(1);
new(&expected [2]) EmplaceInt();
Container c;
c.emplace(c.cend(), 1);
c.emplace(c.cbegin());
if(!test_expected_container(c, &expected[0], 2))
return false;
c.emplace(c.cend());
if(!test_expected_container(c, &expected[0], 3))
return false;
}
{
new(&expected [0]) EmplaceInt();
new(&expected [1]) EmplaceInt(1);
new(&expected [2]) EmplaceInt(1, 2);
new(&expected [3]) EmplaceInt(1, 2, 3);
new(&expected [4]) EmplaceInt(1, 2, 3, 4);
new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
//emplace_front-like
Container c;
c.emplace(c.cbegin(), 1, 2, 3, 4, 5);
c.emplace(c.cbegin(), 1, 2, 3, 4);
c.emplace(c.cbegin(), 1, 2, 3);
c.emplace(c.cbegin(), 1, 2);
c.emplace(c.cbegin(), 1);
c.emplace(c.cbegin());
if(!test_expected_container(c, &expected[0], 6))
return false;
c.clear();
//emplace_back-like
typename Container::const_iterator i = c.emplace(c.cend());
if(!test_expected_container(c, &expected[0], 1))
return false;
i = c.emplace(++i, 1);
if(!test_expected_container(c, &expected[0], 2))
return false;
i = c.emplace(++i, 1, 2);
if(!test_expected_container(c, &expected[0], 3))
return false;
i = c.emplace(++i, 1, 2, 3);
if(!test_expected_container(c, &expected[0], 4))
return false;
i = c.emplace(++i, 1, 2, 3, 4);
if(!test_expected_container(c, &expected[0], 5))
return false;
i = c.emplace(++i, 1, 2, 3, 4, 5);
if(!test_expected_container(c, &expected[0], 6))
return false;
c.clear();
//emplace in the middle
c.emplace(c.cbegin());
i = c.emplace(c.cend(), 1, 2, 3, 4, 5);
i = c.emplace(i, 1, 2, 3, 4);
i = c.emplace(i, 1, 2, 3);
i = c.emplace(i, 1, 2);
i = c.emplace(i, 1);
if(!test_expected_container(c, &expected[0], 6))
return false;
}
return true;
}
template<class Container>
bool test_emplace_before(containers_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_after(containers_detail::true_)
{
std::cout << "Starting test_emplace_after." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
{
new(&expected [0]) EmplaceInt();
new(&expected [1]) EmplaceInt(1);
new(&expected [2]) EmplaceInt();
Container c;
typename Container::const_iterator i = c.emplace_after(c.cbefore_begin(), 1);
c.emplace_after(c.cbefore_begin());
if(!test_expected_container(c, &expected[0], 2))
return false;
c.emplace_after(i);
if(!test_expected_container(c, &expected[0], 3))
return false;
}
{
new(&expected [0]) EmplaceInt();
new(&expected [1]) EmplaceInt(1);
new(&expected [2]) EmplaceInt(1, 2);
new(&expected [3]) EmplaceInt(1, 2, 3);
new(&expected [4]) EmplaceInt(1, 2, 3, 4);
new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
//emplace_front-like
Container c;
c.emplace_after(c.cbefore_begin(), 1, 2, 3, 4, 5);
c.emplace_after(c.cbefore_begin(), 1, 2, 3, 4);
c.emplace_after(c.cbefore_begin(), 1, 2, 3);
c.emplace_after(c.cbefore_begin(), 1, 2);
c.emplace_after(c.cbefore_begin(), 1);
c.emplace_after(c.cbefore_begin());
if(!test_expected_container(c, &expected[0], 6))
return false;
c.clear();
//emplace_back-like
typename Container::const_iterator i = c.emplace_after(c.cbefore_begin());
if(!test_expected_container(c, &expected[0], 1))
return false;
i = c.emplace_after(i, 1);
if(!test_expected_container(c, &expected[0], 2))
return false;
i = c.emplace_after(i, 1, 2);
if(!test_expected_container(c, &expected[0], 3))
return false;
i = c.emplace_after(i, 1, 2, 3);
if(!test_expected_container(c, &expected[0], 4))
return false;
i = c.emplace_after(i, 1, 2, 3, 4);
if(!test_expected_container(c, &expected[0], 5))
return false;
i = c.emplace_after(i, 1, 2, 3, 4, 5);
if(!test_expected_container(c, &expected[0], 6))
return false;
c.clear();
//emplace_after in the middle
i = c.emplace_after(c.cbefore_begin());
c.emplace_after(i, 1, 2, 3, 4, 5);
c.emplace_after(i, 1, 2, 3, 4);
c.emplace_after(i, 1, 2, 3);
c.emplace_after(i, 1, 2);
c.emplace_after(i, 1);
if(!test_expected_container(c, &expected[0], 6))
return false;
}
return true;
}
template<class Container>
bool test_emplace_after(containers_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_assoc(containers_detail::true_)
{
std::cout << "Starting test_emplace_assoc." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
new(&expected [0]) EmplaceInt();
new(&expected [1]) EmplaceInt(1);
new(&expected [2]) EmplaceInt(1, 2);
new(&expected [3]) EmplaceInt(1, 2, 3);
new(&expected [4]) EmplaceInt(1, 2, 3, 4);
new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
{
Container c;
c.emplace();
if(!test_expected_container(c, &expected[0], 1))
return false;
c.emplace(1);
if(!test_expected_container(c, &expected[0], 2))
return false;
c.emplace(1, 2);
if(!test_expected_container(c, &expected[0], 3))
return false;
c.emplace(1, 2, 3);
if(!test_expected_container(c, &expected[0], 4))
return false;
c.emplace(1, 2, 3, 4);
if(!test_expected_container(c, &expected[0], 5))
return false;
c.emplace(1, 2, 3, 4, 5);
if(!test_expected_container(c, &expected[0], 6))
return false;
}
return true;
}
template<class Container>
bool test_emplace_assoc(containers_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_hint(containers_detail::true_)
{
std::cout << "Starting test_emplace_hint." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
new(&expected [0]) EmplaceInt();
new(&expected [1]) EmplaceInt(1);
new(&expected [2]) EmplaceInt(1, 2);
new(&expected [3]) EmplaceInt(1, 2, 3);
new(&expected [4]) EmplaceInt(1, 2, 3, 4);
new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
{
Container c;
typename Container::const_iterator it;
it = c.emplace_hint(c.begin());
if(!test_expected_container(c, &expected[0], 1))
return false;
it = c.emplace_hint(it, 1);
if(!test_expected_container(c, &expected[0], 2))
return false;
it = c.emplace_hint(it, 1, 2);
if(!test_expected_container(c, &expected[0], 3))
return false;
it = c.emplace_hint(it, 1, 2, 3);
if(!test_expected_container(c, &expected[0], 4))
return false;
it = c.emplace_hint(it, 1, 2, 3, 4);
if(!test_expected_container(c, &expected[0], 5))
return false;
it = c.emplace_hint(it, 1, 2, 3, 4, 5);
if(!test_expected_container(c, &expected[0], 6))
return false;
}
return true;
}
template<class Container>
bool test_emplace_hint(containers_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_assoc_pair(containers_detail::true_)
{
std::cout << "Starting test_emplace_assoc_pair." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
new(&expected_pair[0].first) EmplaceInt();
new(&expected_pair[0].second) EmplaceInt();
new(&expected_pair[1].first) EmplaceInt(1);
new(&expected_pair[1].second) EmplaceInt();
new(&expected_pair[2].first) EmplaceInt(2);
new(&expected_pair[2].second) EmplaceInt(2);
new(&expected_pair[3].first) EmplaceInt(3);
new(&expected_pair[3].second) EmplaceInt(2, 3);
new(&expected_pair[4].first) EmplaceInt(4);
new(&expected_pair[4].second) EmplaceInt(2, 3, 4);
new(&expected_pair[5].first) EmplaceInt(5);
new(&expected_pair[5].second) EmplaceInt(2, 3, 4, 5);
{
Container c;
c.emplace();
if(!test_expected_container(c, &expected_pair[0], 1)){
std::cout << "Error after c.emplace();\n";
return false;
}
c.emplace(1);
if(!test_expected_container(c, &expected_pair[0], 2)){
std::cout << "Error after c.emplace(1);\n";
return false;
}
c.emplace(2, 2);
if(!test_expected_container(c, &expected_pair[0], 3)){
std::cout << "Error after c.emplace(2, 2);\n";
return false;
}
c.emplace(3, 2, 3);
if(!test_expected_container(c, &expected_pair[0], 4)){
std::cout << "Error after c.emplace(3, 2, 3);\n";
return false;
}
c.emplace(4, 2, 3, 4);
if(!test_expected_container(c, &expected_pair[0], 5)){
std::cout << "Error after c.emplace(4, 2, 3, 4);\n";
return false;
}
c.emplace(5, 2, 3, 4, 5);
if(!test_expected_container(c, &expected_pair[0], 6)){
std::cout << "Error after c.emplace(5, 2, 3, 4, 5);\n";
return false;
}
}
return true;
}
template<class Container>
bool test_emplace_assoc_pair(containers_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_hint_pair(containers_detail::true_)
{
std::cout << "Starting test_emplace_hint_pair." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
new(&expected_pair[0].first) EmplaceInt();
new(&expected_pair[0].second) EmplaceInt();
new(&expected_pair[1].first) EmplaceInt(1);
new(&expected_pair[1].second) EmplaceInt();
new(&expected_pair[2].first) EmplaceInt(2);
new(&expected_pair[2].second) EmplaceInt(2);
new(&expected_pair[3].first) EmplaceInt(3);
new(&expected_pair[3].second) EmplaceInt(2, 3);
new(&expected_pair[4].first) EmplaceInt(4);
new(&expected_pair[4].second) EmplaceInt(2, 3, 4);
new(&expected_pair[5].first) EmplaceInt(5);
new(&expected_pair[5].second) EmplaceInt(2, 3, 4, 5);
{
Container c;
typename Container::const_iterator it;
it = c.emplace_hint(c.begin());
if(!test_expected_container(c, &expected_pair[0], 1)){
std::cout << "Error after c.emplace(1);\n";
return false;
}
it = c.emplace_hint(it, 1);
if(!test_expected_container(c, &expected_pair[0], 2)){
std::cout << "Error after c.emplace(it, 1);\n";
return false;
}
it = c.emplace_hint(it, 2, 2);
if(!test_expected_container(c, &expected_pair[0], 3)){
std::cout << "Error after c.emplace(it, 2, 2);\n";
return false;
}
it = c.emplace_hint(it, 3, 2, 3);
if(!test_expected_container(c, &expected_pair[0], 4)){
std::cout << "Error after c.emplace(it, 3, 2, 3);\n";
return false;
}
it = c.emplace_hint(it, 4, 2, 3, 4);
if(!test_expected_container(c, &expected_pair[0], 5)){
std::cout << "Error after c.emplace(it, 4, 2, 3, 4);\n";
return false;
}
it = c.emplace_hint(it, 5, 2, 3, 4, 5);
if(!test_expected_container(c, &expected_pair[0], 6)){
std::cout << "Error after c.emplace(it, 5, 2, 3, 4, 5);\n";
return false;
}
}
return true;
}
template<class Container>
bool test_emplace_hint_pair(containers_detail::false_)
{ return true; }
template <EmplaceOptions O, EmplaceOptions Mask>
struct emplace_active
{
static const bool value = (0 != (O & Mask));
typedef containers_detail::bool_<value> type;
operator type() const{ return type(); }
};
template<class Container, EmplaceOptions O>
bool test_emplace()
{
// if(!test_emplace_back<Container>(emplace_active<O, EMPLACE_BACK>()))
// return false;
if(!test_emplace_front<Container>(emplace_active<O, EMPLACE_FRONT>()))
return false;/*
if(!test_emplace_before<Container>(emplace_active<O, EMPLACE_BEFORE>()))
return false;
if(!test_emplace_after<Container>(emplace_active<O, EMPLACE_AFTER>()))
return false;
if(!test_emplace_assoc<Container>(emplace_active<O, EMPLACE_ASSOC>()))
return false;
if(!test_emplace_hint<Container>(emplace_active<O, EMPLACE_HINT>()))
return false;
if(!test_emplace_assoc_pair<Container>(emplace_active<O, EMPLACE_ASSOC_PAIR>()))
return false;
if(!test_emplace_hint_pair<Container>(emplace_active<O, EMPLACE_HINT_PAIR>()))
return false;*/
return true;
}
} //namespace test{
} //namespace container {
} //namespace boost{
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_TEST_EMPLACE_TEST_HPP
+193
View File
@@ -0,0 +1,193 @@
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. 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_EXPAND_BWD_TEST_ALLOCATOR_HPP
#define BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/allocation_type.hpp>
#include <boost/assert.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/version_type.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
#include <stdexcept>
#include <cassert>
//!\file
//!Describes an allocator to test expand capabilities
namespace boost {
namespace container {
namespace test {
//This allocator just allows two allocations. The first one will return
//mp_buffer + m_offset configured in the constructor. The second one
//will return mp_buffer.
template<class T>
class expand_bwd_test_allocator
{
private:
typedef expand_bwd_test_allocator<T> self_t;
typedef void * aux_pointer_t;
typedef const void * cvoid_ptr;
template<class T2>
expand_bwd_test_allocator& operator=(const expand_bwd_test_allocator<T2>&);
expand_bwd_test_allocator& operator=(const expand_bwd_test_allocator&);
public:
typedef T value_type;
typedef T * pointer;
typedef const T * const_pointer;
typedef typename containers_detail::add_reference
<value_type>::type reference;
typedef typename containers_detail::add_reference
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef boost::container::containers_detail::version_type<expand_bwd_test_allocator, 2> version;
template<class T2>
struct rebind
{ typedef expand_bwd_test_allocator<T2> other; };
//!Constructor from the segment manager. Never throws
expand_bwd_test_allocator(T *buffer, size_type size, difference_type offset)
: mp_buffer(buffer), m_size(size)
, m_offset(offset), m_allocations(0){ }
//!Constructor from other expand_bwd_test_allocator. Never throws
expand_bwd_test_allocator(const expand_bwd_test_allocator &other)
: mp_buffer(other.mp_buffer), m_size(other.m_size)
, m_offset(other.m_offset), m_allocations(0){ }
//!Constructor from related expand_bwd_test_allocator. Never throws
template<class T2>
expand_bwd_test_allocator(const expand_bwd_test_allocator<T2> &other)
: mp_buffer(other.mp_buffer), m_size(other.m_size)
, m_offset(other.m_offset), m_allocations(0){ }
pointer address(reference value)
{ return pointer(addressof(value)); }
const_pointer address(const_reference value) const
{ return const_pointer(addressof(value)); }
pointer allocate(size_type , cvoid_ptr hint = 0)
{ (void)hint; return 0; }
void deallocate(const pointer &, size_type)
{}
template<class Convertible>
void construct(pointer ptr, const Convertible &value)
{ new((void*)ptr) value_type(value); }
void destroy(pointer ptr)
{ (*ptr).~value_type(); }
size_type max_size() const
{ return m_size; }
friend void swap(self_t &alloc1, self_t &alloc2)
{
containers_detail::do_swap(alloc1.mp_buffer, alloc2.mp_buffer);
containers_detail::do_swap(alloc1.m_size, alloc2.m_size);
containers_detail::do_swap(alloc1.m_offset, alloc2.m_offset);
}
//Experimental version 2 expand_bwd_test_allocator functions
std::pair<pointer, bool>
allocation_command(boost::container::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0)
{
(void)preferred_size; (void)reuse; (void)command;
//This allocator only expands backwards!
assert(m_allocations == 0 || (command & boost::container::expand_bwd));
received_size = limit_size;
if(m_allocations == 0){
if((m_offset + limit_size) > m_size){
assert(0);
}
++m_allocations;
return std::pair<pointer, bool>(mp_buffer + m_offset, false);
}
else if(m_allocations == 1){
if(limit_size > m_size){
assert(0);
}
++m_allocations;
return std::pair<pointer, bool>(mp_buffer, true);
}
else{
assert(0);
throw std::bad_alloc();
}
}
//!Returns maximum the number of objects the previously allocated memory
//!pointed by p can hold.
size_type size(const pointer &p) const
{ (void)p; return m_size; }
//!Allocates just one object. Memory allocated with this function
//!must be deallocated only with deallocate_one().
//!Throws boost::container::bad_alloc if there is no enough memory
pointer allocate_one()
{ return this->allocate(1); }
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated
//!with other functions different from allocate_one(). Never throws
void deallocate_one(const pointer &p)
{ return this->deallocate(p, 1); }
pointer mp_buffer;
size_type m_size;
difference_type m_offset;
char m_allocations;
};
//!Equality test for same type of expand_bwd_test_allocator
template<class T> inline
bool operator==(const expand_bwd_test_allocator<T> &alloc1,
const expand_bwd_test_allocator<T> &alloc2)
{ return false; }
//!Inequality test for same type of expand_bwd_test_allocator
template<class T> inline
bool operator!=(const expand_bwd_test_allocator<T> &alloc1,
const expand_bwd_test_allocator<T> &alloc2)
{ return true; }
} //namespace test {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP
+269
View File
@@ -0,0 +1,269 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006. 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_ALLOCATION_TEST_TEMPLATE_HEADER
#define BOOST_CONTAINER_TEST_ALLOCATION_TEST_TEMPLATE_HEADER
#include <boost/container/detail/config_begin.hpp>
#include <vector>
#include <typeinfo>
#include "expand_bwd_test_allocator.hpp"
#include <algorithm>
#include <boost/type_traits/remove_volatile.hpp>
namespace boost { namespace container { namespace test {
template<class T>
struct value_holder
{
value_holder(T val) : m_value(val){}
value_holder(): m_value(0){}
~value_holder(){ m_value = 0; }
bool operator == (const value_holder &other) const
{ return m_value == other.m_value; }
bool operator != (const value_holder &other) const
{ return m_value != other.m_value; }
T m_value;
};
template<class T>
struct triple_value_holder
{
triple_value_holder(T val)
: m_value1(val)
, m_value2(val)
, m_value3(val)
{}
triple_value_holder()
: m_value1(0)
, m_value2(0)
, m_value3(0)
{}
~triple_value_holder()
{ m_value1 = m_value2 = m_value3 = 0; }
bool operator == (const triple_value_holder &other) const
{
return m_value1 == other.m_value1
&& m_value2 == other.m_value2
&& m_value3 == other.m_value3;
}
bool operator != (const triple_value_holder &other) const
{
return m_value1 != other.m_value1
|| m_value2 != other.m_value2
|| m_value3 != other.m_value3;
}
T m_value1;
T m_value2;
T m_value3;
};
typedef value_holder<int> int_holder;
typedef triple_value_holder<int> triple_int_holder;
//Function to check if both sets are equal
template <class Vector1, class Vector2>
bool CheckEqualVector(const Vector1 &vector1, const Vector2 &vector2)
{
if(vector1.size() != vector2.size())
return false;
return std::equal(vector1.begin(), vector1.end(), vector2.begin());
}
template<class Vector>
bool CheckUninitializedIsZero(const Vector & v)
{
typedef typename Vector::value_type value_type;
typename Vector::size_type sz = v.size();
typename Vector::size_type extra = v.capacity() - v.size();
value_type comp(0);
const value_type *holder = &v[0] + sz;
while(extra--){
if(*holder++ != comp)
return false;
}
return true;
}
//This function tests all the possible combinations when
//inserting data in a vector and expanding backwards
template<class VectorWithExpandBwdAllocator>
bool test_insert_with_expand_bwd()
{
typedef typename VectorWithExpandBwdAllocator::value_type value_type;
typedef typename boost::remove_volatile<value_type>::type non_volatile_value_type;
typedef std::vector<non_volatile_value_type> Vect;
const int MemorySize = 1000;
//Distance old and new buffer
const int Offset[] =
{ 350, 250, 150, 150,
150, 50, 50, 50 };
//Insert position
const int Position[] =
{ 100, 100, 100, 100,
100, 100, 100, 100 };
//Initial vector size
const int InitialSize[] =
{ 200, 200, 200, 200,
200, 200, 200, 200 };
//Size of the data to insert
const int InsertSize[] =
{ 100, 100, 100, 200,
300, 25, 100, 200 };
//Number of tests
const int Iterations = sizeof(InsertSize)/sizeof(int);
for(int iteration = 0; iteration < Iterations; ++iteration)
{
value_type *memory = new value_type[MemorySize];
try {
std::vector<non_volatile_value_type> initial_data;
initial_data.resize(InitialSize[iteration]);
for(int i = 0; i < InitialSize[iteration]; ++i){
initial_data[i] = i;
}
Vect data_to_insert;
data_to_insert.resize(InsertSize[iteration]);
for(int i = 0; i < InsertSize[iteration]; ++i){
data_to_insert[i] = -i;
}
expand_bwd_test_allocator<value_type> alloc
(&memory[0], MemorySize, Offset[iteration]);
VectorWithExpandBwdAllocator vector(alloc);
vector.insert( vector.begin()
, initial_data.begin(), initial_data.end());
vector.insert( vector.begin() + Position[iteration]
, data_to_insert.begin(), data_to_insert.end());
initial_data.insert(initial_data.begin() + Position[iteration]
, data_to_insert.begin(), data_to_insert.end());
//Now check that values are equal
if(!CheckEqualVector(vector, initial_data)){
std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
<< " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
<< " Iteration: " << iteration << std::endl;
return false;
}
}
catch(...){
delete [](const_cast<non_volatile_value_type*>(memory));
throw;
}
delete [](const_cast<non_volatile_value_type*>(memory));
}
return true;
}
//This function tests all the possible combinations when
//inserting data in a vector and expanding backwards
template<class VectorWithExpandBwdAllocator>
bool test_assign_with_expand_bwd()
{
typedef typename VectorWithExpandBwdAllocator::value_type value_type;
typedef typename boost::remove_volatile<value_type>::type non_volatile_value_type;
typedef std::vector<non_volatile_value_type> Vect;
const int MemorySize = 200;
const int Offset[] = { 50, 50, 50};
const int InitialSize[] = { 25, 25, 25};
const int AssignSize[] = { 40, 60, 80};
const int Iterations = sizeof(AssignSize)/sizeof(int);
for(int iteration = 0; iteration <Iterations; ++iteration)
{
value_type *memory = new value_type[MemorySize];
try {
//Create initial data
std::vector<non_volatile_value_type> initial_data;
initial_data.resize(InitialSize[iteration]);
for(int i = 0; i < InitialSize[iteration]; ++i){
initial_data[i] = i;
}
//Create data to assign
std::vector<non_volatile_value_type> data_to_assign;
data_to_assign.resize(AssignSize[iteration]);
for(int i = 0; i < AssignSize[iteration]; ++i){
data_to_assign[i] = -i;
}
//Insert initial data to the vector to test
expand_bwd_test_allocator<value_type> alloc
(&memory[0], MemorySize, Offset[iteration]);
VectorWithExpandBwdAllocator vector(alloc);
vector.insert( vector.begin()
, initial_data.begin(), initial_data.end());
//Assign data
vector.assign(data_to_assign.begin(), data_to_assign.end());
initial_data.assign(data_to_assign.begin(), data_to_assign.end());
//Now check that values are equal
if(!CheckEqualVector(vector, initial_data)){
std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
<< " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
<< " Iteration: " << iteration << std::endl;
return false;
}
}
catch(...){
delete [](const_cast<typename boost::remove_volatile<value_type>::type*>(memory));
throw;
}
delete [](const_cast<typename boost::remove_volatile<value_type>::type*>(memory));
}
return true;
}
//This function calls all tests
template<class VectorWithExpandBwdAllocator>
bool test_all_expand_bwd()
{
std::cout << "Starting test_insert_with_expand_bwd." << std::endl << " Class: "
<< typeid(VectorWithExpandBwdAllocator).name() << std::endl;
if(!test_insert_with_expand_bwd<VectorWithExpandBwdAllocator>()){
std::cout << "test_allocation_direct_deallocation failed. Class: "
<< typeid(VectorWithExpandBwdAllocator).name() << std::endl;
return false;
}
std::cout << "Starting test_assign_with_expand_bwd." << std::endl << " Class: "
<< typeid(VectorWithExpandBwdAllocator).name() << std::endl;
if(!test_assign_with_expand_bwd<VectorWithExpandBwdAllocator>()){
std::cout << "test_allocation_direct_deallocation failed. Class: "
<< typeid(VectorWithExpandBwdAllocator).name() << std::endl;
return false;
}
return true;
}
}}} //namespace boost { namespace container { namespace test {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_TEST_ALLOCATION_TEST_TEMPLATE_HEADER
+333
View File
@@ -0,0 +1,333 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <set>
#include <boost/container/flat_set.hpp>
#include <boost/container/flat_map.hpp>
#include "print_container.hpp"
#include "dummy_test_allocator.hpp"
#include "movable_int.hpp"
#include "set_test.hpp"
#include "map_test.hpp"
#include "emplace_test.hpp"
using namespace boost::container;
//Alias allocator type
typedef std::allocator<int> allocator_t;
typedef std::allocator<test::movable_int>
movable_allocator_t;
typedef std::allocator<std::pair<int, int> >
pair_allocator_t;
typedef std::allocator<std::pair<test::movable_int, test::movable_int> >
movable_pair_allocator_t;
typedef std::allocator<test::movable_and_copyable_int >
move_copy_allocator_t;
typedef std::allocator<std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
move_copy_pair_allocator_t;
typedef std::allocator<test::copyable_int >
copy_allocator_t;
typedef std::allocator<std::pair<test::copyable_int, test::copyable_int> >
copy_pair_allocator_t;
//Alias set types
typedef std::set<int> MyStdSet;
typedef std::multiset<int> MyStdMultiSet;
typedef std::map<int, int> MyStdMap;
typedef std::multimap<int, int> MyStdMultiMap;
typedef flat_set<int, std::less<int>, allocator_t> MyBoostSet;
typedef flat_multiset<int, std::less<int>, allocator_t> MyBoostMultiSet;
typedef flat_map<int, int, std::less<int>, pair_allocator_t> MyBoostMap;
typedef flat_multimap<int, int, std::less<int>, pair_allocator_t> MyBoostMultiMap;
typedef flat_set<test::movable_int, std::less<test::movable_int>
,movable_allocator_t> MyMovableBoostSet;
typedef flat_multiset<test::movable_int,std::less<test::movable_int>
,movable_allocator_t> MyMovableBoostMultiSet;
typedef flat_map<test::movable_int, test::movable_int
,std::less<test::movable_int>
,movable_pair_allocator_t> MyMovableBoostMap;
typedef flat_multimap<test::movable_int, test::movable_int
,std::less<test::movable_int>
,movable_pair_allocator_t> MyMovableBoostMultiMap;
typedef flat_set<test::movable_and_copyable_int, std::less<test::movable_and_copyable_int>
,move_copy_allocator_t> MyMoveCopyBoostSet;
typedef flat_multiset<test::movable_and_copyable_int,std::less<test::movable_and_copyable_int>
,move_copy_allocator_t> MyMoveCopyBoostMultiSet;
typedef flat_map<test::movable_and_copyable_int, test::movable_and_copyable_int
,std::less<test::movable_and_copyable_int>
,move_copy_pair_allocator_t> MyMoveCopyBoostMap;
typedef flat_multimap<test::movable_and_copyable_int, test::movable_and_copyable_int
,std::less<test::movable_and_copyable_int>
,move_copy_pair_allocator_t> MyMoveCopyBoostMultiMap;
typedef flat_set<test::copyable_int, std::less<test::copyable_int>
,copy_allocator_t> MyCopyBoostSet;
typedef flat_multiset<test::copyable_int,std::less<test::copyable_int>
,copy_allocator_t> MyCopyBoostMultiSet;
typedef flat_map<test::copyable_int, test::copyable_int
,std::less<test::copyable_int>
,copy_pair_allocator_t> MyCopyBoostMap;
typedef flat_multimap<test::copyable_int, test::copyable_int
,std::less<test::copyable_int>
,copy_pair_allocator_t> MyCopyBoostMultiMap;
//Test recursive structures
class recursive_flat_set
{
public:
recursive_flat_set(const recursive_flat_set &c)
: id_(c.id_), flat_set_(c.flat_set_)
{}
recursive_flat_set & operator =(const recursive_flat_set &c)
{
id_ = c.id_;
flat_set_= c.flat_set_;
return *this;
}
int id_;
flat_set<recursive_flat_set> flat_set_;
friend bool operator< (const recursive_flat_set &a, const recursive_flat_set &b)
{ return a.id_ < b.id_; }
};
class recursive_flat_map
{
public:
recursive_flat_map(const recursive_flat_map &c)
: id_(c.id_), map_(c.map_)
{}
recursive_flat_map & operator =(const recursive_flat_map &c)
{
id_ = c.id_;
map_= c.map_;
return *this;
}
int id_;
flat_map<recursive_flat_map, recursive_flat_map> map_;
friend bool operator< (const recursive_flat_map &a, const recursive_flat_map &b)
{ return a.id_ < b.id_; }
};
//Test recursive structures
class recursive_flat_multiset
{
public:
recursive_flat_multiset(const recursive_flat_multiset &c)
: id_(c.id_), flat_set_(c.flat_set_)
{}
recursive_flat_multiset & operator =(const recursive_flat_multiset &c)
{
id_ = c.id_;
flat_set_= c.flat_set_;
return *this;
}
int id_;
flat_multiset<recursive_flat_multiset> flat_set_;
friend bool operator< (const recursive_flat_multiset &a, const recursive_flat_multiset &b)
{ return a.id_ < b.id_; }
};
class recursive_flat_multimap
{
public:
recursive_flat_multimap(const recursive_flat_multimap &c)
: id_(c.id_), map_(c.map_)
{}
recursive_flat_multimap & operator =(const recursive_flat_multimap &c)
{
id_ = c.id_;
map_= c.map_;
return *this;
}
int id_;
flat_map<recursive_flat_multimap, recursive_flat_multimap> map_;
friend bool operator< (const recursive_flat_multimap &a, const recursive_flat_multimap &b)
{ return a.id_ < b.id_; }
};
template<class C>
void test_move()
{
//Now test move semantics
C original;
C move_ctor(boost::move(original));
C move_assign;
move_assign = boost::move(move_ctor);
move_assign.swap(original);
}
int main()
{
using namespace boost::container::test;
//Now test move semantics
{
test_move<flat_set<recursive_flat_set> >();
test_move<flat_multiset<recursive_flat_multiset> >();
test_move<flat_map<recursive_flat_map, recursive_flat_map> >();
test_move<flat_multimap<recursive_flat_multimap, recursive_flat_multimap> >();
}
if (0 != set_test<
MyBoostSet
,MyStdSet
,MyBoostMultiSet
,MyStdMultiSet>()){
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
return 1;
}
if (0 != set_test_copyable<
MyBoostSet
,MyStdSet
,MyBoostMultiSet
,MyStdMultiSet>()){
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
return 1;
}
if (0 != set_test<
MyMovableBoostSet
,MyStdSet
,MyMovableBoostMultiSet
,MyStdMultiSet>()){
std::cout << "Error in set_test<MyMovableBoostSet>" << std::endl;
return 1;
}
if (0 != set_test<
MyMoveCopyBoostSet
,MyStdSet
,MyMoveCopyBoostMultiSet
,MyStdMultiSet>()){
std::cout << "Error in set_test<MyMoveCopyBoostSet>" << std::endl;
return 1;
}
if (0 != set_test_copyable<
MyMoveCopyBoostSet
,MyStdSet
,MyMoveCopyBoostMultiSet
,MyStdMultiSet>()){
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
return 1;
}
if (0 != set_test<
MyCopyBoostSet
,MyStdSet
,MyCopyBoostMultiSet
,MyStdMultiSet>()){
std::cout << "Error in set_test<MyCopyBoostSet>" << std::endl;
return 1;
}
if (0 != set_test_copyable<
MyCopyBoostSet
,MyStdSet
,MyCopyBoostMultiSet
,MyStdMultiSet>()){
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
return 1;
}
if (0 != map_test<
MyBoostMap
,MyStdMap
,MyBoostMultiMap
,MyStdMultiMap>()){
std::cout << "Error in set_test<MyBoostMap>" << std::endl;
return 1;
}
if (0 != map_test_copyable<
MyBoostMap
,MyStdMap
,MyBoostMultiMap
,MyStdMultiMap>()){
std::cout << "Error in set_test<MyBoostMap>" << std::endl;
return 1;
}
// if (0 != map_test<
// MyMovableBoostMap
// ,MyStdMap
// ,MyMovableBoostMultiMap
// ,MyStdMultiMap>()){
// return 1;
// }
if (0 != map_test<
MyMoveCopyBoostMap
,MyStdMap
,MyMoveCopyBoostMultiMap
,MyStdMultiMap>()){
std::cout << "Error in set_test<MyMoveCopyBoostMap>" << std::endl;
return 1;
}
if (0 != map_test_copyable<
MyMoveCopyBoostMap
,MyStdMap
,MyMoveCopyBoostMultiMap
,MyStdMultiMap>()){
std::cout << "Error in set_test<MyBoostMap>" << std::endl;
return 1;
}
if (0 != map_test<
MyCopyBoostMap
,MyStdMap
,MyCopyBoostMultiMap
,MyStdMultiMap>()){
std::cout << "Error in set_test<MyCopyBoostMap>" << std::endl;
return 1;
}
if (0 != map_test_copyable<
MyCopyBoostMap
,MyStdMap
,MyCopyBoostMultiMap
,MyStdMultiMap>()){
std::cout << "Error in set_test<MyBoostMap>" << std::endl;
return 1;
}
const test::EmplaceOptions SetOptions = (test::EmplaceOptions)(test::EMPLACE_HINT | test::EMPLACE_ASSOC);
const test::EmplaceOptions MapOptions = (test::EmplaceOptions)(test::EMPLACE_HINT_PAIR | test::EMPLACE_ASSOC_PAIR);
// if(!boost::container::test::test_emplace<flat_map<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
// return 1;
if(!boost::container::test::test_emplace<flat_multimap<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
return 1;
if(!boost::container::test::test_emplace<flat_set<test::EmplaceInt>, SetOptions>())
return 1;
if(!boost::container::test::test_emplace<flat_multiset<test::EmplaceInt>, SetOptions>())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>
+159
View File
@@ -0,0 +1,159 @@
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. 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_HEAP_ALLOCATOR_V1_HPP
#define BOOST_CONTAINER_HEAP_ALLOCATOR_V1_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/pointer_to_other.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/allocation_type.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/exceptions.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
#include <stdexcept>
//!\file
//!Describes an heap_allocator_v1 that allocates portions of fixed size
//!memory buffer (shared memory, mapped file...)
namespace boost {
namespace container {
namespace test {
//!An STL compatible heap_allocator_v1 that uses a segment manager as
//!memory source. The internal pointer type will of the same type (raw, smart) as
//!"typename SegmentManager::void_pointer" type. This allows
//!placing the heap_allocator_v1 in shared memory, memory mapped-files, etc...*/
template<class T, class SegmentManager>
class heap_allocator_v1
{
private:
typedef heap_allocator_v1<T, SegmentManager> self_t;
typedef SegmentManager segment_manager;
typedef typename segment_manager::void_pointer aux_pointer_t;
typedef typename
boost::pointer_to_other
<aux_pointer_t, const void>::type cvoid_ptr;
typedef typename boost::pointer_to_other
<cvoid_ptr, segment_manager>::type alloc_ptr_t;
template<class T2, class SegmentManager2>
heap_allocator_v1& operator=(const heap_allocator_v1<T2, SegmentManager2>&);
heap_allocator_v1& operator=(const heap_allocator_v1&);
alloc_ptr_t mp_mngr;
public:
typedef T value_type;
typedef typename boost::pointer_to_other
<cvoid_ptr, T>::type pointer;
typedef typename boost::
pointer_to_other<pointer, const T>::type const_pointer;
typedef typename detail::add_reference
<value_type>::type reference;
typedef typename detail::add_reference
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
//!Obtains an heap_allocator_v1 of other type
template<class T2>
struct rebind
{
typedef heap_allocator_v1<T2, SegmentManager> other;
};
//!Returns the segment manager. Never throws
segment_manager* get_segment_manager()const
{ return detail::get_pointer(mp_mngr); }
/*
//!Returns address of mutable object. Never throws
pointer address(reference value) const
{ return pointer(addressof(value)); }
//!Returns address of non mutable object. Never throws
const_pointer address(const_reference value) const
{ return const_pointer(addressof(value)); }
*/
//!Constructor from the segment manager. Never throws
heap_allocator_v1(segment_manager *segment_mngr)
: mp_mngr(segment_mngr) { }
//!Constructor from other heap_allocator_v1. Never throws
heap_allocator_v1(const heap_allocator_v1 &other)
: mp_mngr(other.get_segment_manager()){ }
//!Constructor from related heap_allocator_v1. Never throws
template<class T2>
heap_allocator_v1(const heap_allocator_v1<T2, SegmentManager> &other)
: mp_mngr(other.get_segment_manager()){}
//!Allocates memory for an array of count elements.
//!Throws boost::container::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_ptr hint = 0)
{ (void)hint; return ::new value_type[count]; }
//!Deallocates memory previously allocated. Never throws
void deallocate(const pointer &ptr, size_type)
{ return ::delete[] detail::get_pointer(ptr) ; }
//!Construct object, calling constructor.
//!Throws if T(const T&) throws
void construct(const pointer &ptr, const_reference value)
{ new((void*)detail::get_pointer(ptr)) value_type(value); }
//!Destroys object. Throws if object's destructor throws
void destroy(const pointer &ptr)
{ BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
//!Returns the number of elements that could be allocated. Never throws
size_type max_size() const
{ return mp_mngr->get_size(); }
//!Swap segment manager. Does not throw. If each heap_allocator_v1 is placed in
//!different memory segments, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
{ detail::do_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
};
//!Equality test for same type of heap_allocator_v1
template<class T, class SegmentManager> inline
bool operator==(const heap_allocator_v1<T , SegmentManager> &alloc1,
const heap_allocator_v1<T, SegmentManager> &alloc2)
{ return alloc1.get_segment_manager() == alloc2.get_segment_manager(); }
//!Inequality test for same type of heap_allocator_v1
template<class T, class SegmentManager> inline
bool operator!=(const heap_allocator_v1<T, SegmentManager> &alloc1,
const heap_allocator_v1<T, SegmentManager> &alloc2)
{ return alloc1.get_segment_manager() != alloc2.get_segment_manager(); }
} //namespace test {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_HEAP_ALLOCATOR_V1_HPP
+78
View File
@@ -0,0 +1,78 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/list.hpp>
#include "dummy_test_allocator.hpp"
#include "movable_int.hpp"
#include "list_test.hpp"
#include "emplace_test.hpp"
using namespace boost::container;
//Explicit instantiation to detect compilation errors
template class boost::container::list<test::movable_and_copyable_int,
test::dummy_test_allocator<test::movable_and_copyable_int> >;
typedef list<int> MyList;
typedef list<test::movable_int> MyMoveList;
typedef list<test::movable_and_copyable_int> MyCopyMoveList;
typedef list<test::copyable_int> MyCopyList;
class recursive_list
{
public:
int id_;
list<recursive_list> list_;
recursive_list &operator=(const recursive_list &o)
{ list_ = o.list_; return *this; }
};
void recursive_list_test()//Test for recursive types
{
list<recursive_list> recursive, copy;
//Test to test both move emulations
if(!copy.size()){
copy = recursive;
}
}
int main ()
{
recursive_list_test();
{
//Now test move semantics
list<recursive_list> original;
list<recursive_list> move_ctor(boost::move(original));
list<recursive_list> move_assign;
move_assign = boost::move(move_ctor);
move_assign.swap(original);
}
if(test::list_test<MyList, true>())
return 1;
if(test::list_test<MyMoveList, true>())
return 1;
if(test::list_test<MyCopyMoveList, true>())
return 1;
if(test::list_test<MyCopyList, true>())
return 1;
const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE);
if(!boost::container::test::test_emplace<list<test::EmplaceInt>, Options>())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>
+312
View File
@@ -0,0 +1,312 @@
////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006. 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_LIST_TEST_HEADER
#define BOOST_CONTAINER_TEST_LIST_TEST_HEADER
#include <boost/container/detail/config_begin.hpp>
#include "check_equal_containers.hpp"
#include <memory>
#include <list>
#include <vector>
#include <functional>
#include "print_container.hpp"
#include <boost/move/move.hpp>
#include <string>
namespace boost{
namespace container {
namespace test{
template<class V1, class V2>
bool list_copyable_only(V1 *, V2 *, boost::container::containers_detail::false_type)
{
return true;
}
//Function to check if both sets are equal
template<class V1, class V2>
bool list_copyable_only(V1 *boostlist, V2 *stdlist, boost::container::containers_detail::true_type)
{
typedef typename V1::value_type IntType;
boostlist->insert(boostlist->end(), 50, IntType(1));
stdlist->insert(stdlist->end(), 50, 1);
if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
{
IntType move_me(1);
boostlist->insert(boostlist->begin(), 50, boost::move(move_me));
stdlist->insert(stdlist->begin(), 50, 1);
if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
}
{
IntType move_me(2);
boostlist->assign(boostlist->size()/2, boost::move(move_me));
stdlist->assign(stdlist->size()/2, 2);
if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
}
{
IntType move_me(3);
boostlist->assign(boostlist->size()*3-1, boost::move(move_me));
stdlist->assign(stdlist->size()*3-1, 3);
if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
}
{
IntType copy_me(3);
const IntType ccopy_me(3);
boostlist->push_front(copy_me);
stdlist->push_front(int(3));
boostlist->push_front(ccopy_me);
stdlist->push_front(int(3));
if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
}
return true;
}
template<bool DoublyLinked>
struct list_push_data_function
{
template<class MyBoostList, class MyStdList>
static int execute(int max, MyBoostList *boostlist, MyStdList *stdlist)
{
typedef typename MyBoostList::value_type IntType;
for(int i = 0; i < max; ++i){
IntType move_me(i);
boostlist->push_back(boost::move(move_me));
stdlist->push_back(i);
boostlist->push_front(IntType(i));
stdlist->push_front(int(i));
}
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
return 0;
}
};
template<>
struct list_push_data_function<false>
{
template<class MyBoostList, class MyStdList>
static int execute(int max, MyBoostList *boostlist, MyStdList *stdlist)
{
typedef typename MyBoostList::value_type IntType;
for(int i = 0; i < max; ++i){
IntType move_me(i);
boostlist->push_front(boost::move(move_me));
stdlist->push_front(i);
boostlist->push_front(IntType(i));
stdlist->push_front(int(i));
}
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
return 0;
}
};
template<bool DoublyLinked>
struct list_pop_back_function
{
template<class MyStdList, class MyBoostList>
static int execute(MyBoostList *boostlist, MyStdList *stdlist)
{
boostlist->pop_back();
stdlist->pop_back();
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
return 0;
}
};
template<>
struct list_pop_back_function<false>
{
template<class MyStdList, class MyBoostList>
static int execute(MyBoostList *boostlist, MyStdList *stdlist)
{
(void)boostlist; (void)stdlist;
return 0;
}
};
template<class MyBoostList
,bool DoublyLinked>
int list_test (bool copied_allocators_equal = true)
{
typedef std::list<int> MyStdList;
typedef typename MyBoostList::value_type IntType;
const int max = 100;
typedef list_push_data_function<DoublyLinked> push_data_t;
try{
MyBoostList *boostlist = new MyBoostList;
MyStdList *stdlist = new MyStdList;
if(push_data_t::execute(max, boostlist, stdlist)){
return 1;
}
boostlist->erase(boostlist->begin()++);
stdlist->erase(stdlist->begin()++);
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
if(list_pop_back_function<DoublyLinked>::execute(boostlist, stdlist)){
return 1;
}
boostlist->pop_front();
stdlist->pop_front();
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
boostlist->assign(boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(&aux_vect[50]));
stdlist->assign(&aux_vect2[0], &aux_vect2[50]);
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
}
if(copied_allocators_equal){
boostlist->sort();
stdlist->sort();
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
}
boostlist->reverse();
stdlist->reverse();
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
boostlist->reverse();
stdlist->reverse();
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
boostlist->insert(boostlist->begin()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(&aux_vect[50]));
stdlist->insert(stdlist->begin(), &aux_vect2[0], &aux_vect2[50]);
}
boostlist->unique();
stdlist->unique();
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
if(copied_allocators_equal){
boostlist->sort(std::greater<IntType>());
stdlist->sort(std::greater<int>());
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
}
for(int i = 0; i < max; ++i){
IntType new_int(i);
boostlist->insert(boostlist->end(), boost::move(new_int));
stdlist->insert(stdlist->end(), i);
if(!test::CheckEqualContainers(boostlist, stdlist)) return 1;
}
if(!test::CheckEqualContainers(boostlist, stdlist)) return 1;
boostlist->resize(25);
stdlist->resize(25);
boostlist->resize(50);
stdlist->resize(50);
boostlist->resize(0);
stdlist->resize(0);
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
if(push_data_t::execute(max, boostlist, stdlist)){
return 1;
}
{
MyBoostList otherboostlist(boostlist->get_allocator());
MyStdList otherstdlist;
int listsize = (int)boostlist->size();
if(push_data_t::execute(listsize, boostlist, stdlist)){
return 1;
}
if(copied_allocators_equal){
boostlist->splice(boostlist->begin(), otherboostlist);
stdlist->splice(stdlist->begin(), otherstdlist);
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
}
listsize = (int)boostlist->size();
if(push_data_t::execute(listsize, boostlist, stdlist)){
return 1;
}
if(push_data_t::execute(listsize, &otherboostlist, &otherstdlist)){
return 1;
}
if(copied_allocators_equal){
boostlist->sort(std::greater<IntType>());
stdlist->sort(std::greater<int>());
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
otherboostlist.sort(std::greater<IntType>());
otherstdlist.sort(std::greater<int>());
if(!CheckEqualContainers(&otherboostlist, &otherstdlist))
return 1;
boostlist->merge(otherboostlist, std::greater<IntType>());
stdlist->merge(otherstdlist, std::greater<int>());
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
}
if(!list_copyable_only(boostlist, stdlist
,containers_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
return 1;
}
}
delete boostlist;
delete stdlist;
}
catch(...){
throw;
}
return 0;
}
} //namespace test{
} //namespace container {
} //namespace boost{
#include <boost/container/detail/config_end.hpp>
#endif
+521
View File
@@ -0,0 +1,521 @@
////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006. 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_MAP_TEST_HEADER
#define BOOST_CONTAINER_TEST_MAP_TEST_HEADER
#include <boost/container/detail/config_begin.hpp>
#include "check_equal_containers.hpp"
#include <map>
#include <functional>
#include <utility>
#include "print_container.hpp"
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/pair.hpp>
#include <string>
template<class T1, class T2, class T3, class T4>
bool operator ==(std::pair<T1, T2> &p1, std::pair<T1, T2> &p2)
{
return p1.first == p2.first && p1.second == p2.second;
}
namespace boost{
namespace container {
namespace test{
template<class MyBoostMap
,class MyStdMap
,class MyBoostMultiMap
,class MyStdMultiMap>
int map_test ()
{
typedef typename MyBoostMap::key_type IntType;
typedef containers_detail::pair<IntType, IntType> IntPairType;
typedef typename MyStdMap::value_type StdPairType;
const int max = 100;
try{
MyBoostMap *boostmap = new MyBoostMap;
MyStdMap *stdmap = new MyStdMap;
MyBoostMultiMap *boostmultimap = new MyBoostMultiMap;
MyStdMultiMap *stdmultimap = new MyStdMultiMap;
//Test construction from a range
{
//This is really nasty, but we have no other simple choice
IntPairType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType i1(i/2);
IntType i2(i/2);
new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
}
typedef typename MyStdMap::value_type StdValueType;
typedef typename MyStdMap::key_type StdKeyType;
typedef typename MyStdMap::mapped_type StdMappedType;
StdValueType aux_vect2[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect2[i])StdValueType(StdKeyType(i/2), StdMappedType(i/2));
}
IntPairType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType i1(i/2);
IntType i2(i/2);
new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
}
MyBoostMap *boostmap2 = new MyBoostMap
( boost::make_move_iterator(&aux_vect[0])
, boost::make_move_iterator(aux_vect + 50));
MyStdMap *stdmap2 = new MyStdMap(aux_vect2, aux_vect2 + 50);
MyBoostMultiMap *boostmultimap2 = new MyBoostMultiMap
( boost::make_move_iterator(&aux_vect3[0])
, boost::make_move_iterator(aux_vect3 + 50));
MyStdMultiMap *stdmultimap2 = new MyStdMultiMap(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(boostmap2, stdmap2)) return 1;
if(!CheckEqualContainers(boostmultimap2, stdmultimap2)) return 1;
//ordered range insertion
//This is really nasty, but we have no other simple choice
for(int i = 0; i < 50; ++i){
IntType i1(i);
IntType i2(i);
new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
}
for(int i = 0; i < 50; ++i){
new(&aux_vect2[i])StdValueType(StdKeyType(i), StdMappedType(i));
}
for(int i = 0; i < 50; ++i){
IntType i1(i);
IntType i2(i);
new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
}
/*
MyBoostMap *boostmap3 = new MyBoostMap
( ordered_unique_range
, boost::make_move_iterator(&aux_vect[0])
, boost::make_move_iterator(aux_vect + 50));
MyStdMap *stdmap3 = new MyStdMap(aux_vect2, aux_vect2 + 50);
MyBoostMultiMap *boostmultimap3 = new MyBoostMultiMap
( ordered_range
, boost::make_move_iterator(&aux_vect3[0])
, boost::make_move_iterator(aux_vect3 + 50));
MyStdMultiMap *stdmultimap3 = new MyStdMultiMap(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(boostmap3, stdmap3)){
std::cout << "Error in construct<MyBoostMap>(MyBoostMap3)" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultimap3, stdmultimap3)){
std::cout << "Error in construct<MyBoostMultiMap>(MyBoostMultiMap3)" << std::endl;
return 1;
}
*/
delete boostmap2;
delete boostmultimap2;
delete stdmap2;
delete stdmultimap2;
//delete boostmap3;
//delete boostmultimap3;
//delete stdmap3;
//delete stdmultimap3;
}
{
//This is really nasty, but we have no other simple choice
IntPairType aux_vect[max];
for(int i = 0; i < max; ++i){
IntType i1(i);
IntType i2(i);
new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
}
IntPairType aux_vect3[max];
for(int i = 0; i < max; ++i){
IntType i1(i);
IntType i2(i);
new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
}
for(int i = 0; i < max; ++i){
boostmap->insert(boost::move(aux_vect[i]));
stdmap->insert(StdPairType(i, i));
boostmultimap->insert(boost::move(aux_vect3[i]));
stdmultimap->insert(StdPairType(i, i));
}
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
typename MyBoostMap::iterator it;
typename MyBoostMap::const_iterator cit = it;
boostmap->erase(boostmap->begin()++);
stdmap->erase(stdmap->begin()++);
boostmultimap->erase(boostmultimap->begin()++);
stdmultimap->erase(stdmultimap->begin()++);
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
boostmap->erase(boostmap->begin());
stdmap->erase(stdmap->begin());
boostmultimap->erase(boostmultimap->begin());
stdmultimap->erase(stdmultimap->begin());
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
//Swapping test
MyBoostMap tmpboostemap2;
MyStdMap tmpstdmap2;
MyBoostMultiMap tmpboostemultimap2;
MyStdMultiMap tmpstdmultimap2;
boostmap->swap(tmpboostemap2);
stdmap->swap(tmpstdmap2);
boostmultimap->swap(tmpboostemultimap2);
stdmultimap->swap(tmpstdmultimap2);
boostmap->swap(tmpboostemap2);
stdmap->swap(tmpstdmap2);
boostmultimap->swap(tmpboostemultimap2);
stdmultimap->swap(tmpstdmultimap2);
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
}
//Insertion from other container
//Initialize values
{
//This is really nasty, but we have no other simple choice
IntPairType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType i1(-1);
IntType i2(-1);
new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
}
IntPairType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType i1(-1);
IntType i2(-1);
new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
}
boostmap->insert(boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(aux_vect + 50));
boostmultimap->insert(boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(aux_vect3 + 50));
for(std::size_t i = 0; i != 50; ++i){
StdPairType stdpairtype(-1, -1);
stdmap->insert(stdpairtype);
stdmultimap->insert(stdpairtype);
}
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
for(int i = 0, j = static_cast<int>(boostmap->size()); i < j; ++i){
boostmap->erase(IntType(i));
stdmap->erase(i);
boostmultimap->erase(IntType(i));
stdmultimap->erase(i);
}
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
}
{
IntPairType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType i1(-1);
IntType i2(-1);
new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
}
IntPairType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType i1(-1);
IntType i2(-1);
new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
}
IntPairType aux_vect4[50];
for(int i = 0; i < 50; ++i){
IntType i1(-1);
IntType i2(-1);
new(&aux_vect4[i])IntPairType(boost::move(i1), boost::move(i2));
}
IntPairType aux_vect5[50];
for(int i = 0; i < 50; ++i){
IntType i1(-1);
IntType i2(-1);
new(&aux_vect5[i])IntPairType(boost::move(i1), boost::move(i2));
}
boostmap->insert(boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(aux_vect + 50));
boostmap->insert(boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(aux_vect3 + 50));
boostmultimap->insert(boost::make_move_iterator(&aux_vect4[0]), boost::make_move_iterator(aux_vect4 + 50));
boostmultimap->insert(boost::make_move_iterator(&aux_vect5[0]), boost::make_move_iterator(aux_vect5 + 50));
for(std::size_t i = 0; i != 50; ++i){
StdPairType stdpairtype(-1, -1);
stdmap->insert(stdpairtype);
stdmultimap->insert(stdpairtype);
stdmap->insert(stdpairtype);
stdmultimap->insert(stdpairtype);
}
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
boostmap->erase(boostmap->begin()->first);
stdmap->erase(stdmap->begin()->first);
boostmultimap->erase(boostmultimap->begin()->first);
stdmultimap->erase(stdmultimap->begin()->first);
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
}
{
//This is really nasty, but we have no other simple choice
IntPairType aux_vect[max];
for(int i = 0; i < max; ++i){
IntType i1(i);
IntType i2(i);
new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
}
IntPairType aux_vect3[max];
for(int i = 0; i < max; ++i){
IntType i1(i);
IntType i2(i);
new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
}
for(int i = 0; i < max; ++i){
boostmap->insert(boost::move(aux_vect[i]));
stdmap->insert(StdPairType(i, i));
boostmultimap->insert(boost::move(aux_vect3[i]));
stdmultimap->insert(StdPairType(i, i));
}
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
for(int i = 0; i < max; ++i){
IntPairType intpair;
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
boostmap->insert(boostmap->begin(), boost::move(intpair));
stdmap->insert(stdmap->begin(), StdPairType(i, i));
//PrintContainers(boostmap, stdmap);
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
boostmultimap->insert(boostmultimap->begin(), boost::move(intpair));
stdmultimap->insert(stdmultimap->begin(), StdPairType(i, i));
//PrintContainers(boostmultimap, stdmultimap);
if(!CheckEqualPairContainers(boostmap, stdmap))
return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap))
return 1;
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
boostmap->insert(boostmap->end(), boost::move(intpair));
stdmap->insert(stdmap->end(), StdPairType(i, i));
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
boostmultimap->insert(boostmultimap->end(), boost::move(intpair));
stdmultimap->insert(stdmultimap->end(), StdPairType(i, i));
if(!CheckEqualPairContainers(boostmap, stdmap))
return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap))
return 1;
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
boostmap->insert(boostmap->lower_bound(IntType(i)), boost::move(intpair));
stdmap->insert(stdmap->lower_bound(i), StdPairType(i, i));
//PrintContainers(boostmap, stdmap);
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
{
IntType i1(i);
boostmultimap->insert(boostmultimap->lower_bound(boost::move(i1)), boost::move(intpair));
stdmultimap->insert(stdmultimap->lower_bound(i), StdPairType(i, i));
}
//PrintContainers(boostmultimap, stdmultimap);
if(!CheckEqualPairContainers(boostmap, stdmap))
return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap))
return 1;
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
{
IntType i1(i);
boostmap->insert(boostmap->upper_bound(boost::move(i1)), boost::move(intpair));
stdmap->insert(stdmap->upper_bound(i), StdPairType(i, i));
}
//PrintContainers(boostmap, stdmap);
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
{
IntType i1(i);
boostmultimap->insert(boostmultimap->upper_bound(boost::move(i1)), boost::move(intpair));
stdmultimap->insert(stdmultimap->upper_bound(i), StdPairType(i, i));
}
//PrintContainers(boostmultimap, stdmultimap);
if(!CheckEqualPairContainers(boostmap, stdmap))
return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap))
return 1;
}
//Compare count with std containers
for(int i = 0; i < max; ++i){
if(boostmap->count(IntType(i)) != stdmap->count(i)){
return -1;
}
if(boostmultimap->count(IntType(i)) != stdmultimap->count(i)){
return -1;
}
}
//Now do count exercise
boostmap->erase(boostmap->begin(), boostmap->end());
boostmultimap->erase(boostmultimap->begin(), boostmultimap->end());
boostmap->clear();
boostmultimap->clear();
for(int j = 0; j < 3; ++j)
for(int i = 0; i < 100; ++i){
IntPairType intpair;
{
IntType i1(i), i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
boostmap->insert(boost::move(intpair));
{
IntType i1(i), i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
boostmultimap->insert(boost::move(intpair));
if(boostmap->count(IntType(i)) != typename MyBoostMultiMap::size_type(1))
return 1;
if(boostmultimap->count(IntType(i)) != typename MyBoostMultiMap::size_type(j+1))
return 1;
}
}
delete boostmap;
delete stdmap;
delete boostmultimap;
delete stdmultimap;
}
catch(...){
throw;
}
return 0;
}
template<class MyBoostMap
,class MyStdMap
,class MyBoostMultiMap
,class MyStdMultiMap>
int map_test_copyable ()
{
typedef typename MyBoostMap::key_type IntType;
typedef containers_detail::pair<IntType, IntType> IntPairType;
typedef typename MyStdMap::value_type StdPairType;
const int max = 100;
try{
MyBoostMap *boostmap = new MyBoostMap;
MyStdMap *stdmap = new MyStdMap;
MyBoostMultiMap *boostmultimap = new MyBoostMultiMap;
MyStdMultiMap *stdmultimap = new MyStdMultiMap;
int i;
for(i = 0; i < max; ++i){
{
IntType i1(i), i2(i);
IntPairType intpair1(boost::move(i1), boost::move(i2));
boostmap->insert(boost::move(intpair1));
stdmap->insert(StdPairType(i, i));
}
{
IntType i1(i), i2(i);
IntPairType intpair2(boost::move(i1), boost::move(i2));
boostmultimap->insert(boost::move(intpair2));
stdmultimap->insert(StdPairType(i, i));
}
}
if(!CheckEqualContainers(boostmap, stdmap)) return 1;
if(!CheckEqualContainers(boostmultimap, stdmultimap)) return 1;
{
//Now, test copy constructor
MyBoostMap boostmapcopy(*boostmap);
MyStdMap stdmapcopy(*stdmap);
MyBoostMultiMap boostmmapcopy(*boostmultimap);
MyStdMultiMap stdmmapcopy(*stdmultimap);
if(!CheckEqualContainers(&boostmapcopy, &stdmapcopy))
return 1;
if(!CheckEqualContainers(&boostmmapcopy, &stdmmapcopy))
return 1;
//And now assignment
boostmapcopy = *boostmap;
stdmapcopy = *stdmap;
boostmmapcopy = *boostmultimap;
stdmmapcopy = *stdmultimap;
if(!CheckEqualContainers(&boostmapcopy, &stdmapcopy))
return 1;
if(!CheckEqualContainers(&boostmmapcopy, &stdmmapcopy))
return 1;
delete boostmap;
delete boostmultimap;
delete stdmap;
delete stdmultimap;
}
}
catch(...){
throw;
}
return 0;
}
} //namespace test{
} //namespace container {
} //namespace boost{
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_TEST_MAP_TEST_HEADER
+230
View File
@@ -0,0 +1,230 @@
///////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006. 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_MOVABLE_INT_HEADER
#define BOOST_CONTAINER_TEST_MOVABLE_INT_HEADER
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/move/move.hpp>
namespace boost {
namespace container {
namespace test {
template<class T>
struct is_copyable;
template<>
struct is_copyable<int>
{
static const bool value = true;
};
class movable_int
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_int)
public:
movable_int()
: m_int(0)
{}
explicit movable_int(int a)
: m_int(a)
{}
movable_int(BOOST_RV_REF(movable_int) mmi)
: m_int(mmi.m_int)
{ mmi.m_int = 0; }
movable_int & operator= (BOOST_RV_REF(movable_int) mmi)
{ this->m_int = mmi.m_int; mmi.m_int = 0; return *this; }
movable_int & operator= (int i)
{ this->m_int = i; return *this; }
bool operator ==(const movable_int &mi) const
{ return this->m_int == mi.m_int; }
bool operator !=(const movable_int &mi) const
{ return this->m_int != mi.m_int; }
bool operator <(const movable_int &mi) const
{ return this->m_int < mi.m_int; }
bool operator <=(const movable_int &mi) const
{ return this->m_int <= mi.m_int; }
bool operator >=(const movable_int &mi) const
{ return this->m_int >= mi.m_int; }
bool operator >(const movable_int &mi) const
{ return this->m_int > mi.m_int; }
int get_int() const
{ return m_int; }
private:
int m_int;
};
template<class E, class T>
std::basic_ostream<E, T> & operator<<
(std::basic_ostream<E, T> & os, movable_int const & p)
{
os << p.get_int();
return os;
}
template<>
struct is_copyable<movable_int>
{
static const bool value = false;
};
class movable_and_copyable_int
{
BOOST_COPYABLE_AND_MOVABLE(movable_and_copyable_int)
public:
movable_and_copyable_int()
: m_int(0)
{}
explicit movable_and_copyable_int(int a)
: m_int(a)
{}
movable_and_copyable_int(const movable_and_copyable_int& mmi)
: m_int(mmi.m_int)
{}
movable_and_copyable_int(BOOST_RV_REF(movable_and_copyable_int) mmi)
: m_int(mmi.m_int)
{ mmi.m_int = 0; }
movable_and_copyable_int &operator= (BOOST_COPY_ASSIGN_REF(movable_and_copyable_int) mi)
{ this->m_int = mi.m_int; return *this; }
movable_and_copyable_int & operator= (BOOST_RV_REF(movable_and_copyable_int) mmi)
{ this->m_int = mmi.m_int; mmi.m_int = 0; return *this; }
movable_and_copyable_int & operator= (int i)
{ this->m_int = i; return *this; }
bool operator ==(const movable_and_copyable_int &mi) const
{ return this->m_int == mi.m_int; }
bool operator !=(const movable_and_copyable_int &mi) const
{ return this->m_int != mi.m_int; }
bool operator <(const movable_and_copyable_int &mi) const
{ return this->m_int < mi.m_int; }
bool operator <=(const movable_and_copyable_int &mi) const
{ return this->m_int <= mi.m_int; }
bool operator >=(const movable_and_copyable_int &mi) const
{ return this->m_int >= mi.m_int; }
bool operator >(const movable_and_copyable_int &mi) const
{ return this->m_int > mi.m_int; }
int get_int() const
{ return m_int; }
private:
int m_int;
};
template<class E, class T>
std::basic_ostream<E, T> & operator<<
(std::basic_ostream<E, T> & os, movable_and_copyable_int const & p)
{
os << p.get_int();
return os;
}
template<>
struct is_copyable<movable_and_copyable_int>
{
static const bool value = true;
};
class copyable_int
{
public:
copyable_int()
: m_int(0)
{}
explicit copyable_int(int a)
: m_int(a)
{}
copyable_int(const copyable_int& mmi)
: m_int(mmi.m_int)
{}
copyable_int & operator= (int i)
{ this->m_int = i; return *this; }
bool operator ==(const copyable_int &mi) const
{ return this->m_int == mi.m_int; }
bool operator !=(const copyable_int &mi) const
{ return this->m_int != mi.m_int; }
bool operator <(const copyable_int &mi) const
{ return this->m_int < mi.m_int; }
bool operator <=(const copyable_int &mi) const
{ return this->m_int <= mi.m_int; }
bool operator >=(const copyable_int &mi) const
{ return this->m_int >= mi.m_int; }
bool operator >(const copyable_int &mi) const
{ return this->m_int > mi.m_int; }
int get_int() const
{ return m_int; }
private:
int m_int;
};
template<class E, class T>
std::basic_ostream<E, T> & operator<<
(std::basic_ostream<E, T> & os, copyable_int const & p)
{
os << p.get_int();
return os;
}
template<>
struct is_copyable<copyable_int>
{
static const bool value = true;
};
} //namespace test {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_TEST_MOVABLE_INT_HEADER
+64
View File
@@ -0,0 +1,64 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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_PRINTCONTAINER_HPP
#define BOOST_PRINTCONTAINER_HPP
#include <boost/container/detail/config_begin.hpp>
#include <functional>
#include <iostream>
#include <algorithm>
namespace boost{
namespace container {
namespace test{
struct PrintValues : public std::unary_function<int, void>
{
void operator() (int value) const
{
std::cout << value << " ";
}
};
template<class Container>
void PrintContents(const Container &cont, const char *contName)
{
std::cout<< "Printing contents of " << contName << std::endl;
std::for_each(cont.begin(), cont.end(), PrintValues());
std::cout<< std::endl << std::endl;
}
//Function to dump data
template<class MyBoostCont
,class MyStdCont>
void PrintContainers(MyBoostCont *boostcont, MyStdCont *stdcont)
{
typename MyBoostCont::iterator itboost = boostcont->begin(), itboostend = boostcont->end();
typename MyStdCont::iterator itstd = stdcont->begin(), itstdend = stdcont->end();
std::cout << "MyBoostCont" << std::endl;
for(; itboost != itboostend; ++itboost){
std::cout << *itboost << std::endl;
}
std::cout << "MyStdCont" << std::endl;
for(; itstd != itstdend; ++itstd){
std::cout << *itstd << std::endl;
}
}
} //namespace test{
} //namespace container {
} //namespace boost{
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_PRINTCONTAINER_HPP
+504
View File
@@ -0,0 +1,504 @@
////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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_SET_TEST_HEADER
#define BOOST_CONTAINER_TEST_SET_TEST_HEADER
#include <boost/container/detail/config_begin.hpp>
#include "check_equal_containers.hpp"
#include <memory>
#include <set>
#include <functional>
#include "print_container.hpp"
#include <boost/move/move.hpp>
#include <string>
namespace boost{
namespace container {
namespace test{
template<class MyBoostSet
,class MyStdSet
,class MyBoostMultiSet
,class MyStdMultiSet>
int set_test ()
{
typedef typename MyBoostSet::value_type IntType;
const int max = 100;
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyBoostSet *boostset = new MyBoostSet;
MyStdSet *stdset = new MyStdSet;
MyBoostMultiSet *boostmultiset = new MyBoostMultiSet;
MyStdMultiSet *stdmultiset = new MyStdMultiSet;
//Test construction from a range
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(i/2);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = i/2;
}
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(i/2);
aux_vect3[i] = boost::move(move_me);
}
MyBoostSet *boostset2 = new MyBoostSet
( boost::make_move_iterator(&aux_vect[0])
, boost::make_move_iterator(aux_vect + 50));
MyStdSet *stdset2 = new MyStdSet(aux_vect2, aux_vect2 + 50);
MyBoostMultiSet *boostmultiset2 = new MyBoostMultiSet
( boost::make_move_iterator(&aux_vect3[0])
, boost::make_move_iterator(aux_vect3 + 50));
MyStdMultiSet *stdmultiset2 = new MyStdMultiSet(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(boostset2, stdset2)){
std::cout << "Error in construct<MyBoostSet>(MyBoostSet2)" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset2, stdmultiset2)){
std::cout << "Error in construct<MyBoostMultiSet>(MyBoostMultiSet2)" << std::endl;
return 1;
}
//ordered range insertion
for(int i = 0; i < 50; ++i){
IntType move_me(i);
aux_vect[i] = boost::move(move_me);
}
for(int i = 0; i < 50; ++i){
aux_vect2[i] = i;
}
for(int i = 0; i < 50; ++i){
IntType move_me(i);
aux_vect3[i] = boost::move(move_me);
}
/*
MyBoostSet *boostset3 = 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
( ordered_range
, boost::make_move_iterator(&aux_vect3[0])
, boost::make_move_iterator(aux_vect3 + 50));
MyStdMultiSet *stdmultiset3 = new MyStdMultiSet(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(boostset3, stdset3)){
std::cout << "Error in construct<MyBoostSet>(MyBoostSet3)" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset3, stdmultiset3)){
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;
}
int i, j;
for(i = 0; i < max; ++i){
IntType move_me(i);
boostset->insert(boost::move(move_me));
stdset->insert(i);
boostset->insert(IntType(i));
stdset->insert(i);
IntType move_me2(i);
boostmultiset->insert(boost::move(move_me2));
stdmultiset->insert(i);
boostmultiset->insert(IntType(i));
stdmultiset->insert(i);
}
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boost::move(move_me)" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boost::move(move_me)" << std::endl;
return 1;
}
typename MyBoostSet::iterator it;
typename MyBoostSet::const_iterator cit = it;
boostset->erase(boostset->begin()++);
stdset->erase(stdset->begin()++);
boostmultiset->erase(boostmultiset->begin()++);
stdmultiset->erase(stdmultiset->begin()++);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->erase(boostset->begin()++)" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->erase(boostmultiset->begin()++)" << std::endl;
return 1;
}
boostset->erase(boostset->begin());
stdset->erase(stdset->begin());
boostmultiset->erase(boostmultiset->begin());
stdmultiset->erase(stdmultiset->begin());
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->erase(boostset->begin())" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->erase(boostmultiset->begin())" << std::endl;
return 1;
}
//Swapping test
MyBoostSet tmpboosteset2;
MyStdSet tmpstdset2;
MyBoostMultiSet tmpboostemultiset2;
MyStdMultiSet tmpstdmultiset2;
boostset->swap(tmpboosteset2);
stdset->swap(tmpstdset2);
boostmultiset->swap(tmpboostemultiset2);
stdmultiset->swap(tmpstdmultiset2);
boostset->swap(tmpboosteset2);
stdset->swap(tmpstdset2);
boostmultiset->swap(tmpboostemultiset2);
stdmultiset->swap(tmpstdmultiset2);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->swap(tmpboosteset2)" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->swap(tmpboostemultiset2)" << std::endl;
return 1;
}
//Insertion from other container
//Initialize values
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect3[i] = boost::move(move_me);
}
boostset->insert(boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(aux_vect + 50));
stdset->insert(aux_vect2, aux_vect2 + 50);
boostmultiset->insert(boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(aux_vect3 + 50));
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boost::make_move_iterator(&aux_vect[0])..." << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boost::make_move_iterator(&aux_vect3[0]), ..." << std::endl;
return 1;
}
for(int i = 0, j = static_cast<int>(boostset->size()); i < j; ++i){
IntType erase_me(i);
boostset->erase(erase_me);
stdset->erase(i);
boostmultiset->erase(erase_me);
stdmultiset->erase(i);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->erase(erase_me)" << boostset->size() << " " << stdset->size() << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->erase(erase_me)" << std::endl;
return 1;
}
}
}
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect3[i] = boost::move(move_me);
}
IntType aux_vect4[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect4[i] = boost::move(move_me);
}
IntType aux_vect5[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect5[i] = boost::move(move_me);
}
boostset->insert(boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(aux_vect + 50));
boostset->insert(boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(aux_vect3 + 50));
stdset->insert(aux_vect2, aux_vect2 + 50);
stdset->insert(aux_vect2, aux_vect2 + 50);
boostmultiset->insert(boost::make_move_iterator(&aux_vect4[0]), boost::make_move_iterator(aux_vect4 + 50));
boostmultiset->insert(boost::make_move_iterator(&aux_vect5[0]), boost::make_move_iterator(aux_vect5 + 50));
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boost::make_move_iterator(&aux_vect3[0])..." << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boost::make_move_iterator(&aux_vect5[0])..." << std::endl;
return 1;
}
boostset->erase(*boostset->begin());
stdset->erase(*stdset->begin());
boostmultiset->erase(*boostmultiset->begin());
stdmultiset->erase(*stdmultiset->begin());
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->erase(*boostset->begin())" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->erase(*boostmultiset->begin())" << std::endl;
return 1;
}
}
for(i = 0; i < max; ++i){
IntType move_me(i);
boostset->insert(boost::move(move_me));
stdset->insert(i);
IntType move_me2(i);
boostmultiset->insert(boost::move(move_me2));
stdmultiset->insert(i);
}
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boost::move(move_me)) try 2" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boost::move(move_me2)) try 2" << std::endl;
return 1;
}
for(i = 0; i < max; ++i){
IntType move_me(i);
boostset->insert(boostset->begin(), boost::move(move_me));
stdset->insert(stdset->begin(), i);
//PrintContainers(boostset, stdset);
IntType move_me2(i);
boostmultiset->insert(boostmultiset->begin(), boost::move(move_me2));
stdmultiset->insert(stdmultiset->begin(), i);
//PrintContainers(boostmultiset, stdmultiset);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boostset->begin(), boost::move(move_me))" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boostmultiset->begin(), boost::move(move_me2))" << std::endl;
return 1;
}
IntType move_me3(i);
boostset->insert(boostset->end(), boost::move(move_me3));
stdset->insert(stdset->end(), i);
IntType move_me4(i);
boostmultiset->insert(boostmultiset->end(), boost::move(move_me4));
stdmultiset->insert(stdmultiset->end(), i);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boostset->end(), boost::move(move_me3))" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boostmultiset->end(), boost::move(move_me4))" << std::endl;
return 1;
}
{
IntType move_me(i);
boostset->insert(boostset->upper_bound(move_me), boost::move(move_me));
stdset->insert(stdset->upper_bound(i), i);
//PrintContainers(boostset, stdset);
IntType move_me2(i);
boostmultiset->insert(boostmultiset->upper_bound(move_me2), boost::move(move_me2));
stdmultiset->insert(stdmultiset->upper_bound(i), i);
//PrintContainers(boostmultiset, stdmultiset);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boostset->upper_bound(move_me), boost::move(move_me))" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boostmultiset->upper_bound(move_me2), boost::move(move_me2))" << std::endl;
return 1;
}
}
{
IntType move_me(i);
boostset->insert(boostset->lower_bound(move_me), boost::move(move_me2));
stdset->insert(stdset->lower_bound(i), i);
//PrintContainers(boostset, stdset);
IntType move_me2(i);
boostmultiset->insert(boostmultiset->lower_bound(move_me2), boost::move(move_me2));
stdmultiset->insert(stdmultiset->lower_bound(i), i);
//PrintContainers(boostmultiset, stdmultiset);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boostset->lower_bound(move_me), boost::move(move_me2))" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boostmultiset->lower_bound(move_me2), boost::move(move_me2))" << std::endl;
return 1;
}
}
}
//Compare count with std containers
for(i = 0; i < max; ++i){
IntType count_me(i);
if(boostset->count(count_me) != stdset->count(i)){
return -1;
}
if(boostmultiset->count(count_me) != stdmultiset->count(i)){
return -1;
}
}
//Now do count exercise
boostset->erase(boostset->begin(), boostset->end());
boostmultiset->erase(boostmultiset->begin(), boostmultiset->end());
boostset->clear();
boostmultiset->clear();
for(j = 0; j < 3; ++j)
for(i = 0; i < 100; ++i){
IntType move_me(i);
boostset->insert(boost::move(move_me));
IntType move_me2(i);
boostmultiset->insert(boost::move(move_me2));
IntType count_me(i);
if(boostset->count(count_me) != typename MyBoostMultiSet::size_type(1)){
std::cout << "Error in boostset->count(count_me)" << std::endl;
return 1;
}
if(boostmultiset->count(count_me) != typename MyBoostMultiSet::size_type(j+1)){
std::cout << "Error in boostmultiset->count(count_me)" << std::endl;
return 1;
}
}
delete boostset;
delete stdset;
delete boostmultiset;
delete stdmultiset;
return 0;
}
template<class MyBoostSet
,class MyStdSet
,class MyBoostMultiSet
,class MyStdMultiSet>
int set_test_copyable ()
{
typedef typename MyBoostSet::value_type IntType;
const int max = 100;
try{
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyBoostSet *boostset = new MyBoostSet;
MyStdSet *stdset = new MyStdSet;
MyBoostMultiSet *boostmultiset = new MyBoostMultiSet;
MyStdMultiSet *stdmultiset = new MyStdMultiSet;
int i;
for(i = 0; i < max; ++i){
IntType move_me(i);
boostset->insert(boost::move(move_me));
stdset->insert(i);
IntType move_me2(i);
boostmultiset->insert(boost::move(move_me2));
stdmultiset->insert(i);
}
if(!CheckEqualContainers(boostset, stdset)) return 1;
if(!CheckEqualContainers(boostmultiset, stdmultiset)) return 1;
{
//Now, test copy constructor
MyBoostSet boostsetcopy(*boostset);
MyStdSet stdsetcopy(*stdset);
if(!CheckEqualContainers(&boostsetcopy, &stdsetcopy))
return 1;
MyBoostMultiSet boostmsetcopy(*boostmultiset);
MyStdMultiSet stdmsetcopy(*stdmultiset);
if(!CheckEqualContainers(&boostmsetcopy, &stdmsetcopy))
return 1;
//And now assignment
boostsetcopy = *boostset;
stdsetcopy = *stdset;
if(!CheckEqualContainers(&boostsetcopy, &stdsetcopy))
return 1;
boostmsetcopy = *boostmultiset;
stdmsetcopy = *stdmultiset;
if(!CheckEqualContainers(&boostmsetcopy, &stdmsetcopy))
return 1;
}
delete boostset;
delete boostmultiset;
}
catch(...){
throw;
}
return 0;
}
} //namespace test{
} //namespace container {
} //namespace boost{
#include <boost/container/detail/config_end.hpp>
#endif
+82
View File
@@ -0,0 +1,82 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/slist.hpp>
#include "dummy_test_allocator.hpp"
#include "movable_int.hpp"
#include "list_test.hpp"
#include "emplace_test.hpp"
using namespace boost::container;
//Explicit instantiation to detect compilation errors
template class boost::container::slist<test::movable_and_copyable_int,
test::dummy_test_allocator<test::movable_and_copyable_int> >;
typedef slist<int> MyList;
typedef slist<test::movable_int> MyMoveList;
typedef slist<test::movable_and_copyable_int> MyCopyMoveList;
typedef slist<test::copyable_int> MyCopyList;
class recursive_slist
{
public:
int id_;
slist<recursive_slist> slist_;
recursive_slist &operator=(const recursive_slist &o)
{ slist_ = o.slist_; return *this; }
};
void recursive_slist_test()//Test for recursive types
{
slist<recursive_slist> recursive_list_list;
}
int main ()
{
recursive_slist_test();
{
//Now test move semantics
slist<recursive_slist> original;
slist<recursive_slist> move_ctor(boost::move(original));
slist<recursive_slist> move_assign;
move_assign = boost::move(move_ctor);
move_assign.swap(original);
{
slist<recursive_slist> recursive, copy;
//Test to test both move emulations
if(!copy.size()){
copy = recursive;
}
}
}
if(test::list_test<MyList, false>())
return 1;
if(test::list_test<MyMoveList, false>())
return 1;
if(test::list_test<MyCopyMoveList, false>())
return 1;
if(test::list_test<MyCopyList, false>())
return 1;
const test::EmplaceOptions Options = (test::EmplaceOptions)
(test::EMPLACE_FRONT | test::EMPLACE_AFTER | test::EMPLACE_BEFORE | test::EMPLACE_AFTER);
if(!boost::container::test::test_emplace
< slist<test::EmplaceInt>, Options>())
return 1;
}
#include <boost/container/detail/config_end.hpp>
+86
View File
@@ -0,0 +1,86 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
#include <vector>
#include <iostream>
#include <functional>
#include <boost/container/stable_vector.hpp>
#include "check_equal_containers.hpp"
#include "movable_int.hpp"
#include "expand_bwd_test_allocator.hpp"
#include "expand_bwd_test_template.hpp"
#include "dummy_test_allocator.hpp"
#include "vector_test.hpp"
using namespace boost::container;
//Explicit instantiation to detect compilation errors
//template class stable_vector<test::movable_and_copyable_int,
//test::dummy_test_allocator<test::movable_and_copyable_int> >;
class recursive_vector
{
public:
int id_;
stable_vector<recursive_vector> vector_;
recursive_vector &operator=(const recursive_vector &o)
{ vector_ = o.vector_; return *this; }
};
void recursive_vector_test()//Test for recursive types
{
stable_vector<recursive_vector> recursive, copy;
//Test to test both move emulations
if(!copy.size()){
copy = recursive;
}
}
int main()
{
recursive_vector_test();
{
//Now test move semantics
stable_vector<recursive_vector> original;
stable_vector<recursive_vector> move_ctor(boost::move(original));
stable_vector<recursive_vector> move_assign;
move_assign = boost::move(move_ctor);
move_assign.swap(original);
}
typedef stable_vector<int> MyVector;
typedef stable_vector<test::movable_int> MyMoveVector;
typedef stable_vector<test::movable_and_copyable_int> MyCopyMoveVector;
typedef stable_vector<test::copyable_int> MyCopyVector;
if(test::vector_test<MyVector>())
return 1;
if(test::vector_test<MyMoveVector>())
return 1;
if(test::vector_test<MyCopyMoveVector>())
return 1;
if(test::vector_test<MyCopyVector>())
return 1;
const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE);
if(!boost::container::test::test_emplace
< stable_vector<test::EmplaceInt>, Options>())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>
+293
View File
@@ -0,0 +1,293 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/vector.hpp>
#include <boost/container/string.hpp>
#include <string>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstddef>
#include <new>
#include "dummy_test_allocator.hpp"
#include "check_equal_containers.hpp"
#include "expand_bwd_test_allocator.hpp"
#include "expand_bwd_test_template.hpp"
using namespace boost::container;
typedef test::dummy_test_allocator<char> DummyCharAllocator;
typedef basic_string<char, std::char_traits<char>, DummyCharAllocator> DummyString;
typedef test::dummy_test_allocator<DummyString> DummyStringAllocator;
typedef test::dummy_test_allocator<wchar_t> DummyWCharAllocator;
typedef basic_string<wchar_t, std::char_traits<wchar_t>, DummyWCharAllocator> DummyWString;
typedef test::dummy_test_allocator<DummyWString> DummyWStringAllocator;
//Explicit instantiations of container::basic_string
template class basic_string<char, std::char_traits<char>, DummyCharAllocator>;
template class basic_string<wchar_t, std::char_traits<wchar_t>, DummyWCharAllocator>;
//Explicit instantiation of container::vectors of container::strings
template class vector<DummyString, DummyStringAllocator>;
template class vector<DummyWString, DummyWStringAllocator>;
struct StringEqual
{
template<class Str1, class Str2>
bool operator ()(const Str1 &string1, const Str2 &string2) const
{
if(string1.size() != string2.size())
return false;
return std::char_traits<typename Str1::value_type>::compare
(string1.c_str(), string2.c_str(), string1.size()) == 0;
}
};
//Function to check if both lists are equal
template<class StrVector1, class StrVector2>
bool CheckEqualStringVector(StrVector1 *strvect1, StrVector2 *strvect2)
{
StringEqual comp;
return std::equal(strvect1->begin(), strvect1->end(),
strvect2->begin(), comp);
}
template<class CharType>
int string_test()
{
typedef std::string StdString;
typedef vector<StdString> StdStringVector;
typedef basic_string<CharType> BoostString;
typedef vector<BoostString> BoostStringVector;
const int MaxSize = 100;
//Create shared memory
{
BoostStringVector *boostStringVect = new BoostStringVector;
StdStringVector *stdStringVect = new StdStringVector;
BoostString auxBoostString;
StdString auxStdString(StdString(auxBoostString.begin(), auxBoostString.end() ));
CharType buffer [20];
//First, push back
for(int i = 0; i < MaxSize; ++i){
auxBoostString = "String";
auxStdString = "String";
std::sprintf(buffer, "%i", i);
auxBoostString += buffer;
auxStdString += buffer;
boostStringVect->push_back(auxBoostString);
stdStringVect->push_back(auxStdString);
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)){
return 1;
}
//Now push back moving
for(int i = 0; i < MaxSize; ++i){
auxBoostString = "String";
auxStdString = "String";
std::sprintf(buffer, "%i", i);
auxBoostString += buffer;
auxStdString += buffer;
boostStringVect->push_back(boost::move(auxBoostString));
stdStringVect->push_back(auxStdString);
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)){
return 1;
}
//push front
for(int i = 0; i < MaxSize; ++i){
auxBoostString = "String";
auxStdString = "String";
std::sprintf(buffer, "%i", i);
auxBoostString += buffer;
auxStdString += buffer;
boostStringVect->insert(boostStringVect->begin(), auxBoostString);
stdStringVect->insert(stdStringVect->begin(), auxStdString);
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)){
return 1;
}
//Now push front moving
for(int i = 0; i < MaxSize; ++i){
auxBoostString = "String";
auxStdString = "String";
std::sprintf(buffer, "%i", i);
auxBoostString += buffer;
auxStdString += buffer;
boostStringVect->insert(boostStringVect->begin(), boost::move(auxBoostString));
stdStringVect->insert(stdStringVect->begin(), auxStdString);
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)){
return 1;
}
//Now test long and short representation swapping
//Short first
auxBoostString = "String";
auxStdString = "String";
BoostString boost_swapper;
StdString std_swapper;
boost_swapper.swap(auxBoostString);
std_swapper.swap(auxStdString);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
if(!StringEqual()(boost_swapper, std_swapper))
return 1;
boost_swapper.swap(auxBoostString);
std_swapper.swap(auxStdString);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
if(!StringEqual()(boost_swapper, std_swapper))
return 1;
//Shrink_to_fit
auxBoostString.shrink_to_fit();
StdString(auxStdString).swap(auxStdString);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
//Reserve + shrink_to_fit
auxBoostString.reserve(boost_swapper.size()*2+1);
auxStdString.reserve(std_swapper.size()*2+1);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
auxBoostString.shrink_to_fit();
StdString(auxStdString).swap(auxStdString);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
//Long string
auxBoostString = "LongLongLongLongLongLongLongLongLongLongLongLongLongString";
auxStdString = "LongLongLongLongLongLongLongLongLongLongLongLongLongString";
boost_swapper = BoostString();
std_swapper = StdString();
boost_swapper.swap(auxBoostString);
std_swapper.swap(auxStdString);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
if(!StringEqual()(boost_swapper, std_swapper))
return 1;
boost_swapper.swap(auxBoostString);
std_swapper.swap(auxStdString);
//Shrink_to_fit
auxBoostString.shrink_to_fit();
StdString(auxStdString).swap(auxStdString);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
auxBoostString.clear();
auxStdString.clear();
auxBoostString.shrink_to_fit();
StdString(auxStdString).swap(auxStdString);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
//No sort
std::sort(boostStringVect->begin(), boostStringVect->end());
std::sort(stdStringVect->begin(), stdStringVect->end());
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
const CharType prefix [] = "Prefix";
const int prefix_size = sizeof(prefix)/sizeof(prefix[0])-1;
const CharType sufix [] = "Suffix";
for(int i = 0; i < MaxSize; ++i){
(*boostStringVect)[i].append(sufix);
(*stdStringVect)[i].append(sufix);
(*boostStringVect)[i].insert((*boostStringVect)[i].begin(),
prefix, prefix + prefix_size);
(*stdStringVect)[i].insert((*stdStringVect)[i].begin(),
prefix, prefix + prefix_size);
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
for(int i = 0; i < MaxSize; ++i){
std::reverse((*boostStringVect)[i].begin(), (*boostStringVect)[i].end());
std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end());
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
for(int i = 0; i < MaxSize; ++i){
std::reverse((*boostStringVect)[i].begin(), (*boostStringVect)[i].end());
std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end());
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
for(int i = 0; i < MaxSize; ++i){
std::sort(boostStringVect->begin(), boostStringVect->end());
std::sort(stdStringVect->begin(), stdStringVect->end());
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
for(int i = 0; i < MaxSize; ++i){
(*boostStringVect)[i].replace((*boostStringVect)[i].begin(),
(*boostStringVect)[i].end(),
"String");
(*stdStringVect)[i].replace((*stdStringVect)[i].begin(),
(*stdStringVect)[i].end(),
"String");
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
boostStringVect->erase(std::unique(boostStringVect->begin(), boostStringVect->end()),
boostStringVect->end());
stdStringVect->erase(std::unique(stdStringVect->begin(), stdStringVect->end()),
stdStringVect->end());
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
//When done, delete vector
delete boostStringVect;
delete stdStringVect;
}
return 0;
}
bool test_expand_bwd()
{
//Now test all back insertion possibilities
typedef test::expand_bwd_test_allocator<char>
allocator_type;
typedef basic_string<char, std::char_traits<char>, allocator_type>
string_type;
return test::test_all_expand_bwd<string_type>();
}
int main()
{
if(string_test<char>()){
return 1;
}
if(!test_expand_bwd())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>
+233
View File
@@ -0,0 +1,233 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <set>
#include <boost/container/set.hpp>
#include <boost/container/map.hpp>
#include "print_container.hpp"
#include "movable_int.hpp"
#include "dummy_test_allocator.hpp"
#include "set_test.hpp"
#include "map_test.hpp"
#include "emplace_test.hpp"
using namespace boost::container;
//Alias standard types
typedef std::set<int> MyStdSet;
typedef std::multiset<int> MyStdMultiSet;
typedef std::map<int, int> MyStdMap;
typedef std::multimap<int, int> MyStdMultiMap;
//Alias non-movable types
typedef set<int> MyBoostSet;
typedef multiset<int> MyBoostMultiSet;
typedef map<int, int> MyBoostMap;
typedef multimap<int, int> MyBoostMultiMap;
//Alias movable types
typedef set<test::movable_int> MyMovableBoostSet;
typedef multiset<test::movable_int> MyMovableBoostMultiSet;
typedef map<test::movable_int, test::movable_int> MyMovableBoostMap;
typedef multimap<test::movable_int, test::movable_int> MyMovableBoostMultiMap;
typedef set<test::movable_and_copyable_int> MyMoveCopyBoostSet;
typedef set<test::copyable_int> MyCopyBoostSet;
typedef multiset<test::movable_and_copyable_int> MyMoveCopyBoostMultiSet;
typedef multiset<test::copyable_int> MyCopyBoostMultiSet;
typedef map<test::movable_and_copyable_int
,test::movable_and_copyable_int> MyMoveCopyBoostMap;
typedef multimap<test::movable_and_copyable_int
,test::movable_and_copyable_int> MyMoveCopyBoostMultiMap;
typedef map<test::copyable_int
,test::copyable_int> MyCopyBoostMap;
typedef multimap<test::copyable_int
,test::copyable_int> MyCopyBoostMultiMap;
//Test recursive structures
class recursive_set
{
public:
int id_;
set<recursive_set> set_;
friend bool operator< (const recursive_set &a, const recursive_set &b)
{ return a.id_ < b.id_; }
};
class recursive_map
{
public:
int id_;
map<recursive_map, recursive_map> map_;
friend bool operator< (const recursive_map &a, const recursive_map &b)
{ return a.id_ < b.id_; }
};
//Test recursive structures
class recursive_multiset
{
public:
int id_;
multiset<recursive_multiset> multiset_;
friend bool operator< (const recursive_multiset &a, const recursive_multiset &b)
{ return a.id_ < b.id_; }
};
class recursive_multimap
{
public:
int id_;
multimap<recursive_multimap, recursive_multimap> multimap_;
friend bool operator< (const recursive_multimap &a, const recursive_multimap &b)
{ return a.id_ < b.id_; }
};
template<class C>
void test_move()
{
//Now test move semantics
C original;
C move_ctor(boost::move(original));
C move_assign;
move_assign = boost::move(move_ctor);
move_assign.swap(original);
}
int main ()
{
//Recursive container instantiation
{
set<recursive_set> set_;
multiset<recursive_multiset> multiset_;
map<recursive_map, recursive_map> map_;
multimap<recursive_multimap, recursive_multimap> multimap_;
}
//Now test move semantics
{
test_move<set<recursive_set> >();
test_move<multiset<recursive_multiset> >();
test_move<map<recursive_map, recursive_map> >();
test_move<multimap<recursive_multimap, recursive_multimap> >();
}
//using namespace boost::container::detail;
if(0 != test::set_test<MyBoostSet
,MyStdSet
,MyBoostMultiSet
,MyStdMultiSet>()){
return 1;
}
if(0 != test::set_test_copyable<MyBoostSet
,MyStdSet
,MyBoostMultiSet
,MyStdMultiSet>()){
return 1;
}
if(0 != test::set_test<MyMovableBoostSet
,MyStdSet
,MyMovableBoostMultiSet
,MyStdMultiSet>()){
return 1;
}
if(0 != test::set_test<MyMoveCopyBoostSet
,MyStdSet
,MyMoveCopyBoostMultiSet
,MyStdMultiSet>()){
return 1;
}
if(0 != test::set_test_copyable<MyMoveCopyBoostSet
,MyStdSet
,MyMoveCopyBoostMultiSet
,MyStdMultiSet>()){
return 1;
}
if(0 != test::set_test<MyCopyBoostSet
,MyStdSet
,MyCopyBoostMultiSet
,MyStdMultiSet>()){
return 1;
}
if(0 != test::set_test_copyable<MyCopyBoostSet
,MyStdSet
,MyCopyBoostMultiSet
,MyStdMultiSet>()){
return 1;
}
if (0 != test::map_test<MyBoostMap
,MyStdMap
,MyBoostMultiMap
,MyStdMultiMap>()){
return 1;
}
if(0 != test::map_test_copyable<MyBoostMap
,MyStdMap
,MyBoostMultiMap
,MyStdMultiMap>()){
return 1;
}
// if (0 != test::map_test<my_managed_shared_memory
// ,MyMovableBoostMap
// ,MyStdMap
// ,MyMovableBoostMultiMap
// ,MyStdMultiMap>()){
// return 1;
// }
if (0 != test::map_test<MyMoveCopyBoostMap
,MyStdMap
,MyMoveCopyBoostMultiMap
,MyStdMultiMap>()){
return 1;
}
if (0 != test::map_test_copyable<MyMoveCopyBoostMap
,MyStdMap
,MyMoveCopyBoostMultiMap
,MyStdMultiMap>()){
return 1;
}
if (0 != test::map_test<MyCopyBoostMap
,MyStdMap
,MyCopyBoostMultiMap
,MyStdMultiMap>()){
return 1;
}
if (0 != test::map_test_copyable<MyCopyBoostMap
,MyStdMap
,MyCopyBoostMultiMap
,MyStdMultiMap>()){
return 1;
}
const test::EmplaceOptions SetOptions = (test::EmplaceOptions)(test::EMPLACE_HINT | test::EMPLACE_ASSOC);
if(!boost::container::test::test_emplace<set<test::EmplaceInt>, SetOptions>())
return 1;
if(!boost::container::test::test_emplace<multiset<test::EmplaceInt>, SetOptions>())
return 1;
const test::EmplaceOptions MapOptions = (test::EmplaceOptions)(test::EMPLACE_HINT_PAIR | test::EMPLACE_ASSOC_PAIR);
if(!boost::container::test::test_emplace<map<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
return 1;
if(!boost::container::test::test_emplace<multimap<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>
+113
View File
@@ -0,0 +1,113 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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.
//
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_CONTAINER_TEST_UTIL_HEADER
#define BOOST_CONTAINER_TEST_UTIL_HEADER
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/sync/container_mutex.hpp>
#include <boost/container/sync/container_condition.hpp>
#include <boost/container/sync/scoped_lock.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <algorithm>
#include <iostream>
#ifndef DEFAULT_EXECUTION_MONITOR_TYPE
# define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_condition
#endif
namespace boost {
namespace container {
namespace test {
inline void sleep(const boost::posix_time::ptime &xt)
{
boost::container::container_mutex mx;
boost::container::scoped_lock<boost::container::container_mutex>
lock(mx);
boost::container::container_condition cond;
cond.timed_wait(lock, xt);
}
inline boost::posix_time::ptime delay(int secs, int msecs=0, int nsecs = 0)
{
(void)msecs;
using namespace boost::posix_time;
int count = static_cast<int>(double(nsecs)*
(double(time_duration::ticks_per_second())/double(1000000000.0)));
count += static_cast<int>(double(msecs)*
(double(time_duration::ticks_per_second())/double(1000.0)));
boost::posix_time::ptime cur = microsec_clock::universal_time();
return cur += boost::posix_time::time_duration(0, 0, secs, count);
}
inline bool in_range(const boost::posix_time::ptime& xt, int secs=1)
{
boost::posix_time::ptime min = delay(-secs);
boost::posix_time::ptime max = delay(0);
return (xt > min) && (max > xt);
}
boost::xtime xsecs(int secs)
{
boost::xtime ret;
boost::xtime_get(&ret, boost::TIME_UTC);
ret.sec += secs;
return ret;
}
template <typename P>
class thread_adapter
{
public:
thread_adapter(void (*func)(void*, P &), void* param1, P &param2)
: _func(func), _param1(param1) ,_param2(param2){ }
void operator()() const { _func(_param1, _param2); }
private:
void (*_func)(void*, P &);
void* _param1;
P& _param2;
};
template <typename P>
struct data
{
data(int id, int secs=0)
: m_id(id), m_value(-1), m_secs(secs)
{}
int m_id;
int m_value;
int m_secs;
};
static int shared_val = 0;
static const int BaseSeconds = 1;
} //namespace test {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_TEST_UTIL_HEADER
+127
View File
@@ -0,0 +1,127 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
#include <vector>
#include <iostream>
#include <functional>
#include <boost/container/vector.hpp>
#include "check_equal_containers.hpp"
#include "movable_int.hpp"
#include "expand_bwd_test_allocator.hpp"
#include "expand_bwd_test_template.hpp"
#include "dummy_test_allocator.hpp"
#include "vector_test.hpp"
using namespace boost::container;
//Explicit instantiation to detect compilation errors
template class boost::container::vector<test::movable_and_copyable_int,
test::dummy_test_allocator<test::movable_and_copyable_int> >;
int test_expand_bwd()
{
//Now test all back insertion possibilities
//First raw ints
typedef test::expand_bwd_test_allocator<int>
int_allocator_type;
typedef vector<int, int_allocator_type>
int_vector;
if(!test::test_all_expand_bwd<int_vector>())
return 1;
//Now user defined wrapped int
typedef test::expand_bwd_test_allocator<test::int_holder>
int_holder_allocator_type;
typedef vector<test::int_holder, int_holder_allocator_type>
int_holder_vector;
if(!test::test_all_expand_bwd<int_holder_vector>())
return 1;
//Now user defined bigger wrapped int
typedef test::expand_bwd_test_allocator<test::triple_int_holder>
triple_int_holder_allocator_type;
typedef vector<test::triple_int_holder, triple_int_holder_allocator_type>
triple_int_holder_vector;
if(!test::test_all_expand_bwd<triple_int_holder_vector>())
return 1;
return 0;
}
class recursive_vector
{
public:
int id_;
vector<recursive_vector> vector_;
};
void recursive_vector_test()//Test for recursive types
{
vector<recursive_vector> recursive_vector_vector;
}
enum Test
{
zero, one, two, three, four, five, six
};
int main()
{
recursive_vector_test();
{
//Now test move semantics
vector<recursive_vector> original;
vector<recursive_vector> move_ctor(boost::move(original));
vector<recursive_vector> move_assign;
move_assign = boost::move(move_ctor);
move_assign.swap(original);
}
typedef vector<int> MyVector;
typedef vector<test::movable_int> MyMoveVector;
typedef vector<test::movable_and_copyable_int> MyCopyMoveVector;
typedef vector<test::copyable_int> MyCopyVector;
typedef vector<Test> MyEnumVector;
if(test::vector_test<MyVector>())
return 1;
if(test::vector_test<MyMoveVector>())
return 1;
if(test::vector_test<MyCopyMoveVector>())
return 1;
if(test::vector_test<MyCopyVector>())
return 1;
if(test_expand_bwd())
return 1;
MyEnumVector v;
Test t;
v.push_back(t);
v.push_back(::boost::move(t));
v.push_back(Test());
const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE);
if(!boost::container::test::test_emplace
< vector<test::EmplaceInt>, Options>())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>
+253
View File
@@ -0,0 +1,253 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
#include <vector>
#include <iostream>
#include <functional>
#include <list>
#include <boost/move/move.hpp>
#include <boost/container/detail/mpl.hpp>
#include "print_container.hpp"
#include "check_equal_containers.hpp"
#include "movable_int.hpp"
#include <string>
#include <vector>
#include "emplace_test.hpp"
namespace boost{
namespace container {
namespace test{
template<class V1, class V2>
bool vector_copyable_only(V1 *, V2 *, boost::container::containers_detail::false_type)
{
return true;
}
//Function to check if both sets are equal
template<class V1, class V2>
bool vector_copyable_only(V1 *boostvector, V2 *stdvector, boost::container::containers_detail::true_type)
{
typedef typename V1::value_type IntType;
std::size_t size = boostvector->size();
boostvector->insert(boostvector->end(), 50, IntType(1));
stdvector->insert(stdvector->end(), 50, 1);
if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
{
IntType move_me(1);
boostvector->insert(boostvector->begin()+size/2, 50, boost::move(move_me));
stdvector->insert(stdvector->begin()+size/2, 50, 1);
if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
}
{
IntType move_me(2);
boostvector->assign(boostvector->size()/2, boost::move(move_me));
stdvector->assign(stdvector->size()/2, 2);
if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
}
{
IntType move_me(3);
boostvector->assign(boostvector->size()*3-1, boost::move(move_me));
stdvector->assign(stdvector->size()*3-1, 3);
if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
}
{
IntType copy_me(3);
const IntType ccopy_me(3);
boostvector->push_back(copy_me);
stdvector->push_back(int(3));
boostvector->push_back(ccopy_me);
stdvector->push_back(int(3));
if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
}
return true;
}
template<class MyBoostVector>
int vector_test()
{
typedef std::vector<int> MyStdVector;
typedef typename MyBoostVector::value_type IntType;
const int max = 100;
{
try{
MyBoostVector *boostvector = new MyBoostVector;
MyStdVector *stdvector = new MyStdVector;
boostvector->resize(100);
stdvector->resize(100);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->resize(200);
stdvector->resize(200);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->resize(0);
stdvector->resize(0);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
for(int i = 0; i < max; ++i){
IntType new_int(i);
boostvector->insert(boostvector->end(), boost::move(new_int));
stdvector->insert(stdvector->end(), i);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
}
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
typename MyBoostVector::iterator boostit(boostvector->begin());
typename MyStdVector::iterator stdit(stdvector->begin());
typename MyBoostVector::const_iterator cboostit = boostit;
++boostit; ++stdit;
boostvector->erase(boostit);
stdvector->erase(stdit);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->erase(boostvector->begin());
stdvector->erase(stdvector->begin());
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
{
//Initialize values
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType new_int(-1);
BOOST_STATIC_ASSERT((boost::container::test::is_copyable<boost::container::test::movable_int>::value == false));
aux_vect[i] = boost::move(new_int);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
boostvector->insert(boostvector->end()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(aux_vect + 50));
stdvector->insert(stdvector->end(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
for(int i = 0, j = static_cast<int>(boostvector->size()); i < j; ++i){
boostvector->erase(boostvector->begin());
stdvector->erase(stdvector->begin());
}
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
}
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType new_int(-1);
aux_vect[i] = boost::move(new_int);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
boostvector->insert(boostvector->begin()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(aux_vect + 50));
stdvector->insert(stdvector->begin(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
}
/*
boostvector->reserve(boostvector->size()*2);
stdvector->reserve(stdvector->size()*2);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
*/
boostvector->shrink_to_fit();
MyStdVector(*stdvector).swap(*stdvector);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->shrink_to_fit();
MyStdVector(*stdvector).swap(*stdvector);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
IntType push_back_this(1);
boostvector->push_back(boost::move(push_back_this));
stdvector->push_back(int(1));
boostvector->push_back(IntType(1));
stdvector->push_back(int(1));
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
if(!vector_copyable_only(boostvector, stdvector
,containers_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
return 1;
}
boostvector->erase(boostvector->begin());
stdvector->erase(stdvector->begin());
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
for(int i = 0; i < max; ++i){
IntType insert_this(i);
boostvector->insert(boostvector->begin(), boost::move(insert_this));
stdvector->insert(stdvector->begin(), i);
boostvector->insert(boostvector->begin(), IntType(i));
stdvector->insert(stdvector->begin(), int(i));
}
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
//Test insertion from list
{
std::list<int> l(50, int(1));
boostvector->insert(boostvector->begin(), l.begin(), l.end());
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;
}
/*
std::size_t cap = boostvector->capacity();
boostvector->reserve(cap*2);
stdvector->reserve(cap*2);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->resize(0);
stdvector->resize(0);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->resize(cap*2);
stdvector->resize(cap*2);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->clear();
stdvector->clear();
boostvector->shrink_to_fit();
MyStdVector(*stdvector).swap(*stdvector);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->resize(cap*2);
stdvector->resize(cap*2);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
*/
delete stdvector;
delete boostvector;
}
catch(std::exception &ex){
std::cout << ex.what() << std::endl;
return 1;
}
}
std::cout << std::endl << "Test OK!" << std::endl;
return 0;
}
} //namespace test{
} //namespace container {
} //namespace boost{
#include <boost/container/detail/config_end.hpp>