forked from boostorg/container
Merge branch 'develop'
This commit is contained in:
+2
-2
@@ -1,6 +1,6 @@
|
||||
# Boost Container Library Test Jamfile
|
||||
|
||||
# (C) Copyright Ion Gaztanaga 2009.
|
||||
# (C) Copyright Ion Gaztanaga 2009-2013.
|
||||
# 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)
|
||||
@@ -21,7 +21,7 @@ rule test_all
|
||||
|
||||
for local fileb in [ glob *.cpp ]
|
||||
{
|
||||
all_rules += [ run $(fileb)
|
||||
all_rules += [ run $(fileb) /boost/container//boost_container /boost/timer//boost_timer
|
||||
: # additional args
|
||||
: # test-files
|
||||
: # requirements
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013. 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/alloc_lib_auto_link.hpp>
|
||||
#include <boost/container/allocator.hpp>
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/container/list.hpp>
|
||||
|
||||
using namespace boost::container;
|
||||
|
||||
bool basic_test()
|
||||
{
|
||||
size_t received;
|
||||
if(!boost_cont_all_deallocated())
|
||||
return false;
|
||||
void *ptr = boost_cont_alloc(50, 98, &received);
|
||||
if(boost_cont_size(ptr) != received)
|
||||
return false;
|
||||
if(boost_cont_allocated_memory() != boost_cont_chunksize(ptr))
|
||||
return false;
|
||||
|
||||
if(boost_cont_all_deallocated())
|
||||
return false;
|
||||
|
||||
boost_cont_grow(ptr, received + 20, received + 30, &received);
|
||||
|
||||
if(boost_cont_allocated_memory() != boost_cont_chunksize(ptr))
|
||||
return false;
|
||||
|
||||
if(boost_cont_size(ptr) != received)
|
||||
return false;
|
||||
|
||||
if(!boost_cont_shrink(ptr, 100, 140, &received, 1))
|
||||
return false;
|
||||
|
||||
if(boost_cont_allocated_memory() != boost_cont_chunksize(ptr))
|
||||
return false;
|
||||
|
||||
if(!boost_cont_shrink(ptr, 0, 140, &received, 1))
|
||||
return false;
|
||||
|
||||
if(boost_cont_allocated_memory() != boost_cont_chunksize(ptr))
|
||||
return false;
|
||||
|
||||
if(boost_cont_shrink(ptr, 0, received/2, &received, 1))
|
||||
return false;
|
||||
|
||||
if(boost_cont_allocated_memory() != boost_cont_chunksize(ptr))
|
||||
return false;
|
||||
|
||||
if(boost_cont_size(ptr) != received)
|
||||
return false;
|
||||
|
||||
boost_cont_free(ptr);
|
||||
|
||||
boost_cont_malloc_check();
|
||||
if(!boost_cont_all_deallocated())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vector_test()
|
||||
{
|
||||
typedef boost::container::vector<int, allocator<int> > Vector;
|
||||
if(!boost_cont_all_deallocated())
|
||||
return false;
|
||||
{
|
||||
const int NumElem = 1000;
|
||||
Vector v;
|
||||
v.resize(NumElem);
|
||||
int *orig_buf = &v[0];
|
||||
int *new_buf = &v[0];
|
||||
while(orig_buf == new_buf){
|
||||
Vector::size_type cl = v.capacity() - v.size();
|
||||
while(cl--){
|
||||
v.push_back(0);
|
||||
}
|
||||
v.push_back(0);
|
||||
new_buf = &v[0];
|
||||
}
|
||||
}
|
||||
if(!boost_cont_all_deallocated())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool list_test()
|
||||
{
|
||||
typedef boost::container::list<int, allocator<int> > List;
|
||||
if(!boost_cont_all_deallocated())
|
||||
return false;
|
||||
{
|
||||
const int NumElem = 1000;
|
||||
List l;
|
||||
int values[NumElem];
|
||||
l.insert(l.end(), &values[0], &values[NumElem]);
|
||||
}
|
||||
if(!boost_cont_all_deallocated())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
if(!basic_test())
|
||||
return 1;
|
||||
if(!vector_test())
|
||||
return 1;
|
||||
if(!list_test())
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,851 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013. 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.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable:4702)
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <new>
|
||||
#include <utility>
|
||||
#include <cstring>
|
||||
#include <algorithm> //std::remove
|
||||
#include <boost/container/detail/alloc_lib_auto_link.hpp>
|
||||
|
||||
namespace boost { namespace container { namespace test {
|
||||
|
||||
static const int NumIt = 2000;
|
||||
|
||||
enum deallocation_type { DirectDeallocation, InverseDeallocation, MixedDeallocation, EndDeallocationType };
|
||||
|
||||
//This test allocates until there is no more memory
|
||||
//and after that deallocates all in the inverse order
|
||||
|
||||
bool test_allocation()
|
||||
{
|
||||
if(!boost_cont_all_deallocated())
|
||||
return false;
|
||||
boost_cont_malloc_check();
|
||||
for( deallocation_type t = DirectDeallocation
|
||||
; t != EndDeallocationType
|
||||
; t = (deallocation_type)((int)t + 1)){
|
||||
std::vector<void*> buffers;
|
||||
//std::size_t free_memory = a.get_free_memory();
|
||||
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
void *ptr = boost_cont_malloc(i);
|
||||
if(!ptr)
|
||||
break;
|
||||
buffers.push_back(ptr);
|
||||
}
|
||||
|
||||
switch(t){
|
||||
case DirectDeallocation:
|
||||
{
|
||||
for(int j = 0, max = (int)buffers.size()
|
||||
;j < max
|
||||
;++j){
|
||||
boost_cont_free(buffers[j]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case InverseDeallocation:
|
||||
{
|
||||
for(int j = (int)buffers.size()
|
||||
;j--
|
||||
;){
|
||||
boost_cont_free(buffers[j]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MixedDeallocation:
|
||||
{
|
||||
for(int j = 0, max = (int)buffers.size()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers.size())/4;
|
||||
boost_cont_free(buffers[pos]);
|
||||
buffers.erase(buffers.begin()+pos);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(!boost_cont_all_deallocated())
|
||||
return false;
|
||||
//bool ok = free_memory == a.get_free_memory() &&
|
||||
//a.all_memory_deallocated() && a.check_sanity();
|
||||
//if(!ok) return ok;
|
||||
}
|
||||
boost_cont_malloc_check();
|
||||
return 0 != boost_cont_all_deallocated();
|
||||
}
|
||||
|
||||
//This test allocates until there is no more memory
|
||||
//and after that tries to shrink all the buffers to the
|
||||
//half of the original size
|
||||
|
||||
bool test_allocation_shrink()
|
||||
{
|
||||
boost_cont_malloc_check();
|
||||
std::vector<void*> buffers;
|
||||
|
||||
//Allocate buffers with extra memory
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
void *ptr = boost_cont_malloc(i*2);
|
||||
if(!ptr)
|
||||
break;
|
||||
buffers.push_back(ptr);
|
||||
}
|
||||
|
||||
//Now shrink to half
|
||||
for(int i = 0, max = (int)buffers.size()
|
||||
;i < max
|
||||
; ++i){
|
||||
std::size_t try_received_size;
|
||||
void* try_result = boost_cont_allocation_command
|
||||
( BOOST_CONTAINER_TRY_SHRINK_IN_PLACE, 1, i*2
|
||||
, i, &try_received_size, (char*)buffers[i]).first;
|
||||
|
||||
std::size_t received_size;
|
||||
void* result = boost_cont_allocation_command
|
||||
( BOOST_CONTAINER_SHRINK_IN_PLACE, 1, i*2
|
||||
, i, &received_size, (char*)buffers[i]).first;
|
||||
|
||||
if(result != try_result)
|
||||
return false;
|
||||
|
||||
if(received_size != try_received_size)
|
||||
return false;
|
||||
|
||||
if(result){
|
||||
if(received_size > std::size_t(i*2)){
|
||||
return false;
|
||||
}
|
||||
if(received_size < std::size_t(i)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Deallocate it in non sequential order
|
||||
for(int j = 0, max = (int)buffers.size()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers.size())/4;
|
||||
boost_cont_free(buffers[pos]);
|
||||
buffers.erase(buffers.begin()+pos);
|
||||
}
|
||||
boost_cont_malloc_check();
|
||||
return 0 != boost_cont_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
|
||||
}
|
||||
|
||||
//This test allocates until there is no more memory
|
||||
//and after that tries to expand all the buffers to
|
||||
//avoid the wasted internal fragmentation
|
||||
|
||||
bool test_allocation_expand()
|
||||
{
|
||||
boost_cont_malloc_check();
|
||||
std::vector<void*> buffers;
|
||||
|
||||
//Allocate buffers with extra memory
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
void *ptr = boost_cont_malloc(i);
|
||||
if(!ptr)
|
||||
break;
|
||||
buffers.push_back(ptr);
|
||||
}
|
||||
|
||||
//Now try to expand to the double of the size
|
||||
for(int i = 0, max = (int)buffers.size()
|
||||
;i < max
|
||||
;++i){
|
||||
std::size_t received_size;
|
||||
std::size_t min_size = i+1;
|
||||
std::size_t preferred_size = i*2;
|
||||
preferred_size = min_size > preferred_size ? min_size : preferred_size;
|
||||
while(boost_cont_allocation_command
|
||||
( BOOST_CONTAINER_EXPAND_FWD, 1, min_size
|
||||
, preferred_size, &received_size, (char*)buffers[i]).first){
|
||||
//Check received size is bigger than minimum
|
||||
if(received_size < min_size){
|
||||
return false;
|
||||
}
|
||||
//Now, try to expand further
|
||||
min_size = received_size+1;
|
||||
preferred_size = min_size*2;
|
||||
}
|
||||
}
|
||||
|
||||
//Deallocate it in non sequential order
|
||||
for(int j = 0, max = (int)buffers.size()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers.size())/4;
|
||||
boost_cont_free(buffers[pos]);
|
||||
buffers.erase(buffers.begin()+pos);
|
||||
}
|
||||
boost_cont_malloc_check();
|
||||
return 0 != boost_cont_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
|
||||
}
|
||||
|
||||
//This test allocates until there is no more memory
|
||||
//and after that tries to expand all the buffers to
|
||||
//avoid the wasted internal fragmentation
|
||||
bool test_allocation_shrink_and_expand()
|
||||
{
|
||||
std::vector<void*> buffers;
|
||||
std::vector<std::size_t> received_sizes;
|
||||
std::vector<bool> size_reduced;
|
||||
|
||||
//Allocate buffers wand store received sizes
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
std::size_t received_size;
|
||||
void *ptr = boost_cont_allocation_command
|
||||
(BOOST_CONTAINER_ALLOCATE_NEW, 1, i, i*2, &received_size, 0).first;
|
||||
if(!ptr){
|
||||
ptr = boost_cont_allocation_command
|
||||
( BOOST_CONTAINER_ALLOCATE_NEW, 1, 1, i*2, &received_size, 0).first;
|
||||
if(!ptr)
|
||||
break;
|
||||
}
|
||||
buffers.push_back(ptr);
|
||||
received_sizes.push_back(received_size);
|
||||
}
|
||||
|
||||
//Now shrink to half
|
||||
for(int i = 0, max = (int)buffers.size()
|
||||
; i < max
|
||||
; ++i){
|
||||
std::size_t received_size;
|
||||
bool size_reduced_flag;
|
||||
if(true == (size_reduced_flag = !!
|
||||
boost_cont_allocation_command
|
||||
( BOOST_CONTAINER_SHRINK_IN_PLACE, 1, received_sizes[i]
|
||||
, i, &received_size, (char*)buffers[i]).first)){
|
||||
if(received_size > std::size_t(received_sizes[i])){
|
||||
return false;
|
||||
}
|
||||
if(received_size < std::size_t(i)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
size_reduced.push_back(size_reduced_flag);
|
||||
}
|
||||
|
||||
//Now try to expand to the original size
|
||||
for(int i = 0, max = (int)buffers.size()
|
||||
;i < max
|
||||
;++i){
|
||||
if(!size_reduced[i]) continue;
|
||||
std::size_t received_size;
|
||||
std::size_t request_size = received_sizes[i];
|
||||
if(boost_cont_allocation_command
|
||||
( BOOST_CONTAINER_EXPAND_FWD, 1, request_size
|
||||
, request_size, &received_size, (char*)buffers[i]).first){
|
||||
if(received_size != request_size){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Deallocate it in non sequential order
|
||||
for(int j = 0, max = (int)buffers.size()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers.size())/4;
|
||||
boost_cont_free(buffers[pos]);
|
||||
buffers.erase(buffers.begin()+pos);
|
||||
}
|
||||
|
||||
return 0 != boost_cont_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
|
||||
}
|
||||
|
||||
//This test allocates until there is no more memory
|
||||
//and after that deallocates the odd buffers to
|
||||
//make room for expansions. The expansion will probably
|
||||
//success since the deallocation left room for that.
|
||||
|
||||
bool test_allocation_deallocation_expand()
|
||||
{
|
||||
boost_cont_malloc_check();
|
||||
std::vector<void*> buffers;
|
||||
|
||||
//Allocate buffers with extra memory
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
void *ptr = boost_cont_malloc(i);
|
||||
if(!ptr)
|
||||
break;
|
||||
buffers.push_back(ptr);
|
||||
}
|
||||
|
||||
//Now deallocate the half of the blocks
|
||||
//so expand maybe can merge new free blocks
|
||||
for(int i = 0, max = (int)buffers.size()
|
||||
;i < max
|
||||
;++i){
|
||||
if(i%2){
|
||||
boost_cont_free(buffers[i]);
|
||||
buffers[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//Now try to expand to the double of the size
|
||||
for(int i = 0, max = (int)buffers.size()
|
||||
;i < max
|
||||
;++i){
|
||||
//
|
||||
if(buffers[i]){
|
||||
std::size_t received_size;
|
||||
std::size_t min_size = i+1;
|
||||
std::size_t preferred_size = i*2;
|
||||
preferred_size = min_size > preferred_size ? min_size : preferred_size;
|
||||
|
||||
while(boost_cont_allocation_command
|
||||
( BOOST_CONTAINER_EXPAND_FWD, 1, min_size
|
||||
, preferred_size, &received_size, (char*)buffers[i]).first){
|
||||
//Check received size is bigger than minimum
|
||||
if(received_size < min_size){
|
||||
return false;
|
||||
}
|
||||
//Now, try to expand further
|
||||
min_size = received_size+1;
|
||||
preferred_size = min_size*2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Now erase null values from the vector
|
||||
buffers.erase(std::remove(buffers.begin(), buffers.end(), (void*)0)
|
||||
,buffers.end());
|
||||
|
||||
//Deallocate it in non sequential order
|
||||
for(int j = 0, max = (int)buffers.size()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers.size())/4;
|
||||
boost_cont_free(buffers[pos]);
|
||||
buffers.erase(buffers.begin()+pos);
|
||||
}
|
||||
boost_cont_malloc_check();
|
||||
return 0 != boost_cont_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
|
||||
}
|
||||
|
||||
//This test allocates until there is no more memory
|
||||
//and after that deallocates all except the last.
|
||||
//If the allocation algorithm is a bottom-up algorithm
|
||||
//the last buffer will be in the end of the segment.
|
||||
//Then the test will start expanding backwards, until
|
||||
//the buffer fills all the memory
|
||||
|
||||
bool test_allocation_with_reuse()
|
||||
{
|
||||
boost_cont_malloc_check();
|
||||
//We will repeat this test for different sized elements
|
||||
for(int sizeof_object = 1; sizeof_object < 20; ++sizeof_object){
|
||||
std::vector<void*> buffers;
|
||||
|
||||
//Allocate buffers with extra memory
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
void *ptr = boost_cont_malloc(i*sizeof_object);
|
||||
if(!ptr)
|
||||
break;
|
||||
buffers.push_back(ptr);
|
||||
}
|
||||
|
||||
//Now deallocate all except the latest
|
||||
//Now try to expand to the double of the size
|
||||
for(int i = 0, max = (int)buffers.size() - 1
|
||||
;i < max
|
||||
;++i){
|
||||
boost_cont_free(buffers[i]);
|
||||
}
|
||||
|
||||
//Save the unique buffer and clear vector
|
||||
void *ptr = buffers.back();
|
||||
buffers.clear();
|
||||
|
||||
//Now allocate with reuse
|
||||
std::size_t received_size = 0;
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
std::size_t min_size = (received_size/sizeof_object + 1)*sizeof_object;
|
||||
std::size_t prf_size = (received_size/sizeof_object + (i+1)*2)*sizeof_object;
|
||||
boost_cont_command_ret_t ret = boost_cont_allocation_command
|
||||
( BOOST_CONTAINER_EXPAND_BWD, sizeof_object, min_size
|
||||
, prf_size, &received_size, (char*)ptr);
|
||||
//If we have memory, this must be a buffer reuse
|
||||
if(!ret.first)
|
||||
break;
|
||||
//If we have memory, this must be a buffer reuse
|
||||
if(!ret.second)
|
||||
return false;
|
||||
if(received_size < min_size)
|
||||
return false;
|
||||
ptr = ret.first;
|
||||
}
|
||||
//There should be only a single block so deallocate it
|
||||
boost_cont_free(ptr);
|
||||
boost_cont_malloc_check();
|
||||
if(!boost_cont_all_deallocated())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//This test allocates memory with different alignments
|
||||
//and checks returned memory is aligned.
|
||||
|
||||
bool test_aligned_allocation()
|
||||
{
|
||||
boost_cont_malloc_check();
|
||||
//Allocate aligned buffers in a loop
|
||||
//and then deallocate it
|
||||
for(unsigned int i = 1; i != (1 << (sizeof(int)/2)); i <<= 1){
|
||||
for(unsigned int j = 1; j != 512; j <<= 1){
|
||||
void *ptr = boost_cont_memalign(i-1, j);
|
||||
if(!ptr){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(((std::size_t)ptr & (j - 1)) != 0)
|
||||
return false;
|
||||
boost_cont_free(ptr);
|
||||
//if(!a.all_memory_deallocated() || !a.check_sanity()){
|
||||
// return false;
|
||||
//}
|
||||
}
|
||||
}
|
||||
boost_cont_malloc_check();
|
||||
return 0 != boost_cont_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
|
||||
}
|
||||
|
||||
//This test allocates memory with different alignments
|
||||
//and checks returned memory is aligned.
|
||||
|
||||
bool test_continuous_aligned_allocation()
|
||||
{
|
||||
boost_cont_malloc_check();
|
||||
std::vector<void*> buffers;
|
||||
//Allocate aligned buffers in a loop
|
||||
//and then deallocate it
|
||||
bool continue_loop = true;
|
||||
unsigned int MaxAlign = 4096;
|
||||
unsigned int MaxSize = 4096;
|
||||
for(unsigned i = 1; i < MaxSize; i <<= 1){
|
||||
for(unsigned int j = 1; j < MaxAlign; j <<= 1){
|
||||
for(int k = 0; k != NumIt; ++k){
|
||||
void *ptr = boost_cont_memalign(i-1, j);
|
||||
buffers.push_back(ptr);
|
||||
if(!ptr){
|
||||
continue_loop = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(((std::size_t)ptr & (j - 1)) != 0)
|
||||
return false;
|
||||
}
|
||||
//Deallocate all
|
||||
for(int k = (int)buffers.size(); k--;){
|
||||
boost_cont_free(buffers[k]);
|
||||
}
|
||||
buffers.clear();
|
||||
//if(!a.all_memory_deallocated() && a.check_sanity())
|
||||
// return false;
|
||||
if(!continue_loop)
|
||||
break;
|
||||
}
|
||||
}
|
||||
boost_cont_malloc_check();
|
||||
return 0 != boost_cont_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
|
||||
}
|
||||
|
||||
//This test allocates multiple values until there is no more memory
|
||||
//and after that deallocates all in the inverse order
|
||||
bool test_many_equal_allocation()
|
||||
{
|
||||
boost_cont_malloc_check();
|
||||
for( deallocation_type t = DirectDeallocation
|
||||
; t != EndDeallocationType
|
||||
; t = (deallocation_type)((int)t + 1)){
|
||||
//std::size_t free_memory = a.get_free_memory();
|
||||
|
||||
std::vector<void*> buffers2;
|
||||
|
||||
//Allocate buffers with extra memory
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
void *ptr = boost_cont_malloc(i);
|
||||
if(!ptr)
|
||||
break;
|
||||
//if(!a.check_sanity())
|
||||
//return false;
|
||||
buffers2.push_back(ptr);
|
||||
}
|
||||
|
||||
//Now deallocate the half of the blocks
|
||||
//so expand maybe can merge new free blocks
|
||||
for(int i = 0, max = (int)buffers2.size()
|
||||
;i < max
|
||||
;++i){
|
||||
if(i%2){
|
||||
boost_cont_free(buffers2[i]);
|
||||
buffers2[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//if(!a.check_sanity())
|
||||
//return false;
|
||||
|
||||
std::vector<void*> buffers;
|
||||
for(int i = 0; i != NumIt/10; ++i){
|
||||
boost_cont_memchain chain;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
|
||||
boost_cont_multialloc_nodes((i+1)*2, i+1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
|
||||
boost_cont_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
|
||||
if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
|
||||
break;
|
||||
|
||||
std::size_t n = 0;
|
||||
for(; !BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it); ++n){
|
||||
buffers.push_back(BOOST_CONTAINER_MEMIT_ADDR(it));
|
||||
BOOST_CONTAINER_MEMIT_NEXT(it);
|
||||
}
|
||||
if(n != std::size_t((i+1)*2))
|
||||
return false;
|
||||
}
|
||||
|
||||
//if(!a.check_sanity())
|
||||
//return false;
|
||||
|
||||
switch(t){
|
||||
case DirectDeallocation:
|
||||
{
|
||||
for(int j = 0, max = (int)buffers.size()
|
||||
;j < max
|
||||
;++j){
|
||||
boost_cont_free(buffers[j]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case InverseDeallocation:
|
||||
{
|
||||
for(int j = (int)buffers.size()
|
||||
;j--
|
||||
;){
|
||||
boost_cont_free(buffers[j]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MixedDeallocation:
|
||||
{
|
||||
for(int j = 0, max = (int)buffers.size()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers.size())/4;
|
||||
boost_cont_free(buffers[pos]);
|
||||
buffers.erase(buffers.begin()+pos);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//Deallocate the rest of the blocks
|
||||
|
||||
//Deallocate it in non sequential order
|
||||
for(int j = 0, max = (int)buffers2.size()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers2.size())/4;
|
||||
boost_cont_free(buffers2[pos]);
|
||||
buffers2.erase(buffers2.begin()+pos);
|
||||
}
|
||||
|
||||
//bool ok = free_memory == a.get_free_memory() &&
|
||||
//a.all_memory_deallocated() && a.check_sanity();
|
||||
//if(!ok) return ok;
|
||||
}
|
||||
boost_cont_malloc_check();
|
||||
return 0 != boost_cont_all_deallocated();
|
||||
}
|
||||
|
||||
//This test allocates multiple values until there is no more memory
|
||||
//and after that deallocates all in the inverse order
|
||||
|
||||
bool test_many_different_allocation()
|
||||
{
|
||||
boost_cont_malloc_check();
|
||||
const std::size_t ArraySize = 11;
|
||||
std::size_t requested_sizes[ArraySize];
|
||||
for(std::size_t i = 0; i < ArraySize; ++i){
|
||||
requested_sizes[i] = 4*i;
|
||||
}
|
||||
|
||||
for( deallocation_type t = DirectDeallocation
|
||||
; t != EndDeallocationType
|
||||
; t = (deallocation_type)((int)t + 1)){
|
||||
//std::size_t free_memory = a.get_free_memory();
|
||||
|
||||
std::vector<void*> buffers2;
|
||||
|
||||
//Allocate buffers with extra memory
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
void *ptr = boost_cont_malloc(i);
|
||||
if(!ptr)
|
||||
break;
|
||||
buffers2.push_back(ptr);
|
||||
}
|
||||
|
||||
//Now deallocate the half of the blocks
|
||||
//so expand maybe can merge new free blocks
|
||||
for(int i = 0, max = (int)buffers2.size()
|
||||
;i < max
|
||||
;++i){
|
||||
if(i%2){
|
||||
boost_cont_free(buffers2[i]);
|
||||
buffers2[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<void*> buffers;
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
boost_cont_memchain chain;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
|
||||
boost_cont_multialloc_arrays(ArraySize, requested_sizes, 1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
|
||||
boost_cont_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
|
||||
if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
|
||||
break;
|
||||
std::size_t n = 0;
|
||||
for(; !BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it); ++n){
|
||||
buffers.push_back(BOOST_CONTAINER_MEMIT_ADDR(it));
|
||||
BOOST_CONTAINER_MEMIT_NEXT(it);
|
||||
}
|
||||
if(n != ArraySize)
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(t){
|
||||
case DirectDeallocation:
|
||||
{
|
||||
for(int j = 0, max = (int)buffers.size()
|
||||
;j < max
|
||||
;++j){
|
||||
boost_cont_free(buffers[j]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case InverseDeallocation:
|
||||
{
|
||||
for(int j = (int)buffers.size()
|
||||
;j--
|
||||
;){
|
||||
boost_cont_free(buffers[j]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MixedDeallocation:
|
||||
{
|
||||
for(int j = 0, max = (int)buffers.size()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers.size())/4;
|
||||
boost_cont_free(buffers[pos]);
|
||||
buffers.erase(buffers.begin()+pos);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//Deallocate the rest of the blocks
|
||||
|
||||
//Deallocate it in non sequential order
|
||||
for(int j = 0, max = (int)buffers2.size()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers2.size())/4;
|
||||
boost_cont_free(buffers2[pos]);
|
||||
buffers2.erase(buffers2.begin()+pos);
|
||||
}
|
||||
|
||||
//bool ok = free_memory == a.get_free_memory() &&
|
||||
//a.all_memory_deallocated() && a.check_sanity();
|
||||
//if(!ok) return ok;
|
||||
}
|
||||
boost_cont_malloc_check();
|
||||
return 0 != boost_cont_all_deallocated();
|
||||
}
|
||||
|
||||
bool test_many_deallocation()
|
||||
{
|
||||
const std::size_t ArraySize = 11;
|
||||
std::vector<boost_cont_memchain> buffers;
|
||||
std::size_t requested_sizes[ArraySize];
|
||||
for(std::size_t i = 0; i < ArraySize; ++i){
|
||||
requested_sizes[i] = 4*i;
|
||||
}
|
||||
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
boost_cont_memchain chain;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
|
||||
boost_cont_multialloc_arrays(ArraySize, requested_sizes, 1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
|
||||
boost_cont_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
|
||||
if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
|
||||
return false;
|
||||
buffers.push_back(chain);
|
||||
}
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
boost_cont_multidealloc(&buffers[i]);
|
||||
}
|
||||
buffers.clear();
|
||||
|
||||
boost_cont_malloc_check();
|
||||
if(!boost_cont_all_deallocated())
|
||||
return false;
|
||||
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
boost_cont_memchain chain;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
|
||||
boost_cont_multialloc_nodes(ArraySize, i*4+1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
|
||||
boost_cont_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
|
||||
if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
|
||||
return false;
|
||||
buffers.push_back(chain);
|
||||
}
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
boost_cont_multidealloc(&buffers[i]);
|
||||
}
|
||||
buffers.clear();
|
||||
|
||||
boost_cont_malloc_check();
|
||||
if(!boost_cont_all_deallocated())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//This function calls all tests
|
||||
|
||||
bool test_all_allocation()
|
||||
{
|
||||
std::cout << "Starting test_allocation"
|
||||
<< std::endl;
|
||||
|
||||
if(!test_allocation()){
|
||||
std::cout << "test_allocation_direct_deallocation failed"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "Starting test_many_equal_allocation"
|
||||
<< std::endl;
|
||||
|
||||
if(!test_many_equal_allocation()){
|
||||
std::cout << "test_many_equal_allocation failed"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "Starting test_many_different_allocation"
|
||||
<< std::endl;
|
||||
|
||||
if(!test_many_different_allocation()){
|
||||
std::cout << "test_many_different_allocation failed"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "Starting test_allocation_shrink"
|
||||
<< std::endl;
|
||||
|
||||
if(!test_allocation_shrink()){
|
||||
std::cout << "test_allocation_shrink failed"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!test_allocation_shrink_and_expand()){
|
||||
std::cout << "test_allocation_shrink_and_expand failed"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "Starting test_allocation_expand"
|
||||
<< std::endl;
|
||||
|
||||
if(!test_allocation_expand()){
|
||||
std::cout << "test_allocation_expand failed"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "Starting test_allocation_deallocation_expand"
|
||||
<< std::endl;
|
||||
|
||||
if(!test_allocation_deallocation_expand()){
|
||||
std::cout << "test_allocation_deallocation_expand failed"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "Starting test_allocation_with_reuse"
|
||||
<< std::endl;
|
||||
|
||||
if(!test_allocation_with_reuse()){
|
||||
std::cout << "test_allocation_with_reuse failed"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "Starting test_aligned_allocation"
|
||||
<< std::endl;
|
||||
|
||||
if(!test_aligned_allocation()){
|
||||
std::cout << "test_aligned_allocation failed"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "Starting test_continuous_aligned_allocation"
|
||||
<< std::endl;
|
||||
|
||||
if(!test_continuous_aligned_allocation()){
|
||||
std::cout << "test_continuous_aligned_allocation failed"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!test_many_deallocation()){
|
||||
std::cout << "test_many_deallocation failed"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return 0 != boost_cont_all_deallocated();
|
||||
}
|
||||
|
||||
}}} //namespace boost { namespace container { namespace test {
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
if(!boost::container::test::test_all_allocation())
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. 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)
|
||||
//
|
||||
|
||||
@@ -30,6 +30,23 @@ bool CheckEqual( const T1 &t1, const T2 &t2
|
||||
>::type* = 0)
|
||||
{ return t1 == t2; }
|
||||
|
||||
|
||||
template<class T1, class T2, class C1, class C2>
|
||||
bool CheckEqualIt( const T1 &i1, const T2 &i2, const C1 &c1, const C2 &c2 )
|
||||
{
|
||||
bool c1end = i1 == c1.end();
|
||||
bool c2end = i2 == c2.end();
|
||||
if( c1end != c2end ){
|
||||
return false;
|
||||
}
|
||||
else if(c1end){
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return CheckEqual(*i1, *i2);
|
||||
}
|
||||
}
|
||||
|
||||
template< class Pair1, class Pair2>
|
||||
bool CheckEqual( const Pair1 &pair1, const Pair2 &pair2
|
||||
, typename boost::container::container_detail::enable_if_c
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013. 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_DEFAULT_INIT_TEST_HEADER
|
||||
#define BOOST_CONTAINER_TEST_DEFAULT_INIT_TEST_HEADER
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
|
||||
#include <boost/move/utility.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"
|
||||
#include "input_from_forward_iterator.hpp"
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/move/iterator.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include "insert_test.hpp"
|
||||
|
||||
namespace boost{
|
||||
namespace container {
|
||||
namespace test{
|
||||
|
||||
//
|
||||
template<int Dummy = 0>
|
||||
class default_init_allocator_base
|
||||
{
|
||||
protected:
|
||||
static unsigned char s_pattern;
|
||||
static bool s_ascending;
|
||||
|
||||
public:
|
||||
static void reset_pattern(unsigned char value)
|
||||
{ s_pattern = value; }
|
||||
|
||||
static void set_ascending(bool enable)
|
||||
{ s_ascending = enable; }
|
||||
};
|
||||
|
||||
template<int Dummy>
|
||||
unsigned char default_init_allocator_base<Dummy>::s_pattern = 0u;
|
||||
|
||||
template<int Dummy>
|
||||
bool default_init_allocator_base<Dummy>::s_ascending = true;
|
||||
|
||||
template<class Integral>
|
||||
class default_init_allocator
|
||||
: public default_init_allocator_base<0>
|
||||
{
|
||||
typedef default_init_allocator_base<0> base_t;
|
||||
public:
|
||||
typedef Integral value_type;
|
||||
|
||||
default_init_allocator()
|
||||
{}
|
||||
|
||||
template <class U>
|
||||
default_init_allocator(default_init_allocator<U>)
|
||||
{}
|
||||
|
||||
Integral* allocate(std::size_t n)
|
||||
{
|
||||
//Initialize memory to a pattern
|
||||
const std::size_t max = sizeof(Integral)*n;
|
||||
unsigned char *puc_raw = ::new unsigned char[max];
|
||||
|
||||
if(base_t::s_ascending){
|
||||
for(std::size_t i = 0; i != max; ++i){
|
||||
puc_raw[i] = static_cast<unsigned char>(s_pattern++);
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(std::size_t i = 0; i != max; ++i){
|
||||
puc_raw[i] = static_cast<unsigned char>(s_pattern--);
|
||||
}
|
||||
}
|
||||
return (Integral*)puc_raw;;
|
||||
}
|
||||
|
||||
void deallocate(Integral *p, std::size_t)
|
||||
{ delete[] (unsigned char*)p; }
|
||||
};
|
||||
|
||||
template<class Integral>
|
||||
inline bool check_ascending_byte_pattern(const Integral&t)
|
||||
{
|
||||
const unsigned char *pch = &reinterpret_cast<const unsigned char &>(t);
|
||||
const std::size_t max = sizeof(Integral);
|
||||
for(std::size_t i = 1; i != max; ++i){
|
||||
if( (pch[i-1] != ((unsigned char)(pch[i]-1u))) ){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class Integral>
|
||||
inline bool check_descending_byte_pattern(const Integral&t)
|
||||
{
|
||||
const unsigned char *pch = &reinterpret_cast<const unsigned char &>(t);
|
||||
const std::size_t max = sizeof(Integral);
|
||||
for(std::size_t i = 1; i != max; ++i){
|
||||
if( (pch[i-1] != ((unsigned char)(pch[i]+1u))) ){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class IntDefaultInitAllocVector>
|
||||
bool default_init_test()//Test for default initialization
|
||||
{
|
||||
const std::size_t Capacity = 100;
|
||||
|
||||
{
|
||||
test::default_init_allocator<int>::reset_pattern(0);
|
||||
test::default_init_allocator<int>::set_ascending(true);
|
||||
IntDefaultInitAllocVector v(Capacity, default_init);
|
||||
typename IntDefaultInitAllocVector::iterator it = v.begin();
|
||||
//Compare with the pattern
|
||||
for(std::size_t i = 0; i != Capacity; ++i, ++it){
|
||||
if(!test::check_ascending_byte_pattern(*it))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
{
|
||||
test::default_init_allocator<int>::reset_pattern(100);
|
||||
test::default_init_allocator<int>::set_ascending(false);
|
||||
IntDefaultInitAllocVector v;
|
||||
v.resize(Capacity, default_init);
|
||||
typename IntDefaultInitAllocVector::iterator it = v.begin();
|
||||
//Compare with the pattern
|
||||
for(std::size_t i = 0; i != Capacity; ++i, ++it){
|
||||
if(!test::check_descending_byte_pattern(*it))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} //namespace test{
|
||||
} //namespace container {
|
||||
} //namespace boost{
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_TEST_DEFAULT_INIT_TEST_HEADER
|
||||
+85
-22
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. 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)
|
||||
//
|
||||
@@ -17,6 +17,10 @@
|
||||
#include <list>
|
||||
|
||||
#include <boost/container/deque.hpp>
|
||||
#include <boost/container/allocator.hpp>
|
||||
#include <boost/container/node_allocator.hpp>
|
||||
#include <boost/container/adaptive_pool.hpp>
|
||||
|
||||
#include "print_container.hpp"
|
||||
#include "check_equal_containers.hpp"
|
||||
#include "dummy_test_allocator.hpp"
|
||||
@@ -29,6 +33,7 @@
|
||||
#include "emplace_test.hpp"
|
||||
#include "propagate_allocator_test.hpp"
|
||||
#include "vector_test.hpp"
|
||||
#include "default_init_test.hpp"
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
|
||||
using namespace boost::container;
|
||||
@@ -49,6 +54,18 @@ template class boost::container::deque
|
||||
< test::movable_and_copyable_int
|
||||
, std::allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::deque
|
||||
< test::movable_and_copyable_int
|
||||
, allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::deque
|
||||
< test::movable_and_copyable_int
|
||||
, adaptive_pool<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::deque
|
||||
< test::movable_and_copyable_int
|
||||
, node_allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
}}
|
||||
|
||||
//Function to check if both sets are equal
|
||||
@@ -145,11 +162,8 @@ bool do_test()
|
||||
typedef std::deque<int> MyStdDeque;
|
||||
const int max = 100;
|
||||
BOOST_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
|
||||
for(int i = 0; i < max*100; ++i){
|
||||
IntType move_me(i);
|
||||
cntdeque->insert(cntdeque->end(), boost::move(move_me));
|
||||
@@ -295,6 +309,38 @@ bool do_test()
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class VoidAllocator>
|
||||
struct GetAllocatorCont
|
||||
{
|
||||
template<class ValueType>
|
||||
struct apply
|
||||
{
|
||||
typedef deque< ValueType
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc<ValueType>::type
|
||||
> type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class VoidAllocator>
|
||||
int test_cont_variants()
|
||||
{
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<int>::type MyCont;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_int>::type MyMoveCont;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_and_copyable_int>::type MyCopyMoveCont;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::copyable_int>::type MyCopyCont;
|
||||
|
||||
if(test::vector_test<MyCont>())
|
||||
return 1;
|
||||
if(test::vector_test<MyMoveCont>())
|
||||
return 1;
|
||||
if(test::vector_test<MyCopyMoveCont>())
|
||||
return 1;
|
||||
if(test::vector_test<MyCopyCont>())
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main ()
|
||||
{
|
||||
@@ -319,31 +365,48 @@ int main ()
|
||||
d.resize(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;
|
||||
if(!test::default_init_test< deque<int, test::default_init_allocator<int> > >()){
|
||||
std::cerr << "Default init test failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
////////////////////////////////////
|
||||
// Allocator implementations
|
||||
////////////////////////////////////
|
||||
// std:allocator
|
||||
if(test_cont_variants< std::allocator<void> >()){
|
||||
std::cerr << "test_cont_variants< std::allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::allocator
|
||||
if(test_cont_variants< allocator<void> >()){
|
||||
std::cerr << "test_cont_variants< allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::node_allocator
|
||||
if(test_cont_variants< node_allocator<void> >()){
|
||||
std::cerr << "test_cont_variants< node_allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::adaptive_pool
|
||||
if(test_cont_variants< adaptive_pool<void> >()){
|
||||
std::cerr << "test_cont_variants< adaptive_pool<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
////////////////////////////////////
|
||||
// Default init test
|
||||
////////////////////////////////////
|
||||
if(!test::default_init_test< deque<int, test::default_init_allocator<int> > >()){
|
||||
std::cerr << "Default init test failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Emplace testing
|
||||
////////////////////////////////////
|
||||
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;
|
||||
|
||||
////////////////////////////////////
|
||||
// Allocator propagation testing
|
||||
////////////////////////////////////
|
||||
if(!boost::container::test::test_propagate_allocator<deque>())
|
||||
return 1;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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)
|
||||
//
|
||||
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_DUMMY_TEST_ALLOCATOR_HPP
|
||||
#define BOOST_CONTAINER_DUMMY_TEST_ALLOCATOR_HPP
|
||||
|
||||
#if (defined _MSC_VER)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -33,9 +33,6 @@
|
||||
#include <cstddef>
|
||||
#include <cassert>
|
||||
|
||||
//!\file
|
||||
//!Describes an allocator to test expand capabilities
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace test {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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)
|
||||
//
|
||||
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP
|
||||
#define BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP
|
||||
|
||||
#if (defined _MSC_VER)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -29,9 +29,6 @@
|
||||
#include <cstddef>
|
||||
#include <cassert>
|
||||
|
||||
//!\file
|
||||
//!Describes an allocator to test expand capabilities
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace test {
|
||||
|
||||
@@ -187,8 +187,8 @@ bool test_assign_with_expand_bwd()
|
||||
|
||||
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);
|
||||
const int InsertSize[] = { 15, 35, 55};
|
||||
const int Iterations = sizeof(InsertSize)/sizeof(int);
|
||||
|
||||
for(int iteration = 0; iteration <Iterations; ++iteration)
|
||||
{
|
||||
@@ -202,10 +202,10 @@ bool test_assign_with_expand_bwd()
|
||||
}
|
||||
|
||||
//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;
|
||||
std::vector<non_volatile_value_type> data_to_insert;
|
||||
data_to_insert.resize(InsertSize[iteration]);
|
||||
for(int i = 0; i < InsertSize[iteration]; ++i){
|
||||
data_to_insert[i] = -i;
|
||||
}
|
||||
|
||||
//Insert initial data to the vector to test
|
||||
@@ -216,8 +216,8 @@ bool test_assign_with_expand_bwd()
|
||||
, 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());
|
||||
vector.insert(vector.cbegin(), data_to_insert.begin(), data_to_insert.end());
|
||||
initial_data.insert(initial_data.begin(), data_to_insert.begin(), data_to_insert.end());
|
||||
|
||||
//Now check that values are equal
|
||||
if(!CheckEqualVector(vector, initial_data)){
|
||||
|
||||
@@ -0,0 +1,459 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. 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/flat_map.hpp>
|
||||
#include <boost/container/allocator.hpp>
|
||||
#include <boost/container/node_allocator.hpp>
|
||||
#include <boost/container/adaptive_pool.hpp>
|
||||
|
||||
#include "print_container.hpp"
|
||||
#include "dummy_test_allocator.hpp"
|
||||
#include "movable_int.hpp"
|
||||
#include "map_test.hpp"
|
||||
#include "propagate_allocator_test.hpp"
|
||||
#include "emplace_test.hpp"
|
||||
#include <vector>
|
||||
#include <boost/container/detail/flat_tree.hpp>
|
||||
|
||||
using namespace boost::container;
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//Explicit instantiation to detect compilation errors
|
||||
|
||||
//flat_map
|
||||
template class flat_map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class flat_map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class flat_map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class flat_map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class flat_map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class flat_map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, node_allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
//flat_multimap
|
||||
template class flat_multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class flat_multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class flat_multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class flat_multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class flat_multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class flat_multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, node_allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
//As flat container iterators are typedefs for vector::[const_]iterator,
|
||||
//no need to explicit instantiate them
|
||||
|
||||
}} //boost::container
|
||||
|
||||
|
||||
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_; }
|
||||
};
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
class flat_map_propagate_test_wrapper
|
||||
: public boost::container::flat_map
|
||||
< T, T, std::less<T>
|
||||
, typename boost::container::allocator_traits<A>::template
|
||||
portable_rebind_alloc< std::pair<T, T> >::type>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_map_propagate_test_wrapper)
|
||||
typedef boost::container::flat_map
|
||||
< T, T, std::less<T>
|
||||
, typename boost::container::allocator_traits<A>::template
|
||||
portable_rebind_alloc< std::pair<T, T> >::type> Base;
|
||||
public:
|
||||
flat_map_propagate_test_wrapper()
|
||||
: Base()
|
||||
{}
|
||||
|
||||
flat_map_propagate_test_wrapper(const flat_map_propagate_test_wrapper &x)
|
||||
: Base(x)
|
||||
{}
|
||||
|
||||
flat_map_propagate_test_wrapper(BOOST_RV_REF(flat_map_propagate_test_wrapper) x)
|
||||
: Base(boost::move(static_cast<Base&>(x)))
|
||||
{}
|
||||
|
||||
flat_map_propagate_test_wrapper &operator=(BOOST_COPY_ASSIGN_REF(flat_map_propagate_test_wrapper) x)
|
||||
{ this->Base::operator=(x); return *this; }
|
||||
|
||||
flat_map_propagate_test_wrapper &operator=(BOOST_RV_REF(flat_map_propagate_test_wrapper) x)
|
||||
{ this->Base::operator=(boost::move(static_cast<Base&>(x))); return *this; }
|
||||
|
||||
void swap(flat_map_propagate_test_wrapper &x)
|
||||
{ this->Base::swap(x); }
|
||||
};
|
||||
|
||||
namespace boost{
|
||||
namespace container {
|
||||
namespace test{
|
||||
|
||||
bool flat_tree_ordered_insertion_test()
|
||||
{
|
||||
using namespace boost::container;
|
||||
const std::size_t NumElements = 100;
|
||||
|
||||
//Ordered insertion multimap
|
||||
{
|
||||
std::multimap<int, int> int_mmap;
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
int_mmap.insert(std::multimap<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
|
||||
}
|
||||
//Construction insertion
|
||||
flat_multimap<int, int> fmmap(ordered_range, int_mmap.begin(), int_mmap.end());
|
||||
if(!CheckEqualContainers(&int_mmap, &fmmap))
|
||||
return false;
|
||||
//Insertion when empty
|
||||
fmmap.clear();
|
||||
fmmap.insert(ordered_range, int_mmap.begin(), int_mmap.end());
|
||||
if(!CheckEqualContainers(&int_mmap, &fmmap))
|
||||
return false;
|
||||
//Re-insertion
|
||||
fmmap.insert(ordered_range, int_mmap.begin(), int_mmap.end());
|
||||
std::multimap<int, int> int_mmap2(int_mmap);
|
||||
int_mmap2.insert(int_mmap.begin(), int_mmap.end());
|
||||
if(!CheckEqualContainers(&int_mmap2, &fmmap))
|
||||
return false;
|
||||
//Re-re-insertion
|
||||
fmmap.insert(ordered_range, int_mmap2.begin(), int_mmap2.end());
|
||||
std::multimap<int, int> int_mmap4(int_mmap2);
|
||||
int_mmap4.insert(int_mmap2.begin(), int_mmap2.end());
|
||||
if(!CheckEqualContainers(&int_mmap4, &fmmap))
|
||||
return false;
|
||||
//Re-re-insertion of even
|
||||
std::multimap<int, int> int_even_mmap;
|
||||
for(std::size_t i = 0; i < NumElements; i+=2){
|
||||
int_mmap.insert(std::multimap<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
|
||||
}
|
||||
fmmap.insert(ordered_range, int_even_mmap.begin(), int_even_mmap.end());
|
||||
int_mmap4.insert(int_even_mmap.begin(), int_even_mmap.end());
|
||||
if(!CheckEqualContainers(&int_mmap4, &fmmap))
|
||||
return false;
|
||||
}
|
||||
|
||||
//Ordered insertion map
|
||||
{
|
||||
std::map<int, int> int_map;
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
int_map.insert(std::map<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
|
||||
}
|
||||
//Construction insertion
|
||||
flat_map<int, int> fmap(ordered_unique_range, int_map.begin(), int_map.end());
|
||||
if(!CheckEqualContainers(&int_map, &fmap))
|
||||
return false;
|
||||
//Insertion when empty
|
||||
fmap.clear();
|
||||
fmap.insert(ordered_unique_range, int_map.begin(), int_map.end());
|
||||
if(!CheckEqualContainers(&int_map, &fmap))
|
||||
return false;
|
||||
//Re-insertion
|
||||
fmap.insert(ordered_unique_range, int_map.begin(), int_map.end());
|
||||
std::map<int, int> int_map2(int_map);
|
||||
int_map2.insert(int_map.begin(), int_map.end());
|
||||
if(!CheckEqualContainers(&int_map2, &fmap))
|
||||
return false;
|
||||
//Re-re-insertion
|
||||
fmap.insert(ordered_unique_range, int_map2.begin(), int_map2.end());
|
||||
std::map<int, int> int_map4(int_map2);
|
||||
int_map4.insert(int_map2.begin(), int_map2.end());
|
||||
if(!CheckEqualContainers(&int_map4, &fmap))
|
||||
return false;
|
||||
//Re-re-insertion of even
|
||||
std::map<int, int> int_even_map;
|
||||
for(std::size_t i = 0; i < NumElements; i+=2){
|
||||
int_map.insert(std::map<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
|
||||
}
|
||||
fmap.insert(ordered_unique_range, int_even_map.begin(), int_even_map.end());
|
||||
int_map4.insert(int_even_map.begin(), int_even_map.end());
|
||||
if(!CheckEqualContainers(&int_map4, &fmap))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
template<class VoidAllocator>
|
||||
struct GetAllocatorMap
|
||||
{
|
||||
template<class ValueType>
|
||||
struct apply
|
||||
{
|
||||
typedef flat_map< ValueType
|
||||
, ValueType
|
||||
, std::less<ValueType>
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc< std::pair<ValueType, ValueType> >::type
|
||||
> map_type;
|
||||
|
||||
typedef flat_multimap< ValueType
|
||||
, ValueType
|
||||
, std::less<ValueType>
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc< std::pair<ValueType, ValueType> >::type
|
||||
> multimap_type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class VoidAllocator>
|
||||
int test_map_variants()
|
||||
{
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<int>::map_type MyMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::movable_int>::map_type MyMoveMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::movable_and_copyable_int>::map_type MyCopyMoveMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::copyable_int>::map_type MyCopyMap;
|
||||
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<int>::multimap_type MyMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::movable_int>::multimap_type MyMoveMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::movable_and_copyable_int>::multimap_type MyCopyMoveMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::copyable_int>::multimap_type MyCopyMultiMap;
|
||||
|
||||
typedef std::map<int, int> MyStdMap;
|
||||
typedef std::multimap<int, int> MyStdMultiMap;
|
||||
|
||||
if (0 != test::map_test<
|
||||
MyMap
|
||||
,MyStdMap
|
||||
,MyMultiMap
|
||||
,MyStdMultiMap>()){
|
||||
std::cout << "Error in map_test<MyBoostMap>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::map_test<
|
||||
MyMoveMap
|
||||
,MyStdMap
|
||||
,MyMoveMultiMap
|
||||
,MyStdMultiMap>()){
|
||||
std::cout << "Error in map_test<MyBoostMap>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::map_test<
|
||||
MyCopyMoveMap
|
||||
,MyStdMap
|
||||
,MyCopyMoveMultiMap
|
||||
,MyStdMultiMap>()){
|
||||
std::cout << "Error in map_test<MyBoostMap>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::map_test<
|
||||
MyCopyMap
|
||||
,MyStdMap
|
||||
,MyCopyMultiMap
|
||||
,MyStdMultiMap>()){
|
||||
std::cout << "Error in map_test<MyBoostMap>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container::test;
|
||||
|
||||
//Allocator argument container
|
||||
{
|
||||
flat_map<int, int> map_((std::allocator<std::pair<int, int> >()));
|
||||
flat_multimap<int, int> multimap_((std::allocator<std::pair<int, int> >()));
|
||||
}
|
||||
//Now test move semantics
|
||||
{
|
||||
test_move<flat_map<recursive_flat_map, recursive_flat_map> >();
|
||||
test_move<flat_multimap<recursive_flat_multimap, recursive_flat_multimap> >();
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Ordered insertion test
|
||||
////////////////////////////////////
|
||||
if(!flat_tree_ordered_insertion_test()){
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Testing allocator implementations
|
||||
////////////////////////////////////
|
||||
// std::allocator
|
||||
if(test_map_variants< std::allocator<void> >()){
|
||||
std::cerr << "test_map_variants< std::allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::allocator
|
||||
if(test_map_variants< allocator<void> >()){
|
||||
std::cerr << "test_map_variants< allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::node_allocator
|
||||
if(test_map_variants< node_allocator<void> >()){
|
||||
std::cerr << "test_map_variants< node_allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::adaptive_pool
|
||||
if(test_map_variants< adaptive_pool<void> >()){
|
||||
std::cerr << "test_map_variants< adaptive_pool<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Emplace testing
|
||||
////////////////////////////////////
|
||||
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;
|
||||
|
||||
////////////////////////////////////
|
||||
// Allocator propagation testing
|
||||
////////////////////////////////////
|
||||
if(!boost::container::test::test_propagate_allocator<flat_map_propagate_test_wrapper>())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
@@ -0,0 +1,481 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. 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/allocator.hpp>
|
||||
#include <boost/container/node_allocator.hpp>
|
||||
#include <boost/container/adaptive_pool.hpp>
|
||||
|
||||
#include "print_container.hpp"
|
||||
#include "dummy_test_allocator.hpp"
|
||||
#include "movable_int.hpp"
|
||||
#include "set_test.hpp"
|
||||
#include "propagate_allocator_test.hpp"
|
||||
#include "emplace_test.hpp"
|
||||
#include <vector>
|
||||
#include <boost/container/detail/flat_tree.hpp>
|
||||
|
||||
using namespace boost::container;
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//Explicit instantiation to detect compilation errors
|
||||
|
||||
//flat_set
|
||||
template class flat_set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, node_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
//flat_multiset
|
||||
template class flat_multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, node_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
//Instantiate base class as previous instantiations don't instantiate inherited members
|
||||
template class flat_tree
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_tree
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_tree
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_tree
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_tree
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_tree
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, node_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
} //container_detail {
|
||||
|
||||
//As flat container iterators are typedefs for vector::[const_]iterator,
|
||||
//no need to explicit instantiate them
|
||||
|
||||
}} //boost::container
|
||||
|
||||
//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_; }
|
||||
};
|
||||
|
||||
|
||||
//Test recursive structures
|
||||
class recursive_flat_multiset
|
||||
{
|
||||
public:
|
||||
recursive_flat_multiset(const recursive_flat_multiset &c)
|
||||
: id_(c.id_), flat_multiset_(c.flat_multiset_)
|
||||
{}
|
||||
|
||||
recursive_flat_multiset & operator =(const recursive_flat_multiset &c)
|
||||
{
|
||||
id_ = c.id_;
|
||||
flat_multiset_= c.flat_multiset_;
|
||||
return *this;
|
||||
}
|
||||
int id_;
|
||||
flat_multiset<recursive_flat_multiset> flat_multiset_;
|
||||
friend bool operator< (const recursive_flat_multiset &a, const recursive_flat_multiset &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);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
class flat_set_propagate_test_wrapper
|
||||
: public boost::container::flat_set<T, std::less<T>, A>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_set_propagate_test_wrapper)
|
||||
typedef boost::container::flat_set<T, std::less<T>, A> Base;
|
||||
public:
|
||||
flat_set_propagate_test_wrapper()
|
||||
: Base()
|
||||
{}
|
||||
|
||||
flat_set_propagate_test_wrapper(const flat_set_propagate_test_wrapper &x)
|
||||
: Base(x)
|
||||
{}
|
||||
|
||||
flat_set_propagate_test_wrapper(BOOST_RV_REF(flat_set_propagate_test_wrapper) x)
|
||||
: Base(boost::move(static_cast<Base&>(x)))
|
||||
{}
|
||||
|
||||
flat_set_propagate_test_wrapper &operator=(BOOST_COPY_ASSIGN_REF(flat_set_propagate_test_wrapper) x)
|
||||
{ this->Base::operator=(x); return *this; }
|
||||
|
||||
flat_set_propagate_test_wrapper &operator=(BOOST_RV_REF(flat_set_propagate_test_wrapper) x)
|
||||
{ this->Base::operator=(boost::move(static_cast<Base&>(x))); return *this; }
|
||||
|
||||
void swap(flat_set_propagate_test_wrapper &x)
|
||||
{ this->Base::swap(x); }
|
||||
};
|
||||
|
||||
namespace boost{
|
||||
namespace container {
|
||||
namespace test{
|
||||
|
||||
bool flat_tree_ordered_insertion_test()
|
||||
{
|
||||
using namespace boost::container;
|
||||
const std::size_t NumElements = 100;
|
||||
|
||||
//Ordered insertion multiset
|
||||
{
|
||||
std::multiset<int> int_mset;
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
int_mset.insert(static_cast<int>(i));
|
||||
}
|
||||
//Construction insertion
|
||||
flat_multiset<int> fmset(ordered_range, int_mset.begin(), int_mset.end());
|
||||
if(!CheckEqualContainers(&int_mset, &fmset))
|
||||
return false;
|
||||
//Insertion when empty
|
||||
fmset.clear();
|
||||
fmset.insert(ordered_range, int_mset.begin(), int_mset.end());
|
||||
if(!CheckEqualContainers(&int_mset, &fmset))
|
||||
return false;
|
||||
//Re-insertion
|
||||
fmset.insert(ordered_range, int_mset.begin(), int_mset.end());
|
||||
std::multiset<int> int_mset2(int_mset);
|
||||
int_mset2.insert(int_mset.begin(), int_mset.end());
|
||||
if(!CheckEqualContainers(&int_mset2, &fmset))
|
||||
return false;
|
||||
//Re-re-insertion
|
||||
fmset.insert(ordered_range, int_mset2.begin(), int_mset2.end());
|
||||
std::multiset<int> int_mset4(int_mset2);
|
||||
int_mset4.insert(int_mset2.begin(), int_mset2.end());
|
||||
if(!CheckEqualContainers(&int_mset4, &fmset))
|
||||
return false;
|
||||
//Re-re-insertion of even
|
||||
std::multiset<int> int_even_mset;
|
||||
for(std::size_t i = 0; i < NumElements; i+=2){
|
||||
int_mset.insert(static_cast<int>(i));
|
||||
}
|
||||
fmset.insert(ordered_range, int_even_mset.begin(), int_even_mset.end());
|
||||
int_mset4.insert(int_even_mset.begin(), int_even_mset.end());
|
||||
if(!CheckEqualContainers(&int_mset4, &fmset))
|
||||
return false;
|
||||
}
|
||||
|
||||
//Ordered insertion set
|
||||
{
|
||||
std::set<int> int_set;
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
int_set.insert(static_cast<int>(i));
|
||||
}
|
||||
//Construction insertion
|
||||
flat_set<int> fset(ordered_unique_range, int_set.begin(), int_set.end());
|
||||
if(!CheckEqualContainers(&int_set, &fset))
|
||||
return false;
|
||||
//Insertion when empty
|
||||
fset.clear();
|
||||
fset.insert(ordered_unique_range, int_set.begin(), int_set.end());
|
||||
if(!CheckEqualContainers(&int_set, &fset))
|
||||
return false;
|
||||
//Re-insertion
|
||||
fset.insert(ordered_unique_range, int_set.begin(), int_set.end());
|
||||
std::set<int> int_set2(int_set);
|
||||
int_set2.insert(int_set.begin(), int_set.end());
|
||||
if(!CheckEqualContainers(&int_set2, &fset))
|
||||
return false;
|
||||
//Re-re-insertion
|
||||
fset.insert(ordered_unique_range, int_set2.begin(), int_set2.end());
|
||||
std::set<int> int_set4(int_set2);
|
||||
int_set4.insert(int_set2.begin(), int_set2.end());
|
||||
if(!CheckEqualContainers(&int_set4, &fset))
|
||||
return false;
|
||||
//Re-re-insertion of even
|
||||
std::set<int> int_even_set;
|
||||
for(std::size_t i = 0; i < NumElements; i+=2){
|
||||
int_set.insert(static_cast<int>(i));
|
||||
}
|
||||
fset.insert(ordered_unique_range, int_even_set.begin(), int_even_set.end());
|
||||
int_set4.insert(int_even_set.begin(), int_even_set.end());
|
||||
if(!CheckEqualContainers(&int_set4, &fset))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
template<class VoidAllocator>
|
||||
struct GetAllocatorSet
|
||||
{
|
||||
template<class ValueType>
|
||||
struct apply
|
||||
{
|
||||
typedef flat_set < ValueType
|
||||
, std::less<ValueType>
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc<ValueType>::type
|
||||
> set_type;
|
||||
|
||||
typedef flat_multiset < ValueType
|
||||
, std::less<ValueType>
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc<ValueType>::type
|
||||
> multiset_type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class VoidAllocator>
|
||||
int test_set_variants()
|
||||
{
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<int>::set_type MySet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::movable_int>::set_type MyMoveSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::movable_and_copyable_int>::set_type MyCopyMoveSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::copyable_int>::set_type MyCopySet;
|
||||
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<int>::multiset_type MyMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::movable_int>::multiset_type MyMoveMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::movable_and_copyable_int>::multiset_type MyCopyMoveMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::copyable_int>::multiset_type MyCopyMultiSet;
|
||||
|
||||
typedef std::set<int> MyStdSet;
|
||||
typedef std::multiset<int> MyStdMultiSet;
|
||||
|
||||
if (0 != test::set_test<
|
||||
MySet
|
||||
,MyStdSet
|
||||
,MyMultiSet
|
||||
,MyStdMultiSet>()){
|
||||
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::set_test<
|
||||
MyMoveSet
|
||||
,MyStdSet
|
||||
,MyMoveMultiSet
|
||||
,MyStdMultiSet>()){
|
||||
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::set_test<
|
||||
MyCopyMoveSet
|
||||
,MyStdSet
|
||||
,MyCopyMoveMultiSet
|
||||
,MyStdMultiSet>()){
|
||||
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::set_test<
|
||||
MyCopySet
|
||||
,MyStdSet
|
||||
,MyCopyMultiSet
|
||||
,MyStdMultiSet>()){
|
||||
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container::test;
|
||||
|
||||
//Allocator argument container
|
||||
{
|
||||
flat_set<int> set_((std::allocator<int>()));
|
||||
flat_multiset<int> multiset_((std::allocator<int>()));
|
||||
}
|
||||
//Now test move semantics
|
||||
{
|
||||
test_move<flat_set<recursive_flat_set> >();
|
||||
test_move<flat_multiset<recursive_flat_multiset> >();
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Ordered insertion test
|
||||
////////////////////////////////////
|
||||
if(!flat_tree_ordered_insertion_test()){
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Testing allocator implementations
|
||||
////////////////////////////////////
|
||||
// std::allocator
|
||||
if(test_set_variants< std::allocator<void> >()){
|
||||
std::cerr << "test_set_variants< std::allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::allocator
|
||||
if(test_set_variants< allocator<void> >()){
|
||||
std::cerr << "test_set_variants< allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::node_allocator
|
||||
if(test_set_variants< node_allocator<void> >()){
|
||||
std::cerr << "test_set_variants< node_allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::adaptive_pool
|
||||
if(test_set_variants< adaptive_pool<void> >()){
|
||||
std::cerr << "test_set_variants< adaptive_pool<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Emplace testing
|
||||
////////////////////////////////////
|
||||
const test::EmplaceOptions SetOptions = (test::EmplaceOptions)(test::EMPLACE_HINT | test::EMPLACE_ASSOC);
|
||||
|
||||
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;
|
||||
|
||||
////////////////////////////////////
|
||||
// Allocator propagation testing
|
||||
////////////////////////////////////
|
||||
if(!boost::container::test::test_propagate_allocator<flat_set_propagate_test_wrapper>())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
@@ -1,640 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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 "propagate_allocator_test.hpp"
|
||||
#include "emplace_test.hpp"
|
||||
#include <vector>
|
||||
#include <boost/container/detail/flat_tree.hpp>
|
||||
|
||||
using namespace boost::container;
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//Explicit instantiation to detect compilation errors
|
||||
|
||||
//flat_map
|
||||
template class flat_map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class flat_map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class flat_map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
//flat_multimap
|
||||
template class flat_multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class flat_multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class flat_multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator
|
||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
//flat_set
|
||||
template class flat_set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
//flat_multiset
|
||||
template class flat_multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
//As flat container iterators are typedefs for vector::[const_]iterator,
|
||||
//no need to explicit instantiate them
|
||||
|
||||
}} //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_multiset_(c.flat_multiset_)
|
||||
{}
|
||||
|
||||
recursive_flat_multiset & operator =(const recursive_flat_multiset &c)
|
||||
{
|
||||
id_ = c.id_;
|
||||
flat_multiset_= c.flat_multiset_;
|
||||
return *this;
|
||||
}
|
||||
int id_;
|
||||
flat_multiset<recursive_flat_multiset> flat_multiset_;
|
||||
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);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
class flat_tree_propagate_test_wrapper
|
||||
: public container_detail::flat_tree<T, T, container_detail::identity<T>, std::less<T>, A>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_tree_propagate_test_wrapper)
|
||||
typedef container_detail::flat_tree<T, T, container_detail::identity<T>, std::less<T>, A> Base;
|
||||
public:
|
||||
flat_tree_propagate_test_wrapper()
|
||||
: Base()
|
||||
{}
|
||||
|
||||
flat_tree_propagate_test_wrapper(const flat_tree_propagate_test_wrapper &x)
|
||||
: Base(x)
|
||||
{}
|
||||
|
||||
flat_tree_propagate_test_wrapper(BOOST_RV_REF(flat_tree_propagate_test_wrapper) x)
|
||||
: Base(boost::move(static_cast<Base&>(x)))
|
||||
{}
|
||||
|
||||
flat_tree_propagate_test_wrapper &operator=(BOOST_COPY_ASSIGN_REF(flat_tree_propagate_test_wrapper) x)
|
||||
{ this->Base::operator=(x); return *this; }
|
||||
|
||||
flat_tree_propagate_test_wrapper &operator=(BOOST_RV_REF(flat_tree_propagate_test_wrapper) x)
|
||||
{ this->Base::operator=(boost::move(static_cast<Base&>(x))); return *this; }
|
||||
|
||||
void swap(flat_tree_propagate_test_wrapper &x)
|
||||
{ this->Base::swap(x); }
|
||||
};
|
||||
|
||||
namespace boost{
|
||||
namespace container {
|
||||
namespace test{
|
||||
|
||||
bool flat_tree_ordered_insertion_test()
|
||||
{
|
||||
using namespace boost::container;
|
||||
const std::size_t NumElements = 100;
|
||||
|
||||
//Ordered insertion multiset
|
||||
{
|
||||
std::multiset<int> int_mset;
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
int_mset.insert(static_cast<int>(i));
|
||||
}
|
||||
//Construction insertion
|
||||
flat_multiset<int> fmset(ordered_range, int_mset.begin(), int_mset.end());
|
||||
if(!CheckEqualContainers(&int_mset, &fmset))
|
||||
return false;
|
||||
//Insertion when empty
|
||||
fmset.clear();
|
||||
fmset.insert(ordered_range, int_mset.begin(), int_mset.end());
|
||||
if(!CheckEqualContainers(&int_mset, &fmset))
|
||||
return false;
|
||||
//Re-insertion
|
||||
fmset.insert(ordered_range, int_mset.begin(), int_mset.end());
|
||||
std::multiset<int> int_mset2(int_mset);
|
||||
int_mset2.insert(int_mset.begin(), int_mset.end());
|
||||
if(!CheckEqualContainers(&int_mset2, &fmset))
|
||||
return false;
|
||||
//Re-re-insertion
|
||||
fmset.insert(ordered_range, int_mset2.begin(), int_mset2.end());
|
||||
std::multiset<int> int_mset4(int_mset2);
|
||||
int_mset4.insert(int_mset2.begin(), int_mset2.end());
|
||||
if(!CheckEqualContainers(&int_mset4, &fmset))
|
||||
return false;
|
||||
//Re-re-insertion of even
|
||||
std::multiset<int> int_even_mset;
|
||||
for(std::size_t i = 0; i < NumElements; i+=2){
|
||||
int_mset.insert(static_cast<int>(i));
|
||||
}
|
||||
fmset.insert(ordered_range, int_even_mset.begin(), int_even_mset.end());
|
||||
int_mset4.insert(int_even_mset.begin(), int_even_mset.end());
|
||||
if(!CheckEqualContainers(&int_mset4, &fmset))
|
||||
return false;
|
||||
}
|
||||
//Ordered insertion multimap
|
||||
{
|
||||
std::multimap<int, int> int_mmap;
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
int_mmap.insert(std::multimap<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
|
||||
}
|
||||
//Construction insertion
|
||||
flat_multimap<int, int> fmmap(ordered_range, int_mmap.begin(), int_mmap.end());
|
||||
if(!CheckEqualContainers(&int_mmap, &fmmap))
|
||||
return false;
|
||||
//Insertion when empty
|
||||
fmmap.clear();
|
||||
fmmap.insert(ordered_range, int_mmap.begin(), int_mmap.end());
|
||||
if(!CheckEqualContainers(&int_mmap, &fmmap))
|
||||
return false;
|
||||
//Re-insertion
|
||||
fmmap.insert(ordered_range, int_mmap.begin(), int_mmap.end());
|
||||
std::multimap<int, int> int_mmap2(int_mmap);
|
||||
int_mmap2.insert(int_mmap.begin(), int_mmap.end());
|
||||
if(!CheckEqualContainers(&int_mmap2, &fmmap))
|
||||
return false;
|
||||
//Re-re-insertion
|
||||
fmmap.insert(ordered_range, int_mmap2.begin(), int_mmap2.end());
|
||||
std::multimap<int, int> int_mmap4(int_mmap2);
|
||||
int_mmap4.insert(int_mmap2.begin(), int_mmap2.end());
|
||||
if(!CheckEqualContainers(&int_mmap4, &fmmap))
|
||||
return false;
|
||||
//Re-re-insertion of even
|
||||
std::multimap<int, int> int_even_mmap;
|
||||
for(std::size_t i = 0; i < NumElements; i+=2){
|
||||
int_mmap.insert(std::multimap<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
|
||||
}
|
||||
fmmap.insert(ordered_range, int_even_mmap.begin(), int_even_mmap.end());
|
||||
int_mmap4.insert(int_even_mmap.begin(), int_even_mmap.end());
|
||||
if(!CheckEqualContainers(&int_mmap4, &fmmap))
|
||||
return false;
|
||||
}
|
||||
|
||||
//Ordered insertion set
|
||||
{
|
||||
std::set<int> int_set;
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
int_set.insert(static_cast<int>(i));
|
||||
}
|
||||
//Construction insertion
|
||||
flat_set<int> fset(ordered_unique_range, int_set.begin(), int_set.end());
|
||||
if(!CheckEqualContainers(&int_set, &fset))
|
||||
return false;
|
||||
//Insertion when empty
|
||||
fset.clear();
|
||||
fset.insert(ordered_unique_range, int_set.begin(), int_set.end());
|
||||
if(!CheckEqualContainers(&int_set, &fset))
|
||||
return false;
|
||||
//Re-insertion
|
||||
fset.insert(ordered_unique_range, int_set.begin(), int_set.end());
|
||||
std::set<int> int_set2(int_set);
|
||||
int_set2.insert(int_set.begin(), int_set.end());
|
||||
if(!CheckEqualContainers(&int_set2, &fset))
|
||||
return false;
|
||||
//Re-re-insertion
|
||||
fset.insert(ordered_unique_range, int_set2.begin(), int_set2.end());
|
||||
std::set<int> int_set4(int_set2);
|
||||
int_set4.insert(int_set2.begin(), int_set2.end());
|
||||
if(!CheckEqualContainers(&int_set4, &fset))
|
||||
return false;
|
||||
//Re-re-insertion of even
|
||||
std::set<int> int_even_set;
|
||||
for(std::size_t i = 0; i < NumElements; i+=2){
|
||||
int_set.insert(static_cast<int>(i));
|
||||
}
|
||||
fset.insert(ordered_unique_range, int_even_set.begin(), int_even_set.end());
|
||||
int_set4.insert(int_even_set.begin(), int_even_set.end());
|
||||
if(!CheckEqualContainers(&int_set4, &fset))
|
||||
return false;
|
||||
}
|
||||
//Ordered insertion map
|
||||
{
|
||||
std::map<int, int> int_map;
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
int_map.insert(std::map<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
|
||||
}
|
||||
//Construction insertion
|
||||
flat_map<int, int> fmap(ordered_unique_range, int_map.begin(), int_map.end());
|
||||
if(!CheckEqualContainers(&int_map, &fmap))
|
||||
return false;
|
||||
//Insertion when empty
|
||||
fmap.clear();
|
||||
fmap.insert(ordered_unique_range, int_map.begin(), int_map.end());
|
||||
if(!CheckEqualContainers(&int_map, &fmap))
|
||||
return false;
|
||||
//Re-insertion
|
||||
fmap.insert(ordered_unique_range, int_map.begin(), int_map.end());
|
||||
std::map<int, int> int_map2(int_map);
|
||||
int_map2.insert(int_map.begin(), int_map.end());
|
||||
if(!CheckEqualContainers(&int_map2, &fmap))
|
||||
return false;
|
||||
//Re-re-insertion
|
||||
fmap.insert(ordered_unique_range, int_map2.begin(), int_map2.end());
|
||||
std::map<int, int> int_map4(int_map2);
|
||||
int_map4.insert(int_map2.begin(), int_map2.end());
|
||||
if(!CheckEqualContainers(&int_map4, &fmap))
|
||||
return false;
|
||||
//Re-re-insertion of even
|
||||
std::map<int, int> int_even_map;
|
||||
for(std::size_t i = 0; i < NumElements; i+=2){
|
||||
int_map.insert(std::map<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
|
||||
}
|
||||
fmap.insert(ordered_unique_range, int_even_map.begin(), int_even_map.end());
|
||||
int_map4.insert(int_even_map.begin(), int_even_map.end());
|
||||
if(!CheckEqualContainers(&int_map4, &fmap))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container::test;
|
||||
|
||||
//Allocator argument container
|
||||
{
|
||||
flat_set<int> set_((std::allocator<int>()));
|
||||
flat_multiset<int> multiset_((std::allocator<int>()));
|
||||
flat_map<int, int> map_((std::allocator<std::pair<int, int> >()));
|
||||
flat_multimap<int, int> multimap_((std::allocator<std::pair<int, int> >()));
|
||||
}
|
||||
//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(!flat_tree_ordered_insertion_test()){
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
if(!boost::container::test::test_propagate_allocator<flat_tree_propagate_test_wrapper>())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_HEAP_ALLOCATOR_V1_HPP
|
||||
#define BOOST_CONTAINER_HEAP_ALLOCATOR_V1_HPP
|
||||
|
||||
#if (defined _MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/intrusive/pointer_traits.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>
|
||||
|
||||
//!\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)
|
||||
{ boost::container::boost::container::swap_dispatch(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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2012-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2012-2013. 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)
|
||||
//
|
||||
|
||||
+88
-20
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. 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)
|
||||
//
|
||||
@@ -10,6 +10,10 @@
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/list.hpp>
|
||||
#include <boost/container/allocator.hpp>
|
||||
#include <boost/container/node_allocator.hpp>
|
||||
#include <boost/container/adaptive_pool.hpp>
|
||||
|
||||
#include "dummy_test_allocator.hpp"
|
||||
#include <memory>
|
||||
#include "movable_int.hpp"
|
||||
@@ -23,14 +27,29 @@ namespace boost {
|
||||
namespace container {
|
||||
|
||||
//Explicit instantiation to detect compilation errors
|
||||
template class boost::container::list<test::movable_and_copyable_int,
|
||||
test::simple_allocator<test::movable_and_copyable_int> >;
|
||||
template class boost::container::list
|
||||
< test::movable_and_copyable_int
|
||||
, test::simple_allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::list<test::movable_and_copyable_int,
|
||||
test::dummy_test_allocator<test::movable_and_copyable_int> >;
|
||||
template class boost::container::list
|
||||
< test::movable_and_copyable_int
|
||||
, test::dummy_test_allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::list<test::movable_and_copyable_int,
|
||||
std::allocator<test::movable_and_copyable_int> >;
|
||||
template class boost::container::list
|
||||
< test::movable_and_copyable_int
|
||||
, std::allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::list
|
||||
< test::movable_and_copyable_int
|
||||
, allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::list
|
||||
< test::movable_and_copyable_int
|
||||
, adaptive_pool<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::list
|
||||
< test::movable_and_copyable_int
|
||||
, node_allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
@@ -43,12 +62,6 @@ template class iterator
|
||||
|
||||
}}
|
||||
|
||||
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:
|
||||
@@ -67,6 +80,42 @@ void recursive_list_test()//Test for recursive types
|
||||
}
|
||||
}
|
||||
|
||||
template<class VoidAllocator>
|
||||
struct GetAllocatorCont
|
||||
{
|
||||
template<class ValueType>
|
||||
struct apply
|
||||
{
|
||||
typedef list< ValueType
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc<ValueType>::type
|
||||
> type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class VoidAllocator>
|
||||
int test_cont_variants()
|
||||
{
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<int>::type MyCont;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_int>::type MyMoveCont;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_and_copyable_int>::type MyCopyMoveCont;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::copyable_int>::type MyCopyCont;
|
||||
|
||||
if(test::list_test<MyCont, true>())
|
||||
return 1;
|
||||
if(test::list_test<MyMoveCont, true>())
|
||||
return 1;
|
||||
if(test::list_test<MyCopyMoveCont, true>())
|
||||
return 1;
|
||||
if(test::list_test<MyCopyMoveCont, true>())
|
||||
return 1;
|
||||
if(test::list_test<MyCopyCont, true>())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main ()
|
||||
{
|
||||
recursive_list_test();
|
||||
@@ -78,23 +127,42 @@ int main ()
|
||||
move_assign = boost::move(move_ctor);
|
||||
move_assign.swap(original);
|
||||
}
|
||||
if(test::list_test<MyList, true>())
|
||||
return 1;
|
||||
|
||||
if(test::list_test<MyMoveList, true>())
|
||||
////////////////////////////////////
|
||||
// Testing allocator implementations
|
||||
////////////////////////////////////
|
||||
// std:allocator
|
||||
if(test_cont_variants< std::allocator<void> >()){
|
||||
std::cerr << "test_cont_variants< std::allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
|
||||
if(test::list_test<MyCopyMoveList, true>())
|
||||
}
|
||||
// boost::container::allocator
|
||||
if(test_cont_variants< allocator<void> >()){
|
||||
std::cerr << "test_cont_variants< allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
|
||||
if(test::list_test<MyCopyList, true>())
|
||||
}
|
||||
// boost::container::node_allocator
|
||||
if(test_cont_variants< node_allocator<void> >()){
|
||||
std::cerr << "test_cont_variants< node_allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::adaptive_pool
|
||||
if(test_cont_variants< adaptive_pool<void> >()){
|
||||
std::cerr << "test_cont_variants< adaptive_pool<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Emplace testing
|
||||
////////////////////////////////////
|
||||
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;
|
||||
|
||||
////////////////////////////////////
|
||||
// Allocator propagation testing
|
||||
////////////////////////////////////
|
||||
if(!boost::container::test::test_propagate_allocator<list>())
|
||||
return 1;
|
||||
|
||||
|
||||
@@ -0,0 +1,459 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. 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/map.hpp>
|
||||
#include <boost/container/allocator.hpp>
|
||||
#include <boost/container/node_allocator.hpp>
|
||||
#include <boost/container/adaptive_pool.hpp>
|
||||
|
||||
#include "print_container.hpp"
|
||||
#include "movable_int.hpp"
|
||||
#include "dummy_test_allocator.hpp"
|
||||
#include "map_test.hpp"
|
||||
#include "propagate_allocator_test.hpp"
|
||||
#include "emplace_test.hpp"
|
||||
|
||||
using namespace boost::container;
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//Explicit instantiation to detect compilation errors
|
||||
|
||||
//map
|
||||
template class map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
|
||||
template class map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, node_allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
//multimap
|
||||
template class multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, node_allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
template class tree
|
||||
< const test::movable_and_copyable_int
|
||||
, std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int>
|
||||
, container_detail::select1st< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
, tree_assoc_defaults >;
|
||||
|
||||
template class tree
|
||||
< const test::movable_and_copyable_int
|
||||
, std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int>
|
||||
, container_detail::select1st< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
, tree_assoc_defaults >;
|
||||
|
||||
template class tree
|
||||
< const test::movable_and_copyable_int
|
||||
, std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int>
|
||||
, container_detail::select1st< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
, tree_assoc_defaults >;
|
||||
|
||||
template class tree
|
||||
< const test::movable_and_copyable_int
|
||||
, std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int>
|
||||
, container_detail::select1st< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
, tree_assoc_defaults >;
|
||||
|
||||
template class tree
|
||||
< const test::movable_and_copyable_int
|
||||
, std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int>
|
||||
, container_detail::select1st< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
, tree_assoc_defaults >;
|
||||
|
||||
template class tree
|
||||
< const test::movable_and_copyable_int
|
||||
, std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int>
|
||||
, container_detail::select1st< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, node_allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
, tree_assoc_defaults >;
|
||||
|
||||
} //container_detail {
|
||||
|
||||
}} //boost::container
|
||||
|
||||
class recursive_map
|
||||
{
|
||||
public:
|
||||
recursive_map & operator=(const recursive_map &x)
|
||||
{ id_ = x.id_; map_ = x.map_; return *this; }
|
||||
|
||||
int id_;
|
||||
map<recursive_map, recursive_map> map_;
|
||||
friend bool operator< (const recursive_map &a, const recursive_map &b)
|
||||
{ return a.id_ < b.id_; }
|
||||
};
|
||||
|
||||
class recursive_multimap
|
||||
{
|
||||
public:
|
||||
recursive_multimap & operator=(const recursive_multimap &x)
|
||||
{ id_ = x.id_; multimap_ = x.multimap_; return *this; }
|
||||
|
||||
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;
|
||||
original.emplace();
|
||||
C move_ctor(boost::move(original));
|
||||
C move_assign;
|
||||
move_assign.emplace();
|
||||
move_assign = boost::move(move_ctor);
|
||||
move_assign.swap(original);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
class map_propagate_test_wrapper
|
||||
: public boost::container::map
|
||||
< T, T, std::less<T>
|
||||
, typename boost::container::allocator_traits<A>::template
|
||||
portable_rebind_alloc< std::pair<const T, T> >::type
|
||||
//tree_assoc_defaults
|
||||
>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(map_propagate_test_wrapper)
|
||||
typedef boost::container::map
|
||||
< T, T, std::less<T>
|
||||
, typename boost::container::allocator_traits<A>::template
|
||||
portable_rebind_alloc< std::pair<const T, T> >::type
|
||||
> Base;
|
||||
public:
|
||||
map_propagate_test_wrapper()
|
||||
: Base()
|
||||
{}
|
||||
|
||||
map_propagate_test_wrapper(const map_propagate_test_wrapper &x)
|
||||
: Base(x)
|
||||
{}
|
||||
|
||||
map_propagate_test_wrapper(BOOST_RV_REF(map_propagate_test_wrapper) x)
|
||||
: Base(boost::move(static_cast<Base&>(x)))
|
||||
{}
|
||||
|
||||
map_propagate_test_wrapper &operator=(BOOST_COPY_ASSIGN_REF(map_propagate_test_wrapper) x)
|
||||
{ this->Base::operator=(x); return *this; }
|
||||
|
||||
map_propagate_test_wrapper &operator=(BOOST_RV_REF(map_propagate_test_wrapper) x)
|
||||
{ this->Base::operator=(boost::move(static_cast<Base&>(x))); return *this; }
|
||||
|
||||
void swap(map_propagate_test_wrapper &x)
|
||||
{ this->Base::swap(x); }
|
||||
};
|
||||
|
||||
|
||||
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value>
|
||||
struct GetAllocatorMap
|
||||
{
|
||||
template<class ValueType>
|
||||
struct apply
|
||||
{
|
||||
typedef map< ValueType
|
||||
, ValueType
|
||||
, std::less<ValueType>
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc< std::pair<const ValueType, ValueType> >::type
|
||||
, typename boost::container::tree_assoc_options
|
||||
< boost::container::tree_type<tree_type_value>
|
||||
>::type
|
||||
> map_type;
|
||||
|
||||
typedef multimap< ValueType
|
||||
, ValueType
|
||||
, std::less<ValueType>
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc< std::pair<const ValueType, ValueType> >::type
|
||||
, typename boost::container::tree_assoc_options
|
||||
< boost::container::tree_type<tree_type_value>
|
||||
>::type
|
||||
> multimap_type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value>
|
||||
int test_map_variants()
|
||||
{
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<int>::map_type MyMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::movable_int>::map_type MyMoveMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::movable_and_copyable_int>::map_type MyCopyMoveMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::copyable_int>::map_type MyCopyMap;
|
||||
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<int>::multimap_type MyMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::movable_int>::multimap_type MyMoveMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::movable_and_copyable_int>::multimap_type MyCopyMoveMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::copyable_int>::multimap_type MyCopyMultiMap;
|
||||
|
||||
typedef std::map<int, int> MyStdMap;
|
||||
typedef std::multimap<int, int> MyStdMultiMap;
|
||||
|
||||
if (0 != test::map_test<
|
||||
MyMap
|
||||
,MyStdMap
|
||||
,MyMultiMap
|
||||
,MyStdMultiMap>()){
|
||||
std::cout << "Error in map_test<MyBoostMap>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::map_test<
|
||||
MyMoveMap
|
||||
,MyStdMap
|
||||
,MyMoveMultiMap
|
||||
,MyStdMultiMap>()){
|
||||
std::cout << "Error in map_test<MyBoostMap>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::map_test<
|
||||
MyCopyMoveMap
|
||||
,MyStdMap
|
||||
,MyCopyMoveMultiMap
|
||||
,MyStdMultiMap>()){
|
||||
std::cout << "Error in map_test<MyBoostMap>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::map_test<
|
||||
MyCopyMap
|
||||
,MyStdMap
|
||||
,MyCopyMultiMap
|
||||
,MyStdMultiMap>()){
|
||||
std::cout << "Error in map_test<MyBoostMap>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
//Recursive container instantiation
|
||||
{
|
||||
map<recursive_map, recursive_map> map_;
|
||||
multimap<recursive_multimap, recursive_multimap> multimap_;
|
||||
}
|
||||
//Allocator argument container
|
||||
{
|
||||
map<int, int> map_((std::allocator<std::pair<const int, int> >()));
|
||||
multimap<int, int> multimap_((std::allocator<std::pair<const int, int> >()));
|
||||
}
|
||||
//Now test move semantics
|
||||
{
|
||||
test_move<map<recursive_map, recursive_map> >();
|
||||
test_move<multimap<recursive_multimap, recursive_multimap> >();
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Testing allocator implementations
|
||||
////////////////////////////////////
|
||||
// std:allocator
|
||||
if(test_map_variants< std::allocator<void>, red_black_tree >()){
|
||||
std::cerr << "test_map_variants< std::allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::allocator
|
||||
if(test_map_variants< allocator<void>, red_black_tree >()){
|
||||
std::cerr << "test_map_variants< allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::node_allocator
|
||||
if(test_map_variants< node_allocator<void>, red_black_tree >()){
|
||||
std::cerr << "test_map_variants< node_allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::adaptive_pool
|
||||
if(test_map_variants< adaptive_pool<void>, red_black_tree >()){
|
||||
std::cerr << "test_map_variants< adaptive_pool<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Tree implementations
|
||||
////////////////////////////////////
|
||||
// AVL
|
||||
if(test_map_variants< std::allocator<void>, avl_tree >()){
|
||||
std::cerr << "test_map_variants< std::allocator<void>, avl_tree > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// SCAPEGOAT TREE
|
||||
if(test_map_variants< std::allocator<void>, scapegoat_tree >()){
|
||||
std::cerr << "test_map_variants< std::allocator<void>, scapegoat_tree > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// SPLAY TREE
|
||||
if(test_map_variants< std::allocator<void>, splay_tree >()){
|
||||
std::cerr << "test_map_variants< std::allocator<void>, splay_tree > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Emplace testing
|
||||
////////////////////////////////////
|
||||
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;
|
||||
|
||||
////////////////////////////////////
|
||||
// Allocator propagation testing
|
||||
////////////////////////////////////
|
||||
if(!boost::container::test::test_propagate_allocator<map_propagate_test_wrapper>())
|
||||
return 1;
|
||||
|
||||
////////////////////////////////////
|
||||
// Test optimize_size option
|
||||
////////////////////////////////////
|
||||
//
|
||||
// map
|
||||
//
|
||||
typedef map< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<red_black_tree> >::type > rbmap_size_optimized_no;
|
||||
typedef map< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<red_black_tree> >::type > rbmap_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(rbmap_size_optimized_yes) < sizeof(rbmap_size_optimized_no));
|
||||
|
||||
typedef map< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<avl_tree> >::type > avlmap_size_optimized_no;
|
||||
typedef map< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<avl_tree> >::type > avlmap_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(avlmap_size_optimized_yes) < sizeof(avlmap_size_optimized_no));
|
||||
//
|
||||
// multimap
|
||||
//
|
||||
typedef multimap< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<red_black_tree> >::type > rbmmap_size_optimized_no;
|
||||
typedef multimap< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<red_black_tree> >::type > rbmmap_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(rbmmap_size_optimized_yes) < sizeof(rbmmap_size_optimized_no));
|
||||
|
||||
typedef multimap< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<avl_tree> >::type > avlmmap_size_optimized_no;
|
||||
typedef multimap< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<avl_tree> >::type > avlmmap_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(avlmmap_size_optimized_yes) < sizeof(avlmmap_size_optimized_no));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
+112
-70
@@ -23,6 +23,13 @@
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <string>
|
||||
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME rebalance
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace test {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
template<class T1, class T2, class T3, class T4>
|
||||
bool operator ==(std::pair<T1, T2> &p1, std::pair<T1, T2> &p2)
|
||||
{
|
||||
@@ -33,11 +40,99 @@ namespace boost{
|
||||
namespace container {
|
||||
namespace test{
|
||||
|
||||
template<class C>
|
||||
void map_test_rebalanceable(C &, boost::container::container_detail::false_type)
|
||||
{}
|
||||
|
||||
template<class C>
|
||||
void map_test_rebalanceable(C &c, boost::container::container_detail::true_type)
|
||||
{
|
||||
c.rebalance();
|
||||
}
|
||||
|
||||
template<class MyBoostMap
|
||||
,class MyStdMap
|
||||
,class MyBoostMultiMap
|
||||
,class MyStdMultiMap>
|
||||
int map_test ()
|
||||
int map_test_copyable(boost::container::container_detail::false_type)
|
||||
{ return 0; }
|
||||
|
||||
template<class MyBoostMap
|
||||
,class MyStdMap
|
||||
,class MyBoostMultiMap
|
||||
,class MyStdMultiMap>
|
||||
int map_test_copyable(boost::container::container_detail::true_type)
|
||||
{
|
||||
typedef typename MyBoostMap::key_type IntType;
|
||||
typedef container_detail::pair<IntType, IntType> IntPairType;
|
||||
typedef typename MyStdMap::value_type StdPairType;
|
||||
|
||||
const int max = 100;
|
||||
|
||||
BOOST_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;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class MyBoostMap
|
||||
,class MyStdMap
|
||||
,class MyBoostMultiMap
|
||||
,class MyStdMultiMap>
|
||||
int map_test()
|
||||
{
|
||||
typedef typename MyBoostMap::key_type IntType;
|
||||
typedef container_detail::pair<IntType, IntType> IntPairType;
|
||||
@@ -423,6 +518,19 @@ int map_test ()
|
||||
return 1;
|
||||
if(!CheckEqualPairContainers(boostmultimap, stdmultimap))
|
||||
return 1;
|
||||
|
||||
map_test_rebalanceable(*boostmap
|
||||
, container_detail::bool_<has_member_function_callable_with_rebalance<MyBoostMap>::value>());
|
||||
if(!CheckEqualContainers(boostmap, stdmap)){
|
||||
std::cout << "Error in boostmap->rebalance()" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
map_test_rebalanceable(*boostmultimap
|
||||
, container_detail::bool_<has_member_function_callable_with_rebalance<MyBoostMultiMap>::value>());
|
||||
if(!CheckEqualContainers(boostmultimap, stdmultimap)){
|
||||
std::cout << "Error in boostmultimap->rebalance()" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
//Compare count with std containers
|
||||
@@ -471,77 +579,11 @@ int map_test ()
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class MyBoostMap
|
||||
,class MyStdMap
|
||||
,class MyBoostMultiMap
|
||||
,class MyStdMultiMap>
|
||||
int map_test_copyable ()
|
||||
{
|
||||
typedef typename MyBoostMap::key_type IntType;
|
||||
typedef container_detail::pair<IntType, IntType> IntPairType;
|
||||
typedef typename MyStdMap::value_type StdPairType;
|
||||
|
||||
const int max = 100;
|
||||
|
||||
BOOST_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(map_test_copyable<MyBoostMap, MyStdMap, MyBoostMultiMap, MyStdMultiMap>
|
||||
(container_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
|
||||
return 1;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. 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)
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. 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)
|
||||
//
|
||||
@@ -20,8 +20,11 @@ namespace boost{
|
||||
namespace container {
|
||||
namespace test{
|
||||
|
||||
struct PrintValues : public std::unary_function<int, void>
|
||||
struct PrintValues
|
||||
{
|
||||
typedef int argument_type;
|
||||
typedef void result_type;
|
||||
|
||||
void operator() (int value) const
|
||||
{
|
||||
std::cout << value << " ";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. 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)
|
||||
//
|
||||
|
||||
@@ -114,9 +114,9 @@ typedef multiset<alloc_int, std::less<alloc_int>, AllocIntAllocator> MultiSet;
|
||||
//[multi]flat_map/set
|
||||
typedef std::pair<alloc_int, alloc_int> FlatMapNode;
|
||||
typedef scoped_allocator_adaptor<SimpleAllocator<FlatMapNode> > FlatMapAllocator;
|
||||
typedef flat_map<alloc_int, alloc_int, std::less<alloc_int>, MapAllocator> FlatMap;
|
||||
typedef flat_map<alloc_int, alloc_int, std::less<alloc_int>, FlatMapAllocator> FlatMap;
|
||||
typedef flat_set<alloc_int, std::less<alloc_int>, AllocIntAllocator> FlatSet;
|
||||
typedef flat_multimap<alloc_int, alloc_int, std::less<alloc_int>, MapAllocator> FlatMultiMap;
|
||||
typedef flat_multimap<alloc_int, alloc_int, std::less<alloc_int>, FlatMapAllocator> FlatMultiMap;
|
||||
typedef flat_multiset<alloc_int, std::less<alloc_int>, AllocIntAllocator> FlatMultiSet;
|
||||
|
||||
//vector, deque, list, slist, stable_vector.
|
||||
|
||||
@@ -0,0 +1,428 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. 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/allocator.hpp>
|
||||
#include <boost/container/node_allocator.hpp>
|
||||
#include <boost/container/adaptive_pool.hpp>
|
||||
|
||||
#include "print_container.hpp"
|
||||
#include "movable_int.hpp"
|
||||
#include "dummy_test_allocator.hpp"
|
||||
#include "set_test.hpp"
|
||||
#include "propagate_allocator_test.hpp"
|
||||
#include "emplace_test.hpp"
|
||||
|
||||
using namespace boost::container;
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//Explicit instantiation to detect compilation errors
|
||||
|
||||
//set
|
||||
template class set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, node_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
//multiset
|
||||
template class multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, node_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
//Instantiate base class as previous instantiations don't instantiate inherited members
|
||||
template class tree
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator<test::movable_and_copyable_int>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
template class tree
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<test::movable_and_copyable_int>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
template class tree
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<test::movable_and_copyable_int>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
template class tree
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, allocator<test::movable_and_copyable_int>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
template class tree
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool<test::movable_and_copyable_int>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
template class tree
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, node_allocator<test::movable_and_copyable_int>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
} //container_detail {
|
||||
|
||||
}} //boost::container
|
||||
|
||||
//Test recursive structures
|
||||
class recursive_set
|
||||
{
|
||||
public:
|
||||
recursive_set & operator=(const recursive_set &x)
|
||||
{ id_ = x.id_; set_ = x.set_; return *this; }
|
||||
|
||||
int id_;
|
||||
set<recursive_set> set_;
|
||||
friend bool operator< (const recursive_set &a, const recursive_set &b)
|
||||
{ return a.id_ < b.id_; }
|
||||
};
|
||||
|
||||
//Test recursive structures
|
||||
class recursive_multiset
|
||||
{
|
||||
public:
|
||||
recursive_multiset & operator=(const recursive_multiset &x)
|
||||
{ id_ = x.id_; multiset_ = x.multiset_; return *this; }
|
||||
|
||||
int id_;
|
||||
multiset<recursive_multiset> multiset_;
|
||||
friend bool operator< (const recursive_multiset &a, const recursive_multiset &b)
|
||||
{ return a.id_ < b.id_; }
|
||||
};
|
||||
|
||||
template<class C>
|
||||
void test_move()
|
||||
{
|
||||
//Now test move semantics
|
||||
C original;
|
||||
original.emplace();
|
||||
C move_ctor(boost::move(original));
|
||||
C move_assign;
|
||||
move_assign.emplace();
|
||||
move_assign = boost::move(move_ctor);
|
||||
move_assign.swap(original);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
class set_propagate_test_wrapper
|
||||
: public boost::container::set<T, std::less<T>, A
|
||||
//tree_assoc_defaults
|
||||
>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(set_propagate_test_wrapper)
|
||||
typedef boost::container::set<T, std::less<T>, A > Base;
|
||||
public:
|
||||
set_propagate_test_wrapper()
|
||||
: Base()
|
||||
{}
|
||||
|
||||
set_propagate_test_wrapper(const set_propagate_test_wrapper &x)
|
||||
: Base(x)
|
||||
{}
|
||||
|
||||
set_propagate_test_wrapper(BOOST_RV_REF(set_propagate_test_wrapper) x)
|
||||
: Base(boost::move(static_cast<Base&>(x)))
|
||||
{}
|
||||
|
||||
set_propagate_test_wrapper &operator=(BOOST_COPY_ASSIGN_REF(set_propagate_test_wrapper) x)
|
||||
{ this->Base::operator=(x); return *this; }
|
||||
|
||||
set_propagate_test_wrapper &operator=(BOOST_RV_REF(set_propagate_test_wrapper) x)
|
||||
{ this->Base::operator=(boost::move(static_cast<Base&>(x))); return *this; }
|
||||
|
||||
void swap(set_propagate_test_wrapper &x)
|
||||
{ this->Base::swap(x); }
|
||||
};
|
||||
|
||||
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value>
|
||||
struct GetAllocatorSet
|
||||
{
|
||||
template<class ValueType>
|
||||
struct apply
|
||||
{
|
||||
typedef set < ValueType
|
||||
, std::less<ValueType>
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc<ValueType>::type
|
||||
, typename boost::container::tree_assoc_options
|
||||
< boost::container::tree_type<tree_type_value>
|
||||
>::type
|
||||
> set_type;
|
||||
|
||||
typedef multiset < ValueType
|
||||
, std::less<ValueType>
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc<ValueType>::type
|
||||
, typename boost::container::tree_assoc_options
|
||||
< boost::container::tree_type<tree_type_value>
|
||||
>::type
|
||||
> multiset_type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value>
|
||||
int test_set_variants()
|
||||
{
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<int>::set_type MySet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::movable_int>::set_type MyMoveSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::movable_and_copyable_int>::set_type MyCopyMoveSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::copyable_int>::set_type MyCopySet;
|
||||
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<int>::multiset_type MyMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::movable_int>::multiset_type MyMoveMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::movable_and_copyable_int>::multiset_type MyCopyMoveMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::copyable_int>::multiset_type MyCopyMultiSet;
|
||||
|
||||
typedef std::set<int> MyStdSet;
|
||||
typedef std::multiset<int> MyStdMultiSet;
|
||||
|
||||
if (0 != test::set_test<
|
||||
MySet
|
||||
,MyStdSet
|
||||
,MyMultiSet
|
||||
,MyStdMultiSet>()){
|
||||
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::set_test<
|
||||
MyMoveSet
|
||||
,MyStdSet
|
||||
,MyMoveMultiSet
|
||||
,MyStdMultiSet>()){
|
||||
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::set_test<
|
||||
MyCopyMoveSet
|
||||
,MyStdSet
|
||||
,MyCopyMoveMultiSet
|
||||
,MyStdMultiSet>()){
|
||||
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::set_test<
|
||||
MyCopySet
|
||||
,MyStdSet
|
||||
,MyCopyMultiSet
|
||||
,MyStdMultiSet>()){
|
||||
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main ()
|
||||
{
|
||||
//Recursive container instantiation
|
||||
{
|
||||
set<recursive_set> set_;
|
||||
multiset<recursive_multiset> multiset_;
|
||||
}
|
||||
//Allocator argument container
|
||||
{
|
||||
set<int> set_((std::allocator<int>()));
|
||||
multiset<int> multiset_((std::allocator<int>()));
|
||||
}
|
||||
//Now test move semantics
|
||||
{
|
||||
test_move<set<recursive_set> >();
|
||||
test_move<multiset<recursive_multiset> >();
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Testing allocator implementations
|
||||
////////////////////////////////////
|
||||
// std:allocator
|
||||
if(test_set_variants< std::allocator<void>, red_black_tree >()){
|
||||
std::cerr << "test_set_variants< std::allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::allocator
|
||||
if(test_set_variants< allocator<void>, red_black_tree>()){
|
||||
std::cerr << "test_set_variants< allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::node_allocator
|
||||
if(test_set_variants< node_allocator<void>, red_black_tree>()){
|
||||
std::cerr << "test_set_variants< node_allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// boost::container::adaptive_pool
|
||||
if(test_set_variants< adaptive_pool<void>, red_black_tree>()){
|
||||
std::cerr << "test_set_variants< adaptive_pool<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Tree implementations
|
||||
////////////////////////////////////
|
||||
// AVL
|
||||
if(test_set_variants< std::allocator<void>, avl_tree >()){
|
||||
std::cerr << "test_set_variants< std::allocator<void>, avl_tree > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// SCAPEGOAT TREE
|
||||
if(test_set_variants< std::allocator<void>, scapegoat_tree >()){
|
||||
std::cerr << "test_set_variants< std::allocator<void>, scapegoat_tree > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// SPLAY TREE
|
||||
if(test_set_variants< std::allocator<void>, splay_tree >()){
|
||||
std::cerr << "test_set_variants< std::allocator<void>, splay_tree > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Emplace testing
|
||||
////////////////////////////////////
|
||||
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;
|
||||
|
||||
////////////////////////////////////
|
||||
// Allocator propagation testing
|
||||
////////////////////////////////////
|
||||
if(!boost::container::test::test_propagate_allocator<set_propagate_test_wrapper>())
|
||||
return 1;
|
||||
|
||||
////////////////////////////////////
|
||||
// Test optimize_size option
|
||||
////////////////////////////////////
|
||||
//
|
||||
// set
|
||||
//
|
||||
typedef set< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<red_black_tree> >::type > rbset_size_optimized_no;
|
||||
typedef set< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<red_black_tree> >::type > rbset_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(rbset_size_optimized_yes) < sizeof(rbset_size_optimized_no));
|
||||
|
||||
typedef set< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<avl_tree> >::type > avlset_size_optimized_no;
|
||||
typedef set< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<avl_tree> >::type > avlset_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(avlset_size_optimized_yes) < sizeof(avlset_size_optimized_no));
|
||||
//
|
||||
// multiset
|
||||
//
|
||||
typedef multiset< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<red_black_tree> >::type > rbmset_size_optimized_no;
|
||||
typedef multiset< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<red_black_tree> >::type > rbmset_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(rbmset_size_optimized_yes) < sizeof(rbmset_size_optimized_no));
|
||||
|
||||
typedef multiset< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<avl_tree> >::type > avlmset_size_optimized_no;
|
||||
typedef multiset< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<avl_tree> >::type > avlmset_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(avlmset_size_optimized_yes) < sizeof(avlmset_size_optimized_no));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
+230
-99
@@ -1,6 +1,6 @@
|
||||
////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. 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)
|
||||
//
|
||||
@@ -21,10 +21,99 @@
|
||||
#include <boost/move/iterator.hpp>
|
||||
#include <string>
|
||||
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME rebalance
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace test {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
|
||||
namespace boost{
|
||||
namespace container {
|
||||
namespace test{
|
||||
|
||||
template<class C>
|
||||
void set_test_rebalanceable(C &, boost::container::container_detail::false_type)
|
||||
{}
|
||||
|
||||
template<class C>
|
||||
void set_test_rebalanceable(C &c, boost::container::container_detail::true_type)
|
||||
{
|
||||
c.rebalance();
|
||||
}
|
||||
|
||||
template<class MyBoostSet
|
||||
,class MyStdSet
|
||||
,class MyBoostMultiSet
|
||||
,class MyStdMultiSet>
|
||||
int set_test_copyable(boost::container::container_detail::false_type)
|
||||
{ return 0; }
|
||||
|
||||
template<class MyBoostSet
|
||||
,class MyStdSet
|
||||
,class MyBoostMultiSet
|
||||
,class MyStdMultiSet>
|
||||
int set_test_copyable(boost::container::container_detail::true_type)
|
||||
{
|
||||
typedef typename MyBoostSet::value_type IntType;
|
||||
const int max = 100;
|
||||
|
||||
BOOST_TRY{
|
||||
MyBoostSet *boostset = new MyBoostSet;
|
||||
MyStdSet *stdset = new MyStdSet;
|
||||
MyBoostMultiSet *boostmultiset = new MyBoostMultiSet;
|
||||
MyStdMultiSet *stdmultiset = new MyStdMultiSet;
|
||||
|
||||
for(int 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;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
template<class MyBoostSet
|
||||
,class MyStdSet
|
||||
,class MyBoostMultiSet
|
||||
@@ -34,8 +123,6 @@ 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;
|
||||
@@ -354,42 +441,54 @@ int set_test ()
|
||||
}
|
||||
}
|
||||
{
|
||||
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->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);
|
||||
IntType move_me2(i);
|
||||
boostset->insert(boostset->lower_bound(move_me), boost::move(move_me2));
|
||||
stdset->insert(stdset->lower_bound(i), i);
|
||||
//PrintContainers(boostset, stdset);
|
||||
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;
|
||||
}
|
||||
IntType move_me(i);
|
||||
IntType move_me2(i);
|
||||
boostset->insert(boostset->lower_bound(move_me), boost::move(move_me2));
|
||||
stdset->insert(stdset->lower_bound(i), i);
|
||||
//PrintContainers(boostset, stdset);
|
||||
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;
|
||||
}
|
||||
set_test_rebalanceable(*boostset
|
||||
, container_detail::bool_<has_member_function_callable_with_rebalance<MyBoostSet>::value>());
|
||||
if(!CheckEqualContainers(boostset, stdset)){
|
||||
std::cout << "Error in boostset->rebalance()" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
set_test_rebalanceable(*boostmultiset
|
||||
, container_detail::bool_<has_member_function_callable_with_rebalance<MyBoostMultiSet>::value>());
|
||||
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
|
||||
std::cout << "Error in boostmultiset->rebalance()" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,6 +503,97 @@ int set_test ()
|
||||
}
|
||||
}
|
||||
|
||||
//Compare find/lower_bound/upper_bound in set
|
||||
{
|
||||
typename MyBoostSet::iterator bs_b = boostset->begin();
|
||||
typename MyBoostSet::iterator bs_e = boostset->end();
|
||||
typename MyStdSet::iterator ss_b = stdset->begin();
|
||||
|
||||
std::size_t i = 0;
|
||||
while(bs_b != bs_e){
|
||||
++i;
|
||||
typename MyBoostSet::iterator bs_i;
|
||||
typename MyStdSet::iterator ss_i;
|
||||
//find
|
||||
bs_i = boostset->find(*bs_b);
|
||||
ss_i = stdset->find(*ss_b);
|
||||
if(!CheckEqualIt(bs_i, ss_i, *boostset, *stdset)){
|
||||
return -1;
|
||||
}
|
||||
//lower bound
|
||||
bs_i = boostset->lower_bound(*bs_b);
|
||||
ss_i = stdset->lower_bound(*ss_b);
|
||||
if(!CheckEqualIt(bs_i, ss_i, *boostset, *stdset)){
|
||||
return -1;
|
||||
}
|
||||
//upper bound
|
||||
bs_i = boostset->upper_bound(*bs_b);
|
||||
ss_i = stdset->upper_bound(*ss_b);
|
||||
if(!CheckEqualIt(bs_i, ss_i, *boostset, *stdset)){
|
||||
return -1;
|
||||
}
|
||||
//equal range
|
||||
std::pair<typename MyBoostSet::iterator
|
||||
,typename MyBoostSet::iterator> bs_ip;
|
||||
std::pair<typename MyStdSet::iterator
|
||||
,typename MyStdSet::iterator> ss_ip;
|
||||
bs_ip = boostset->equal_range(*bs_b);
|
||||
ss_ip = stdset->equal_range(*ss_b);
|
||||
if(!CheckEqualIt(bs_ip.first, ss_ip.first, *boostset, *stdset)){
|
||||
return -1;
|
||||
}
|
||||
if(!CheckEqualIt(bs_ip.second, ss_ip.second, *boostset, *stdset)){
|
||||
return -1;
|
||||
}
|
||||
++bs_b;
|
||||
++ss_b;
|
||||
}
|
||||
}
|
||||
//Compare find/lower_bound/upper_bound in multiset
|
||||
{
|
||||
typename MyBoostMultiSet::iterator bm_b = boostmultiset->begin();
|
||||
typename MyBoostMultiSet::iterator bm_e = boostmultiset->end();
|
||||
typename MyStdMultiSet::iterator sm_b = stdmultiset->begin();
|
||||
|
||||
while(bm_b != bm_e){
|
||||
typename MyBoostMultiSet::iterator bm_i;
|
||||
typename MyStdMultiSet::iterator sm_i;
|
||||
//find
|
||||
bm_i = boostmultiset->find(*bm_b);
|
||||
sm_i = stdmultiset->find(*sm_b);
|
||||
if(!CheckEqualIt(bm_i, sm_i, *boostmultiset, *stdmultiset)){
|
||||
return -1;
|
||||
}
|
||||
//lower bound
|
||||
bm_i = boostmultiset->lower_bound(*bm_b);
|
||||
sm_i = stdmultiset->lower_bound(*sm_b);
|
||||
if(!CheckEqualIt(bm_i, sm_i, *boostmultiset, *stdmultiset)){
|
||||
return -1;
|
||||
}
|
||||
//upper bound
|
||||
bm_i = boostmultiset->upper_bound(*bm_b);
|
||||
sm_i = stdmultiset->upper_bound(*sm_b);
|
||||
if(!CheckEqualIt(bm_i, sm_i, *boostmultiset, *stdmultiset)){
|
||||
return -1;
|
||||
}
|
||||
//equal range
|
||||
std::pair<typename MyBoostMultiSet::iterator
|
||||
,typename MyBoostMultiSet::iterator> bm_ip;
|
||||
std::pair<typename MyStdMultiSet::iterator
|
||||
,typename MyStdMultiSet::iterator> sm_ip;
|
||||
bm_ip = boostmultiset->equal_range(*bm_b);
|
||||
sm_ip = stdmultiset->equal_range(*sm_b);
|
||||
if(!CheckEqualIt(bm_ip.first, sm_ip.first, *boostmultiset, *stdmultiset)){
|
||||
return -1;
|
||||
}
|
||||
if(!CheckEqualIt(bm_ip.second, sm_ip.second, *boostmultiset, *stdmultiset)){
|
||||
return -1;
|
||||
}
|
||||
++bm_b;
|
||||
++sm_b;
|
||||
}
|
||||
}
|
||||
|
||||
//Now do count exercise
|
||||
boostset->erase(boostset->begin(), boostset->end());
|
||||
boostmultiset->erase(boostmultiset->begin(), boostmultiset->end());
|
||||
@@ -431,71 +621,12 @@ int set_test ()
|
||||
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;
|
||||
|
||||
BOOST_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;
|
||||
|
||||
for(int 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;
|
||||
if(set_test_copyable<MyBoostSet, MyStdSet, MyBoostMultiSet, MyStdMultiSet>
|
||||
(container_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
|
||||
return 1;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+87
-20
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. 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)
|
||||
//
|
||||
@@ -9,6 +9,10 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/slist.hpp>
|
||||
#include <boost/container/allocator.hpp>
|
||||
#include <boost/container/node_allocator.hpp>
|
||||
#include <boost/container/adaptive_pool.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include "dummy_test_allocator.hpp"
|
||||
#include "movable_int.hpp"
|
||||
@@ -22,22 +26,32 @@ namespace boost {
|
||||
namespace container {
|
||||
|
||||
//Explicit instantiation to detect compilation errors
|
||||
template class boost::container::slist<test::movable_and_copyable_int,
|
||||
test::simple_allocator<test::movable_and_copyable_int> >;
|
||||
template class boost::container::slist
|
||||
< test::movable_and_copyable_int
|
||||
, test::simple_allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::slist<test::movable_and_copyable_int,
|
||||
test::dummy_test_allocator<test::movable_and_copyable_int> >;
|
||||
template class boost::container::slist
|
||||
< test::movable_and_copyable_int
|
||||
, test::dummy_test_allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::slist<test::movable_and_copyable_int,
|
||||
std::allocator<test::movable_and_copyable_int> >;
|
||||
template class boost::container::slist
|
||||
< test::movable_and_copyable_int
|
||||
, std::allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::slist
|
||||
< test::movable_and_copyable_int
|
||||
, allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::slist
|
||||
< test::movable_and_copyable_int
|
||||
, adaptive_pool<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::slist
|
||||
< test::movable_and_copyable_int
|
||||
, node_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:
|
||||
@@ -52,6 +66,42 @@ void recursive_slist_test()//Test for recursive types
|
||||
slist<recursive_slist> recursive_list_list;
|
||||
}
|
||||
|
||||
template<class VoidAllocator>
|
||||
struct GetAllocatorCont
|
||||
{
|
||||
template<class ValueType>
|
||||
struct apply
|
||||
{
|
||||
typedef slist< ValueType
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc<ValueType>::type
|
||||
> type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class VoidAllocator>
|
||||
int test_cont_variants()
|
||||
{
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<int>::type MyCont;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_int>::type MyMoveCont;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_and_copyable_int>::type MyCopyMoveCont;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::copyable_int>::type MyCopyCont;
|
||||
|
||||
if(test::list_test<MyCont, false>())
|
||||
return 1;
|
||||
if(test::list_test<MyMoveCont, false>())
|
||||
return 1;
|
||||
if(test::list_test<MyCopyMoveCont, false>())
|
||||
return 1;
|
||||
if(test::list_test<MyCopyMoveCont, false>())
|
||||
return 1;
|
||||
if(test::list_test<MyCopyCont, false>())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main ()
|
||||
{
|
||||
recursive_slist_test();
|
||||
@@ -70,19 +120,33 @@ int main ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(test::list_test<MyList, false>())
|
||||
////////////////////////////////////
|
||||
// Testing allocator implementations
|
||||
////////////////////////////////////
|
||||
// std:allocator
|
||||
if(test_cont_variants< std::allocator<void> >()){
|
||||
std::cerr << "test_cont_variants< std::allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
|
||||
if(test::list_test<MyMoveList, false>())
|
||||
}
|
||||
// boost::container::allocator
|
||||
if(test_cont_variants< allocator<void> >()){
|
||||
std::cerr << "test_cont_variants< allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
|
||||
if(test::list_test<MyCopyMoveList, false>())
|
||||
}
|
||||
// boost::container::node_allocator
|
||||
if(test_cont_variants< node_allocator<void> >()){
|
||||
std::cerr << "test_cont_variants< node_allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
|
||||
if(test::list_test<MyCopyList, false>())
|
||||
}
|
||||
// boost::container::adaptive_pool
|
||||
if(test_cont_variants< adaptive_pool<void> >()){
|
||||
std::cerr << "test_cont_variants< adaptive_pool<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Emplace testing
|
||||
////////////////////////////////////
|
||||
const test::EmplaceOptions Options = (test::EmplaceOptions)
|
||||
(test::EMPLACE_FRONT | test::EMPLACE_AFTER | test::EMPLACE_BEFORE | test::EMPLACE_AFTER);
|
||||
|
||||
@@ -90,6 +154,9 @@ int main ()
|
||||
< slist<test::EmplaceInt>, Options>())
|
||||
return 1;
|
||||
|
||||
////////////////////////////////////
|
||||
// Allocator propagation testing
|
||||
////////////////////////////////////
|
||||
if(!boost::container::test::test_propagate_allocator<slist>())
|
||||
return 1;
|
||||
}
|
||||
|
||||
+75
-38
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. 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)
|
||||
//
|
||||
@@ -16,6 +16,10 @@
|
||||
#include <functional>
|
||||
|
||||
#include <boost/container/stable_vector.hpp>
|
||||
#include <boost/container/allocator.hpp>
|
||||
#include <boost/container/node_allocator.hpp>
|
||||
#include <boost/container/adaptive_pool.hpp>
|
||||
|
||||
#include "check_equal_containers.hpp"
|
||||
#include "movable_int.hpp"
|
||||
#include "expand_bwd_test_allocator.hpp"
|
||||
@@ -23,6 +27,7 @@
|
||||
#include "dummy_test_allocator.hpp"
|
||||
#include "propagate_allocator_test.hpp"
|
||||
#include "vector_test.hpp"
|
||||
#include "default_init_test.hpp"
|
||||
|
||||
using namespace boost::container;
|
||||
|
||||
@@ -39,6 +44,18 @@ template class stable_vector<test::movable_and_copyable_int,
|
||||
template class stable_vector<test::movable_and_copyable_int,
|
||||
std::allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class stable_vector
|
||||
< test::movable_and_copyable_int
|
||||
, allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class stable_vector
|
||||
< test::movable_and_copyable_int
|
||||
, adaptive_pool<test::movable_and_copyable_int> >;
|
||||
|
||||
template class stable_vector
|
||||
< test::movable_and_copyable_int
|
||||
, node_allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
namespace stable_vector_detail{
|
||||
|
||||
template class iterator<int*, false>;
|
||||
@@ -66,34 +83,37 @@ void recursive_vector_test()//Test for recursive types
|
||||
}
|
||||
}
|
||||
|
||||
bool default_init_test()//Test for default initialization
|
||||
template<class VoidAllocator>
|
||||
struct GetAllocatorCont
|
||||
{
|
||||
typedef stable_vector<int, test::default_init_allocator<int> > svector_t;
|
||||
|
||||
const std::size_t Capacity = 100;
|
||||
|
||||
template<class ValueType>
|
||||
struct apply
|
||||
{
|
||||
test::default_init_allocator<int>::reset_pattern(0);
|
||||
svector_t v(Capacity, default_init);
|
||||
svector_t::iterator it = v.begin();
|
||||
//Compare with the pattern
|
||||
for(std::size_t i = 0; i != Capacity; ++i, ++it){
|
||||
if(*it != static_cast<int>(i))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
{
|
||||
test::default_init_allocator<int>::reset_pattern(100);
|
||||
svector_t v;
|
||||
v.resize(Capacity, default_init);
|
||||
svector_t::iterator it = v.begin();
|
||||
//Compare with the pattern
|
||||
for(std::size_t i = 0; i != Capacity; ++i, ++it){
|
||||
if(*it != static_cast<int>(i+100))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
typedef stable_vector< ValueType
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc<ValueType>::type
|
||||
> type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class VoidAllocator>
|
||||
int test_cont_variants()
|
||||
{
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<int>::type MyCont;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_int>::type MyMoveCont;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_and_copyable_int>::type MyCopyMoveCont;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::copyable_int>::type MyCopyCont;
|
||||
|
||||
if(test::vector_test<MyCont>())
|
||||
return 1;
|
||||
if(test::vector_test<MyMoveCont>())
|
||||
return 1;
|
||||
if(test::vector_test<MyCopyMoveCont>())
|
||||
return 1;
|
||||
if(test::vector_test<MyCopyCont>())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
@@ -115,33 +135,50 @@ int main()
|
||||
sv.resize(10);
|
||||
sv.resize(1);
|
||||
}
|
||||
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>())
|
||||
////////////////////////////////////
|
||||
// Testing allocator implementations
|
||||
////////////////////////////////////
|
||||
// std:allocator
|
||||
if(test_cont_variants< std::allocator<void> >()){
|
||||
std::cerr << "test_cont_variants< std::allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
|
||||
if(test::vector_test<MyMoveVector>())
|
||||
}
|
||||
// boost::container::allocator
|
||||
if(test_cont_variants< allocator<void> >()){
|
||||
std::cerr << "test_cont_variants< allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
|
||||
if(test::vector_test<MyCopyMoveVector>())
|
||||
}
|
||||
// boost::container::node_allocator
|
||||
if(test_cont_variants< node_allocator<void> >()){
|
||||
std::cerr << "test_cont_variants< node_allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
|
||||
if(test::vector_test<MyCopyVector>())
|
||||
}
|
||||
// boost::container::adaptive_pool
|
||||
if(test_cont_variants< adaptive_pool<void> >()){
|
||||
std::cerr << "test_cont_variants< adaptive_pool<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Default init test
|
||||
////////////////////////////////////
|
||||
if(!test::default_init_test< stable_vector<int, test::default_init_allocator<int> > >()){
|
||||
std::cerr << "Default init test failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Emplace testing
|
||||
////////////////////////////////////
|
||||
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;
|
||||
|
||||
////////////////////////////////////
|
||||
// Allocator propagation testing
|
||||
////////////////////////////////////
|
||||
if(!boost::container::test::test_propagate_allocator<stable_vector>())
|
||||
return 1;
|
||||
|
||||
|
||||
+21
-2
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. 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)
|
||||
//
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "expand_bwd_test_allocator.hpp"
|
||||
#include "expand_bwd_test_template.hpp"
|
||||
#include "propagate_allocator_test.hpp"
|
||||
#include "default_init_test.hpp"
|
||||
|
||||
using namespace boost::container;
|
||||
|
||||
@@ -137,7 +138,6 @@ int string_test()
|
||||
|
||||
const int MaxSize = 100;
|
||||
|
||||
//Create shared memory
|
||||
{
|
||||
BoostStringVector *boostStringVect = new BoostStringVector;
|
||||
StdStringVector *stdStringVect = new StdStringVector;
|
||||
@@ -471,12 +471,31 @@ int main()
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Backwards expansion test
|
||||
////////////////////////////////////
|
||||
if(!test_expand_bwd())
|
||||
return 1;
|
||||
|
||||
////////////////////////////////////
|
||||
// Allocator propagation testing
|
||||
////////////////////////////////////
|
||||
if(!boost::container::test::test_propagate_allocator<string_propagate_test_wrapper>())
|
||||
return 1;
|
||||
|
||||
////////////////////////////////////
|
||||
// Default init test
|
||||
////////////////////////////////////
|
||||
if(!test::default_init_test< basic_string<char, std::char_traits<char>, test::default_init_allocator<char> > >()){
|
||||
std::cerr << "Default init test failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!test::default_init_test< basic_string<wchar_t, std::char_traits<wchar_t>, test::default_init_allocator<wchar_t> > >()){
|
||||
std::cerr << "Default init test failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,380 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#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 "propagate_allocator_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;
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//Explicit instantiation to detect compilation errors
|
||||
|
||||
//map
|
||||
template class map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
//multimap
|
||||
template class multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
template class multimap
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator
|
||||
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
||||
>;
|
||||
|
||||
//set
|
||||
template class set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
//multiset
|
||||
template class multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::dummy_test_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class multiset
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
}} //boost::container
|
||||
|
||||
//Test recursive structures
|
||||
class recursive_set
|
||||
{
|
||||
public:
|
||||
recursive_set & operator=(const recursive_set &x)
|
||||
{ id_ = x.id_; set_ = x.set_; return *this; }
|
||||
|
||||
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:
|
||||
recursive_map & operator=(const recursive_map &x)
|
||||
{ id_ = x.id_; map_ = x.map_; return *this; }
|
||||
|
||||
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:
|
||||
recursive_multiset & operator=(const recursive_multiset &x)
|
||||
{ id_ = x.id_; multiset_ = x.multiset_; return *this; }
|
||||
|
||||
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:
|
||||
recursive_multimap & operator=(const recursive_multimap &x)
|
||||
{ id_ = x.id_; multimap_ = x.multimap_; return *this; }
|
||||
|
||||
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;
|
||||
original.emplace();
|
||||
C move_ctor(boost::move(original));
|
||||
C move_assign;
|
||||
move_assign.emplace();
|
||||
move_assign = boost::move(move_ctor);
|
||||
move_assign.swap(original);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
class tree_propagate_test_wrapper
|
||||
: public container_detail::rbtree<T, T, container_detail::identity<T>, std::less<T>, A>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(tree_propagate_test_wrapper)
|
||||
typedef container_detail::rbtree<T, T, container_detail::identity<T>, std::less<T>, A> Base;
|
||||
public:
|
||||
tree_propagate_test_wrapper()
|
||||
: Base()
|
||||
{}
|
||||
|
||||
tree_propagate_test_wrapper(const tree_propagate_test_wrapper &x)
|
||||
: Base(x)
|
||||
{}
|
||||
|
||||
tree_propagate_test_wrapper(BOOST_RV_REF(tree_propagate_test_wrapper) x)
|
||||
: Base(boost::move(static_cast<Base&>(x)))
|
||||
{}
|
||||
|
||||
tree_propagate_test_wrapper &operator=(BOOST_COPY_ASSIGN_REF(tree_propagate_test_wrapper) x)
|
||||
{ this->Base::operator=(x); return *this; }
|
||||
|
||||
tree_propagate_test_wrapper &operator=(BOOST_RV_REF(tree_propagate_test_wrapper) x)
|
||||
{ this->Base::operator=(boost::move(static_cast<Base&>(x))); return *this; }
|
||||
|
||||
void swap(tree_propagate_test_wrapper &x)
|
||||
{ this->Base::swap(x); }
|
||||
};
|
||||
|
||||
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_;
|
||||
}
|
||||
//Allocator argument container
|
||||
{
|
||||
set<int> set_((std::allocator<int>()));
|
||||
multiset<int> multiset_((std::allocator<int>()));
|
||||
map<int, int> map_((std::allocator<std::pair<const int, int> >()));
|
||||
multimap<int, int> multimap_((std::allocator<std::pair<const int, int> >()));
|
||||
}
|
||||
//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> >();
|
||||
}
|
||||
|
||||
|
||||
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<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;
|
||||
if(!boost::container::test::test_propagate_allocator<tree_propagate_test_wrapper>())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
+102
-22
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. 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)
|
||||
//
|
||||
@@ -15,6 +15,10 @@
|
||||
#include <functional>
|
||||
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/container/allocator.hpp>
|
||||
#include <boost/container/node_allocator.hpp>
|
||||
#include <boost/container/adaptive_pool.hpp>
|
||||
|
||||
#include <boost/move/utility.hpp>
|
||||
#include "check_equal_containers.hpp"
|
||||
#include "movable_int.hpp"
|
||||
@@ -23,6 +27,7 @@
|
||||
#include "dummy_test_allocator.hpp"
|
||||
#include "propagate_allocator_test.hpp"
|
||||
#include "vector_test.hpp"
|
||||
#include "default_init_test.hpp"
|
||||
|
||||
using namespace boost::container;
|
||||
|
||||
@@ -30,14 +35,29 @@ namespace boost {
|
||||
namespace container {
|
||||
|
||||
//Explicit instantiation to detect compilation errors
|
||||
template class boost::container::vector<test::movable_and_copyable_int,
|
||||
test::simple_allocator<test::movable_and_copyable_int> >;
|
||||
template class boost::container::vector
|
||||
< test::movable_and_copyable_int
|
||||
, test::simple_allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::vector<test::movable_and_copyable_int,
|
||||
test::dummy_test_allocator<test::movable_and_copyable_int> >;
|
||||
template class boost::container::vector
|
||||
< test::movable_and_copyable_int
|
||||
, test::dummy_test_allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::vector<test::movable_and_copyable_int,
|
||||
std::allocator<test::movable_and_copyable_int> >;
|
||||
template class boost::container::vector
|
||||
< test::movable_and_copyable_int
|
||||
, std::allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::vector
|
||||
< test::movable_and_copyable_int
|
||||
, allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::vector
|
||||
< test::movable_and_copyable_int
|
||||
, adaptive_pool<test::movable_and_copyable_int> >;
|
||||
|
||||
template class boost::container::vector
|
||||
< test::movable_and_copyable_int
|
||||
, node_allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
@@ -104,6 +124,39 @@ enum Test
|
||||
zero, one, two, three, four, five, six
|
||||
};
|
||||
|
||||
template<class VoidAllocator>
|
||||
struct GetAllocatorCont
|
||||
{
|
||||
template<class ValueType>
|
||||
struct apply
|
||||
{
|
||||
typedef vector< ValueType
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc<ValueType>::type
|
||||
> type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class VoidAllocator>
|
||||
int test_cont_variants()
|
||||
{
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<int>::type MyCont;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_int>::type MyMoveCont;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_and_copyable_int>::type MyCopyMoveCont;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::copyable_int>::type MyCopyCont;
|
||||
|
||||
if(test::vector_test<MyCont>())
|
||||
return 1;
|
||||
if(test::vector_test<MyMoveCont>())
|
||||
return 1;
|
||||
if(test::vector_test<MyCopyMoveCont>())
|
||||
return 1;
|
||||
if(test::vector_test<MyCopyCont>())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
@@ -135,38 +188,65 @@ int main()
|
||||
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>())
|
||||
////////////////////////////////////
|
||||
// Testing allocator implementations
|
||||
////////////////////////////////////
|
||||
// std:allocator
|
||||
if(test_cont_variants< std::allocator<void> >()){
|
||||
std::cerr << "test_cont_variants< std::allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
if(test::vector_test<MyMoveVector>())
|
||||
}
|
||||
// boost::container::allocator
|
||||
if(test_cont_variants< allocator<void> >()){
|
||||
std::cerr << "test_cont_variants< allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
if(test::vector_test<MyCopyMoveVector>())
|
||||
}
|
||||
// boost::container::node_allocator
|
||||
if(test_cont_variants< node_allocator<void> >()){
|
||||
std::cerr << "test_cont_variants< node_allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
if(test::vector_test<MyCopyVector>())
|
||||
}
|
||||
// boost::container::adaptive_pool
|
||||
if(test_cont_variants< adaptive_pool<void> >()){
|
||||
std::cerr << "test_cont_variants< adaptive_pool<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
{
|
||||
typedef vector<Test, std::allocator<Test> > MyEnumCont;
|
||||
MyEnumCont v;
|
||||
Test t;
|
||||
v.push_back(t);
|
||||
v.push_back(::boost::move(t));
|
||||
v.push_back(Test());
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Backwards expansion test
|
||||
////////////////////////////////////
|
||||
if(test_expand_bwd())
|
||||
return 1;
|
||||
|
||||
////////////////////////////////////
|
||||
// Default init test
|
||||
////////////////////////////////////
|
||||
if(!test::default_init_test< vector<int, test::default_init_allocator<int> > >()){
|
||||
std::cerr << "Default init test failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
MyEnumVector v;
|
||||
Test t;
|
||||
v.push_back(t);
|
||||
v.push_back(::boost::move(t));
|
||||
v.push_back(Test());
|
||||
|
||||
////////////////////////////////////
|
||||
// Emplace testing
|
||||
////////////////////////////////////
|
||||
const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE);
|
||||
if(!boost::container::test::test_emplace< vector<test::EmplaceInt>, Options>()){
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Allocator propagation testing
|
||||
////////////////////////////////////
|
||||
if(!boost::container::test::test_propagate_allocator<vector>()){
|
||||
return 1;
|
||||
}
|
||||
|
||||
+1
-118
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. 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)
|
||||
//
|
||||
@@ -38,123 +38,6 @@ namespace boost{
|
||||
namespace container {
|
||||
namespace test{
|
||||
|
||||
//
|
||||
template<int Dummy = 0>
|
||||
class default_init_allocator_base
|
||||
{
|
||||
protected:
|
||||
static unsigned char s_pattern;
|
||||
static bool s_ascending;
|
||||
|
||||
public:
|
||||
static void reset_pattern(unsigned char value)
|
||||
{ s_pattern = value; }
|
||||
|
||||
static void set_ascending(bool enable)
|
||||
{ s_ascending = enable; }
|
||||
};
|
||||
|
||||
template<int Dummy>
|
||||
unsigned char default_init_allocator_base<Dummy>::s_pattern = 0u;
|
||||
|
||||
template<int Dummy>
|
||||
bool default_init_allocator_base<Dummy>::s_ascending = true;
|
||||
|
||||
template<class T>
|
||||
class default_init_allocator
|
||||
: public default_init_allocator_base<0>
|
||||
{
|
||||
typedef default_init_allocator_base<0> base_t;
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
default_init_allocator()
|
||||
{}
|
||||
|
||||
template <class U>
|
||||
default_init_allocator(default_init_allocator<U>)
|
||||
{}
|
||||
|
||||
T* allocate(std::size_t n)
|
||||
{
|
||||
//Initialize memory to a pattern
|
||||
T *const p = ::new T[n];
|
||||
unsigned char *puc_raw = reinterpret_cast<unsigned char*>(p);
|
||||
std::size_t max = sizeof(T)*n;
|
||||
if(base_t::s_ascending){
|
||||
for(std::size_t i = 0; i != max; ++i){
|
||||
puc_raw[i] = static_cast<unsigned char>(s_pattern++);
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(std::size_t i = 0; i != max; ++i){
|
||||
puc_raw[i] = static_cast<unsigned char>(s_pattern--);
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void deallocate(T *p, std::size_t)
|
||||
{ delete[] p; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline bool check_ascending_byte_pattern(const T&t)
|
||||
{
|
||||
const unsigned char *pch = &reinterpret_cast<const unsigned char &>(t);
|
||||
const std::size_t max = sizeof(T);
|
||||
for(std::size_t i = 1; i != max; ++i){
|
||||
if( (pch[i-1] != ((unsigned char)(pch[i]-1u))) ){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool check_descending_byte_pattern(const T&t)
|
||||
{
|
||||
const unsigned char *pch = &reinterpret_cast<const unsigned char &>(t);
|
||||
const std::size_t max = sizeof(T);
|
||||
for(std::size_t i = 1; i != max; ++i){
|
||||
if( (pch[i-1] != ((unsigned char)(pch[i]+1u))) ){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class IntDefaultInitAllocVector>
|
||||
bool default_init_test()//Test for default initialization
|
||||
{
|
||||
const std::size_t Capacity = 100;
|
||||
|
||||
{
|
||||
test::default_init_allocator<int>::reset_pattern(0);
|
||||
test::default_init_allocator<int>::set_ascending(true);
|
||||
IntDefaultInitAllocVector v(Capacity, default_init);
|
||||
typename IntDefaultInitAllocVector::iterator it = v.begin();
|
||||
//Compare with the pattern
|
||||
for(std::size_t i = 0; i != Capacity; ++i, ++it){
|
||||
if(!test::check_ascending_byte_pattern(*it))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
{
|
||||
test::default_init_allocator<int>::reset_pattern(100);
|
||||
test::default_init_allocator<int>::set_ascending(false);
|
||||
IntDefaultInitAllocVector v;
|
||||
v.resize(Capacity, default_init);
|
||||
typename IntDefaultInitAllocVector::iterator it = v.begin();
|
||||
//Compare with the pattern
|
||||
for(std::size_t i = 0; i != Capacity; ++i, ++it){
|
||||
if(!test::check_descending_byte_pattern(*it))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class V1, class V2>
|
||||
bool vector_copyable_only(V1 *, V2 *, boost::container::container_detail::false_type)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user