forked from boostorg/container
Merged for Boost 1.48
[SVN r74161]
This commit is contained in:
@@ -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 ] ;
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
@@ -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 ¶m2)
|
||||
: _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
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user