forked from boostorg/container
Add Polymorphic Memory Resource utilities and rework the separately compiled library:
- Dlmalloc's based C function are boost_cont_xxx no longer exported, but wrapped into C++ linkage dlmalloc_xxx functions to effectively reuse Boost's dynamic library and autolink machinery instead of rewriting machinery to compile the C source file. - Refactored scoped_allocator_adaptor's construct logic as it was shared with polymorphic allocator's one. Moved common logic to detail/dispatch_uses_allocator.hpp. Refactored also scoped_allocator_adaptor test utilities to be reused with polymorphic_allocator tests.
This commit is contained in:
@@ -11,6 +11,12 @@
|
||||
# Boost Software License, Version 1.0. (See accompanying file
|
||||
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
project
|
||||
: requirements
|
||||
<link>shared:<define>BOOST_CONTAINER_DYN_LINK=1
|
||||
<toolset>gcc-cygwin:<link>static
|
||||
;
|
||||
|
||||
# this rule enumerates through all the sources and invokes
|
||||
# the run rule for each source, the result is a list of all
|
||||
# the run rules, which we can pass on to the test_suite rule:
|
||||
|
||||
+23
-23
@@ -8,7 +8,7 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/container/detail/alloc_lib_auto_link.hpp>
|
||||
#include <boost/container/detail/dlmalloc.hpp>
|
||||
#include <boost/container/allocator.hpp>
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/container/list.hpp>
|
||||
@@ -18,50 +18,50 @@ using namespace boost::container;
|
||||
bool basic_test()
|
||||
{
|
||||
size_t received = 0;
|
||||
if(!boost_cont_all_deallocated())
|
||||
if(!dlmalloc_all_deallocated())
|
||||
return false;
|
||||
void *ptr = boost_cont_alloc(50, 98, &received);
|
||||
if(boost_cont_size(ptr) != received)
|
||||
void *ptr = dlmalloc_alloc(50, 98, &received);
|
||||
if(dlmalloc_size(ptr) != received)
|
||||
return false;
|
||||
if(boost_cont_allocated_memory() != boost_cont_chunksize(ptr))
|
||||
if(dlmalloc_allocated_memory() != dlmalloc_chunksize(ptr))
|
||||
return false;
|
||||
|
||||
if(boost_cont_all_deallocated())
|
||||
if(dlmalloc_all_deallocated())
|
||||
return false;
|
||||
|
||||
boost_cont_grow(ptr, received + 20, received + 30, &received);
|
||||
dlmalloc_grow(ptr, received + 20, received + 30, &received);
|
||||
|
||||
if(boost_cont_allocated_memory() != boost_cont_chunksize(ptr))
|
||||
if(dlmalloc_allocated_memory() != dlmalloc_chunksize(ptr))
|
||||
return false;
|
||||
|
||||
if(boost_cont_size(ptr) != received)
|
||||
if(dlmalloc_size(ptr) != received)
|
||||
return false;
|
||||
|
||||
if(!boost_cont_shrink(ptr, 100, 140, &received, 1))
|
||||
if(!dlmalloc_shrink(ptr, 100, 140, &received, 1))
|
||||
return false;
|
||||
|
||||
if(boost_cont_allocated_memory() != boost_cont_chunksize(ptr))
|
||||
if(dlmalloc_allocated_memory() != dlmalloc_chunksize(ptr))
|
||||
return false;
|
||||
|
||||
if(!boost_cont_shrink(ptr, 0, 140, &received, 1))
|
||||
if(!dlmalloc_shrink(ptr, 0, 140, &received, 1))
|
||||
return false;
|
||||
|
||||
if(boost_cont_allocated_memory() != boost_cont_chunksize(ptr))
|
||||
if(dlmalloc_allocated_memory() != dlmalloc_chunksize(ptr))
|
||||
return false;
|
||||
|
||||
if(boost_cont_shrink(ptr, 0, received/2, &received, 1))
|
||||
if(dlmalloc_shrink(ptr, 0, received/2, &received, 1))
|
||||
return false;
|
||||
|
||||
if(boost_cont_allocated_memory() != boost_cont_chunksize(ptr))
|
||||
if(dlmalloc_allocated_memory() != dlmalloc_chunksize(ptr))
|
||||
return false;
|
||||
|
||||
if(boost_cont_size(ptr) != received)
|
||||
if(dlmalloc_size(ptr) != received)
|
||||
return false;
|
||||
|
||||
boost_cont_free(ptr);
|
||||
dlmalloc_free(ptr);
|
||||
|
||||
boost_cont_malloc_check();
|
||||
if(!boost_cont_all_deallocated())
|
||||
dlmalloc_malloc_check();
|
||||
if(!dlmalloc_all_deallocated())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -69,7 +69,7 @@ bool basic_test()
|
||||
bool vector_test()
|
||||
{
|
||||
typedef boost::container::vector<int, allocator<int> > Vector;
|
||||
if(!boost_cont_all_deallocated())
|
||||
if(!dlmalloc_all_deallocated())
|
||||
return false;
|
||||
{
|
||||
const int NumElem = 1000;
|
||||
@@ -86,7 +86,7 @@ bool vector_test()
|
||||
new_buf = &v[0];
|
||||
}
|
||||
}
|
||||
if(!boost_cont_all_deallocated())
|
||||
if(!dlmalloc_all_deallocated())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -94,7 +94,7 @@ bool vector_test()
|
||||
bool list_test()
|
||||
{
|
||||
typedef boost::container::list<int, allocator<int> > List;
|
||||
if(!boost_cont_all_deallocated())
|
||||
if(!dlmalloc_all_deallocated())
|
||||
return false;
|
||||
{
|
||||
const int NumElem = 1000;
|
||||
@@ -102,7 +102,7 @@ bool list_test()
|
||||
int values[NumElem];
|
||||
l.insert(l.end(), &values[0], &values[NumElem]);
|
||||
}
|
||||
if(!boost_cont_all_deallocated())
|
||||
if(!dlmalloc_all_deallocated())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
+91
-91
@@ -17,7 +17,7 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <algorithm> //std::remove
|
||||
#include <boost/container/detail/alloc_lib_auto_link.hpp>
|
||||
#include <boost/container/detail/dlmalloc.hpp>
|
||||
|
||||
namespace boost { namespace container { namespace test {
|
||||
|
||||
@@ -30,9 +30,9 @@ enum deallocation_type { DirectDeallocation, InverseDeallocation, MixedDeallocat
|
||||
|
||||
bool test_allocation()
|
||||
{
|
||||
if(!boost_cont_all_deallocated())
|
||||
if(!dlmalloc_all_deallocated())
|
||||
return false;
|
||||
boost_cont_malloc_check();
|
||||
dlmalloc_malloc_check();
|
||||
for( deallocation_type t = DirectDeallocation
|
||||
; t != EndDeallocationType
|
||||
; t = (deallocation_type)((int)t + 1)){
|
||||
@@ -40,7 +40,7 @@ bool test_allocation()
|
||||
//std::size_t free_memory = a.get_free_memory();
|
||||
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
void *ptr = boost_cont_malloc(i);
|
||||
void *ptr = dlmalloc_malloc(i);
|
||||
if(!ptr)
|
||||
break;
|
||||
buffers.push_back(ptr);
|
||||
@@ -52,7 +52,7 @@ bool test_allocation()
|
||||
for(int j = 0, max = (int)buffers.size()
|
||||
;j < max
|
||||
;++j){
|
||||
boost_cont_free(buffers[j]);
|
||||
dlmalloc_free(buffers[j]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -61,7 +61,7 @@ bool test_allocation()
|
||||
for(int j = (int)buffers.size()
|
||||
;j--
|
||||
;){
|
||||
boost_cont_free(buffers[j]);
|
||||
dlmalloc_free(buffers[j]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -71,7 +71,7 @@ bool test_allocation()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers.size())/4;
|
||||
boost_cont_free(buffers[pos]);
|
||||
dlmalloc_free(buffers[pos]);
|
||||
buffers.erase(buffers.begin()+pos);
|
||||
}
|
||||
}
|
||||
@@ -79,14 +79,14 @@ bool test_allocation()
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(!boost_cont_all_deallocated())
|
||||
if(!dlmalloc_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();
|
||||
dlmalloc_malloc_check();
|
||||
return 0 != dlmalloc_all_deallocated();
|
||||
}
|
||||
|
||||
//This test allocates until there is no more memory
|
||||
@@ -95,12 +95,12 @@ bool test_allocation()
|
||||
|
||||
bool test_allocation_shrink()
|
||||
{
|
||||
boost_cont_malloc_check();
|
||||
dlmalloc_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);
|
||||
void *ptr = dlmalloc_malloc(i*2);
|
||||
if(!ptr)
|
||||
break;
|
||||
buffers.push_back(ptr);
|
||||
@@ -111,12 +111,12 @@ bool test_allocation_shrink()
|
||||
;i < max
|
||||
; ++i){
|
||||
std::size_t try_received_size = 0;
|
||||
void* try_result = boost_cont_allocation_command
|
||||
void* try_result = dlmalloc_allocation_command
|
||||
( BOOST_CONTAINER_TRY_SHRINK_IN_PLACE, 1, i*2
|
||||
, i, &try_received_size, (char*)buffers[i]).first;
|
||||
|
||||
std::size_t received_size = 0;
|
||||
void* result = boost_cont_allocation_command
|
||||
void* result = dlmalloc_allocation_command
|
||||
( BOOST_CONTAINER_SHRINK_IN_PLACE, 1, i*2
|
||||
, i, &received_size, (char*)buffers[i]).first;
|
||||
|
||||
@@ -141,11 +141,11 @@ bool test_allocation_shrink()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers.size())/4;
|
||||
boost_cont_free(buffers[pos]);
|
||||
dlmalloc_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();
|
||||
dlmalloc_malloc_check();
|
||||
return 0 != dlmalloc_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
|
||||
}
|
||||
|
||||
//This test allocates until there is no more memory
|
||||
@@ -154,12 +154,12 @@ bool test_allocation_shrink()
|
||||
|
||||
bool test_allocation_expand()
|
||||
{
|
||||
boost_cont_malloc_check();
|
||||
dlmalloc_malloc_check();
|
||||
std::vector<void*> buffers;
|
||||
|
||||
//Allocate buffers with extra memory
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
void *ptr = boost_cont_malloc(i);
|
||||
void *ptr = dlmalloc_malloc(i);
|
||||
if(!ptr)
|
||||
break;
|
||||
buffers.push_back(ptr);
|
||||
@@ -173,7 +173,7 @@ bool test_allocation_expand()
|
||||
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
|
||||
while(dlmalloc_allocation_command
|
||||
( BOOST_CONTAINER_EXPAND_FWD, 1, min_size
|
||||
, preferred_size, &received_size, (char*)buffers[i]).first){
|
||||
//Check received size is bigger than minimum
|
||||
@@ -191,11 +191,11 @@ bool test_allocation_expand()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers.size())/4;
|
||||
boost_cont_free(buffers[pos]);
|
||||
dlmalloc_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();
|
||||
dlmalloc_malloc_check();
|
||||
return 0 != dlmalloc_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
|
||||
}
|
||||
|
||||
//This test allocates until there is no more memory
|
||||
@@ -210,10 +210,10 @@ bool test_allocation_shrink_and_expand()
|
||||
//Allocate buffers wand store received sizes
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
std::size_t received_size = 0;
|
||||
void *ptr = boost_cont_allocation_command
|
||||
void *ptr = dlmalloc_allocation_command
|
||||
(BOOST_CONTAINER_ALLOCATE_NEW, 1, i, i*2, &received_size, 0).first;
|
||||
if(!ptr){
|
||||
ptr = boost_cont_allocation_command
|
||||
ptr = dlmalloc_allocation_command
|
||||
( BOOST_CONTAINER_ALLOCATE_NEW, 1, 1, i*2, &received_size, 0).first;
|
||||
if(!ptr)
|
||||
break;
|
||||
@@ -229,7 +229,7 @@ bool test_allocation_shrink_and_expand()
|
||||
std::size_t received_size = 0;
|
||||
bool size_reduced_flag;
|
||||
if(true == (size_reduced_flag = !!
|
||||
boost_cont_allocation_command
|
||||
dlmalloc_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])){
|
||||
@@ -249,7 +249,7 @@ bool test_allocation_shrink_and_expand()
|
||||
if(!size_reduced[i]) continue;
|
||||
std::size_t received_size = 0;
|
||||
std::size_t request_size = received_sizes[i];
|
||||
if(boost_cont_allocation_command
|
||||
if(dlmalloc_allocation_command
|
||||
( BOOST_CONTAINER_EXPAND_FWD, 1, request_size
|
||||
, request_size, &received_size, (char*)buffers[i]).first){
|
||||
if(received_size != request_size){
|
||||
@@ -266,11 +266,11 @@ bool test_allocation_shrink_and_expand()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers.size())/4;
|
||||
boost_cont_free(buffers[pos]);
|
||||
dlmalloc_free(buffers[pos]);
|
||||
buffers.erase(buffers.begin()+pos);
|
||||
}
|
||||
|
||||
return 0 != boost_cont_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
|
||||
return 0 != dlmalloc_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
|
||||
}
|
||||
|
||||
//This test allocates until there is no more memory
|
||||
@@ -280,12 +280,12 @@ bool test_allocation_shrink_and_expand()
|
||||
|
||||
bool test_allocation_deallocation_expand()
|
||||
{
|
||||
boost_cont_malloc_check();
|
||||
dlmalloc_malloc_check();
|
||||
std::vector<void*> buffers;
|
||||
|
||||
//Allocate buffers with extra memory
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
void *ptr = boost_cont_malloc(i);
|
||||
void *ptr = dlmalloc_malloc(i);
|
||||
if(!ptr)
|
||||
break;
|
||||
buffers.push_back(ptr);
|
||||
@@ -297,7 +297,7 @@ bool test_allocation_deallocation_expand()
|
||||
;i < max
|
||||
;++i){
|
||||
if(i%2){
|
||||
boost_cont_free(buffers[i]);
|
||||
dlmalloc_free(buffers[i]);
|
||||
buffers[i] = 0;
|
||||
}
|
||||
}
|
||||
@@ -313,7 +313,7 @@ bool test_allocation_deallocation_expand()
|
||||
std::size_t preferred_size = i*2;
|
||||
preferred_size = min_size > preferred_size ? min_size : preferred_size;
|
||||
|
||||
while(boost_cont_allocation_command
|
||||
while(dlmalloc_allocation_command
|
||||
( BOOST_CONTAINER_EXPAND_FWD, 1, min_size
|
||||
, preferred_size, &received_size, (char*)buffers[i]).first){
|
||||
//Check received size is bigger than minimum
|
||||
@@ -336,11 +336,11 @@ bool test_allocation_deallocation_expand()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers.size())/4;
|
||||
boost_cont_free(buffers[pos]);
|
||||
dlmalloc_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();
|
||||
dlmalloc_malloc_check();
|
||||
return 0 != dlmalloc_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
|
||||
}
|
||||
|
||||
//This test allocates until there is no more memory
|
||||
@@ -352,14 +352,14 @@ bool test_allocation_deallocation_expand()
|
||||
|
||||
bool test_allocation_with_reuse()
|
||||
{
|
||||
boost_cont_malloc_check();
|
||||
dlmalloc_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);
|
||||
void *ptr = dlmalloc_malloc(i*sizeof_object);
|
||||
if(!ptr)
|
||||
break;
|
||||
buffers.push_back(ptr);
|
||||
@@ -370,7 +370,7 @@ bool test_allocation_with_reuse()
|
||||
for(int i = 0, max = (int)buffers.size() - 1
|
||||
;i < max
|
||||
;++i){
|
||||
boost_cont_free(buffers[i]);
|
||||
dlmalloc_free(buffers[i]);
|
||||
}
|
||||
|
||||
//Save the unique buffer and clear vector
|
||||
@@ -382,7 +382,7 @@ bool test_allocation_with_reuse()
|
||||
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
|
||||
dlmalloc_command_ret_t ret = dlmalloc_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
|
||||
@@ -396,9 +396,9 @@ bool test_allocation_with_reuse()
|
||||
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())
|
||||
dlmalloc_free(ptr);
|
||||
dlmalloc_malloc_check();
|
||||
if(!dlmalloc_all_deallocated())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -410,26 +410,26 @@ bool test_allocation_with_reuse()
|
||||
|
||||
bool test_aligned_allocation()
|
||||
{
|
||||
boost_cont_malloc_check();
|
||||
dlmalloc_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);
|
||||
void *ptr = dlmalloc_memalign(i-1, j);
|
||||
if(!ptr){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(((std::size_t)ptr & (j - 1)) != 0)
|
||||
return false;
|
||||
boost_cont_free(ptr);
|
||||
dlmalloc_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();
|
||||
dlmalloc_malloc_check();
|
||||
return 0 != dlmalloc_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
|
||||
}
|
||||
|
||||
//This test allocates memory with different alignments
|
||||
@@ -437,7 +437,7 @@ bool test_aligned_allocation()
|
||||
|
||||
bool test_continuous_aligned_allocation()
|
||||
{
|
||||
boost_cont_malloc_check();
|
||||
dlmalloc_malloc_check();
|
||||
std::vector<void*> buffers;
|
||||
//Allocate aligned buffers in a loop
|
||||
//and then deallocate it
|
||||
@@ -447,7 +447,7 @@ bool test_continuous_aligned_allocation()
|
||||
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);
|
||||
void *ptr = dlmalloc_memalign(i-1, j);
|
||||
buffers.push_back(ptr);
|
||||
if(!ptr){
|
||||
continue_loop = false;
|
||||
@@ -459,7 +459,7 @@ bool test_continuous_aligned_allocation()
|
||||
}
|
||||
//Deallocate all
|
||||
for(int k = (int)buffers.size(); k--;){
|
||||
boost_cont_free(buffers[k]);
|
||||
dlmalloc_free(buffers[k]);
|
||||
}
|
||||
buffers.clear();
|
||||
//if(!a.all_memory_deallocated() && a.check_sanity())
|
||||
@@ -468,15 +468,15 @@ bool test_continuous_aligned_allocation()
|
||||
break;
|
||||
}
|
||||
}
|
||||
boost_cont_malloc_check();
|
||||
return 0 != boost_cont_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
|
||||
dlmalloc_malloc_check();
|
||||
return 0 != dlmalloc_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();
|
||||
dlmalloc_malloc_check();
|
||||
for( deallocation_type t = DirectDeallocation
|
||||
; t != EndDeallocationType
|
||||
; t = (deallocation_type)((int)t + 1)){
|
||||
@@ -486,7 +486,7 @@ bool test_many_equal_allocation()
|
||||
|
||||
//Allocate buffers with extra memory
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
void *ptr = boost_cont_malloc(i);
|
||||
void *ptr = dlmalloc_malloc(i);
|
||||
if(!ptr)
|
||||
break;
|
||||
//if(!a.check_sanity())
|
||||
@@ -500,7 +500,7 @@ bool test_many_equal_allocation()
|
||||
;i < max
|
||||
;++i){
|
||||
if(i%2){
|
||||
boost_cont_free(buffers2[i]);
|
||||
dlmalloc_free(buffers2[i]);
|
||||
buffers2[i] = 0;
|
||||
}
|
||||
}
|
||||
@@ -510,10 +510,10 @@ bool test_many_equal_allocation()
|
||||
|
||||
std::vector<void*> buffers;
|
||||
for(int i = 0; i != NumIt/10; ++i){
|
||||
boost_cont_memchain chain;
|
||||
dlmalloc_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);
|
||||
dlmalloc_multialloc_nodes((i+1)*2, i+1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
|
||||
dlmalloc_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
|
||||
if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
|
||||
break;
|
||||
|
||||
@@ -535,7 +535,7 @@ bool test_many_equal_allocation()
|
||||
for(int j = 0, max = (int)buffers.size()
|
||||
;j < max
|
||||
;++j){
|
||||
boost_cont_free(buffers[j]);
|
||||
dlmalloc_free(buffers[j]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -544,7 +544,7 @@ bool test_many_equal_allocation()
|
||||
for(int j = (int)buffers.size()
|
||||
;j--
|
||||
;){
|
||||
boost_cont_free(buffers[j]);
|
||||
dlmalloc_free(buffers[j]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -554,7 +554,7 @@ bool test_many_equal_allocation()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers.size())/4;
|
||||
boost_cont_free(buffers[pos]);
|
||||
dlmalloc_free(buffers[pos]);
|
||||
buffers.erase(buffers.begin()+pos);
|
||||
}
|
||||
}
|
||||
@@ -570,7 +570,7 @@ bool test_many_equal_allocation()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers2.size())/4;
|
||||
boost_cont_free(buffers2[pos]);
|
||||
dlmalloc_free(buffers2[pos]);
|
||||
buffers2.erase(buffers2.begin()+pos);
|
||||
}
|
||||
|
||||
@@ -578,8 +578,8 @@ bool test_many_equal_allocation()
|
||||
//a.all_memory_deallocated() && a.check_sanity();
|
||||
//if(!ok) return ok;
|
||||
}
|
||||
boost_cont_malloc_check();
|
||||
return 0 != boost_cont_all_deallocated();
|
||||
dlmalloc_malloc_check();
|
||||
return 0 != dlmalloc_all_deallocated();
|
||||
}
|
||||
|
||||
//This test allocates multiple values until there is no more memory
|
||||
@@ -587,7 +587,7 @@ bool test_many_equal_allocation()
|
||||
|
||||
bool test_many_different_allocation()
|
||||
{
|
||||
boost_cont_malloc_check();
|
||||
dlmalloc_malloc_check();
|
||||
const std::size_t ArraySize = 11;
|
||||
std::size_t requested_sizes[ArraySize];
|
||||
for(std::size_t i = 0; i < ArraySize; ++i){
|
||||
@@ -603,7 +603,7 @@ bool test_many_different_allocation()
|
||||
|
||||
//Allocate buffers with extra memory
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
void *ptr = boost_cont_malloc(i);
|
||||
void *ptr = dlmalloc_malloc(i);
|
||||
if(!ptr)
|
||||
break;
|
||||
buffers2.push_back(ptr);
|
||||
@@ -615,17 +615,17 @@ bool test_many_different_allocation()
|
||||
;i < max
|
||||
;++i){
|
||||
if(i%2){
|
||||
boost_cont_free(buffers2[i]);
|
||||
dlmalloc_free(buffers2[i]);
|
||||
buffers2[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<void*> buffers;
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
boost_cont_memchain chain;
|
||||
dlmalloc_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);
|
||||
dlmalloc_multialloc_arrays(ArraySize, requested_sizes, 1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
|
||||
dlmalloc_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
|
||||
if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
|
||||
break;
|
||||
std::size_t n = 0;
|
||||
@@ -643,7 +643,7 @@ bool test_many_different_allocation()
|
||||
for(int j = 0, max = (int)buffers.size()
|
||||
;j < max
|
||||
;++j){
|
||||
boost_cont_free(buffers[j]);
|
||||
dlmalloc_free(buffers[j]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -652,7 +652,7 @@ bool test_many_different_allocation()
|
||||
for(int j = (int)buffers.size()
|
||||
;j--
|
||||
;){
|
||||
boost_cont_free(buffers[j]);
|
||||
dlmalloc_free(buffers[j]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -662,7 +662,7 @@ bool test_many_different_allocation()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers.size())/4;
|
||||
boost_cont_free(buffers[pos]);
|
||||
dlmalloc_free(buffers[pos]);
|
||||
buffers.erase(buffers.begin()+pos);
|
||||
}
|
||||
}
|
||||
@@ -678,7 +678,7 @@ bool test_many_different_allocation()
|
||||
;j < max
|
||||
;++j){
|
||||
int pos = (j%4)*((int)buffers2.size())/4;
|
||||
boost_cont_free(buffers2[pos]);
|
||||
dlmalloc_free(buffers2[pos]);
|
||||
buffers2.erase(buffers2.begin()+pos);
|
||||
}
|
||||
|
||||
@@ -686,53 +686,53 @@ bool test_many_different_allocation()
|
||||
//a.all_memory_deallocated() && a.check_sanity();
|
||||
//if(!ok) return ok;
|
||||
}
|
||||
boost_cont_malloc_check();
|
||||
return 0 != boost_cont_all_deallocated();
|
||||
dlmalloc_malloc_check();
|
||||
return 0 != dlmalloc_all_deallocated();
|
||||
}
|
||||
|
||||
bool test_many_deallocation()
|
||||
{
|
||||
const std::size_t ArraySize = 11;
|
||||
std::vector<boost_cont_memchain> buffers;
|
||||
std::vector<dlmalloc_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;
|
||||
dlmalloc_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);
|
||||
dlmalloc_multialloc_arrays(ArraySize, requested_sizes, 1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
|
||||
dlmalloc_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]);
|
||||
dlmalloc_multidealloc(&buffers[i]);
|
||||
}
|
||||
buffers.clear();
|
||||
|
||||
boost_cont_malloc_check();
|
||||
if(!boost_cont_all_deallocated())
|
||||
dlmalloc_malloc_check();
|
||||
if(!dlmalloc_all_deallocated())
|
||||
return false;
|
||||
|
||||
for(int i = 0; i != NumIt; ++i){
|
||||
boost_cont_memchain chain;
|
||||
dlmalloc_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);
|
||||
dlmalloc_multialloc_nodes(ArraySize, i*4+1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
|
||||
dlmalloc_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]);
|
||||
dlmalloc_multidealloc(&buffers[i]);
|
||||
}
|
||||
buffers.clear();
|
||||
|
||||
boost_cont_malloc_check();
|
||||
if(!boost_cont_all_deallocated())
|
||||
dlmalloc_malloc_check();
|
||||
if(!dlmalloc_all_deallocated())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -835,7 +835,7 @@ bool test_all_allocation()
|
||||
return false;
|
||||
}
|
||||
|
||||
return 0 != boost_cont_all_deallocated();
|
||||
return 0 != dlmalloc_all_deallocated();
|
||||
}
|
||||
|
||||
}}} //namespace boost { namespace container { namespace test {
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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_ALLOCATOR_ARGUMENT_TESTER_HPP
|
||||
#define BOOST_CONTAINER_TEST_ALLOCATOR_ARGUMENT_TESTER_HPP
|
||||
|
||||
#include <boost/container/uses_allocator.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
|
||||
template<class T, unsigned int Id, bool HasTrueTypes = false>
|
||||
class propagation_test_allocator
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(propagation_test_allocator)
|
||||
public:
|
||||
|
||||
template<class U>
|
||||
struct rebind
|
||||
{
|
||||
typedef propagation_test_allocator<U, Id, HasTrueTypes> other;
|
||||
};
|
||||
|
||||
typedef boost::container::container_detail::bool_<HasTrueTypes> propagate_on_container_copy_assignment;
|
||||
typedef boost::container::container_detail::bool_<HasTrueTypes> propagate_on_container_move_assignment;
|
||||
typedef boost::container::container_detail::bool_<HasTrueTypes> propagate_on_container_swap;
|
||||
typedef boost::container::container_detail::bool_<HasTrueTypes> is_always_equal;
|
||||
typedef T value_type;
|
||||
|
||||
propagation_test_allocator()
|
||||
: m_move_contructed(false), m_move_assigned(false)
|
||||
{}
|
||||
|
||||
propagation_test_allocator(const propagation_test_allocator&)
|
||||
: m_move_contructed(false), m_move_assigned(false)
|
||||
{}
|
||||
|
||||
propagation_test_allocator(BOOST_RV_REF(propagation_test_allocator) )
|
||||
: m_move_contructed(true), m_move_assigned(false)
|
||||
{}
|
||||
|
||||
template<class U>
|
||||
propagation_test_allocator(BOOST_RV_REF_BEG propagation_test_allocator<U, Id, HasTrueTypes> BOOST_RV_REF_END)
|
||||
: m_move_contructed(true), m_move_assigned(false)
|
||||
{}
|
||||
|
||||
template<class U>
|
||||
propagation_test_allocator(const propagation_test_allocator<U, Id, HasTrueTypes> &)
|
||||
{}
|
||||
|
||||
propagation_test_allocator & operator=(BOOST_COPY_ASSIGN_REF(propagation_test_allocator))
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
propagation_test_allocator & operator=(BOOST_RV_REF(propagation_test_allocator))
|
||||
{
|
||||
m_move_assigned = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::size_t max_size() const
|
||||
{ return std::size_t(-1); }
|
||||
|
||||
T* allocate(std::size_t n)
|
||||
{ return (T*)::new char[n*sizeof(T)]; }
|
||||
|
||||
void deallocate(T*p, std::size_t)
|
||||
{ delete []static_cast<char*>(static_cast<void*>(p)); }
|
||||
|
||||
bool m_move_contructed;
|
||||
bool m_move_assigned;
|
||||
};
|
||||
|
||||
template <class T1, class T2, unsigned int Id, bool HasTrueTypes>
|
||||
bool operator==( const propagation_test_allocator<T1, Id, HasTrueTypes>&
|
||||
, const propagation_test_allocator<T2, Id, HasTrueTypes>&)
|
||||
{ return true; }
|
||||
|
||||
template <class T1, class T2, unsigned int Id, bool HasTrueTypes>
|
||||
bool operator!=( const propagation_test_allocator<T1, Id, HasTrueTypes>&
|
||||
, const propagation_test_allocator<T2, Id, HasTrueTypes>&)
|
||||
{ return false; }
|
||||
|
||||
//This enum lists the construction options
|
||||
//for an allocator-aware type
|
||||
enum ConstructionTypeEnum
|
||||
{
|
||||
ConstructiblePrefix,
|
||||
ConstructibleSuffix,
|
||||
NotUsesAllocator
|
||||
};
|
||||
|
||||
//This base class provices types for
|
||||
//the derived class to implement each construction
|
||||
//type. If a construction type does not apply
|
||||
//the typedef is set to an internal nat
|
||||
//so that the class is not constructible from
|
||||
//the user arguments.
|
||||
template<ConstructionTypeEnum ConstructionType, unsigned int AllocatorTag>
|
||||
struct uses_allocator_base;
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct uses_allocator_base<ConstructibleSuffix, AllocatorTag>
|
||||
{
|
||||
typedef propagation_test_allocator<int, AllocatorTag> allocator_type;
|
||||
typedef allocator_type allocator_constructor_type;
|
||||
struct nat{};
|
||||
typedef nat allocator_arg_type;
|
||||
};
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct uses_allocator_base<ConstructiblePrefix, AllocatorTag>
|
||||
{
|
||||
typedef propagation_test_allocator<int, AllocatorTag> allocator_type;
|
||||
typedef allocator_type allocator_constructor_type;
|
||||
typedef boost::container::allocator_arg_t allocator_arg_type;
|
||||
};
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct uses_allocator_base<NotUsesAllocator, AllocatorTag>
|
||||
{
|
||||
struct nat{};
|
||||
typedef nat allocator_constructor_type;
|
||||
typedef nat allocator_arg_type;
|
||||
};
|
||||
|
||||
template<ConstructionTypeEnum ConstructionType, unsigned int AllocatorTag>
|
||||
struct allocator_argument_tester
|
||||
: uses_allocator_base<ConstructionType, AllocatorTag>
|
||||
{
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(allocator_argument_tester)
|
||||
|
||||
public:
|
||||
|
||||
typedef uses_allocator_base<ConstructionType, AllocatorTag> base_type;
|
||||
|
||||
//0 user argument constructors
|
||||
allocator_argument_tester()
|
||||
: construction_type(NotUsesAllocator), value(0)
|
||||
{}
|
||||
|
||||
explicit allocator_argument_tester
|
||||
(typename base_type::allocator_constructor_type)
|
||||
: construction_type(ConstructibleSuffix), value(0)
|
||||
{}
|
||||
|
||||
explicit allocator_argument_tester
|
||||
(typename base_type::allocator_arg_type, typename base_type::allocator_constructor_type)
|
||||
: construction_type(ConstructiblePrefix), value(0)
|
||||
{}
|
||||
|
||||
//1 user argument constructors
|
||||
explicit allocator_argument_tester(int i)
|
||||
: construction_type(NotUsesAllocator), value(i)
|
||||
{}
|
||||
|
||||
allocator_argument_tester
|
||||
(int i, typename base_type::allocator_constructor_type)
|
||||
: construction_type(ConstructibleSuffix), value(i)
|
||||
{}
|
||||
|
||||
allocator_argument_tester
|
||||
( typename base_type::allocator_arg_type
|
||||
, typename base_type::allocator_constructor_type
|
||||
, int i)
|
||||
: construction_type(ConstructiblePrefix), value(i)
|
||||
{}
|
||||
|
||||
//Copy constructors
|
||||
allocator_argument_tester(const allocator_argument_tester &other)
|
||||
: construction_type(NotUsesAllocator), value(other.value)
|
||||
{}
|
||||
|
||||
allocator_argument_tester( const allocator_argument_tester &other
|
||||
, typename base_type::allocator_constructor_type)
|
||||
: construction_type(ConstructibleSuffix), value(other.value)
|
||||
{}
|
||||
|
||||
allocator_argument_tester( typename base_type::allocator_arg_type
|
||||
, typename base_type::allocator_constructor_type
|
||||
, const allocator_argument_tester &other)
|
||||
: construction_type(ConstructiblePrefix), value(other.value)
|
||||
{}
|
||||
|
||||
//Move constructors
|
||||
allocator_argument_tester(BOOST_RV_REF(allocator_argument_tester) other)
|
||||
: construction_type(NotUsesAllocator), value(other.value)
|
||||
{ other.value = 0; other.construction_type = NotUsesAllocator; }
|
||||
|
||||
allocator_argument_tester( BOOST_RV_REF(allocator_argument_tester) other
|
||||
, typename base_type::allocator_constructor_type)
|
||||
: construction_type(ConstructibleSuffix), value(other.value)
|
||||
{ other.value = 0; other.construction_type = ConstructibleSuffix; }
|
||||
|
||||
allocator_argument_tester( typename base_type::allocator_arg_type
|
||||
, typename base_type::allocator_constructor_type
|
||||
, BOOST_RV_REF(allocator_argument_tester) other)
|
||||
: construction_type(ConstructiblePrefix), value(other.value)
|
||||
{ other.value = 0; other.construction_type = ConstructiblePrefix; }
|
||||
|
||||
ConstructionTypeEnum construction_type;
|
||||
int value;
|
||||
};
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct constructible_with_allocator_prefix
|
||||
< ::allocator_argument_tester<ConstructiblePrefix, AllocatorTag> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct constructible_with_allocator_suffix
|
||||
< ::allocator_argument_tester<ConstructibleSuffix, AllocatorTag> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //BOOST_CONTAINER_TEST_ALLOCATOR_ARGUMENT_TESTER_HPP
|
||||
@@ -0,0 +1,87 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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_DERIVED_FROM_MEMORY_RESOURCE_HPP
|
||||
#define BOOST_CONTAINER_TEST_DERIVED_FROM_MEMORY_RESOURCE_HPP
|
||||
|
||||
#include <boost/container/pmr/memory_resource.hpp>
|
||||
|
||||
class derived_from_memory_resource
|
||||
: public boost::container::pmr::memory_resource
|
||||
{
|
||||
public:
|
||||
explicit derived_from_memory_resource(unsigned i = 0u)
|
||||
: id(i)
|
||||
{}
|
||||
|
||||
virtual ~derived_from_memory_resource()
|
||||
{ destructor_called = true; }
|
||||
|
||||
virtual void* do_allocate(std::size_t bytes, std::size_t alignment)
|
||||
{
|
||||
do_allocate_called = true;
|
||||
do_allocate_bytes = bytes;
|
||||
do_allocate_alignment = alignment;
|
||||
return do_allocate_return;
|
||||
}
|
||||
|
||||
virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment)
|
||||
{
|
||||
do_deallocate_called = true;
|
||||
do_deallocate_p = p;
|
||||
do_deallocate_bytes = bytes;
|
||||
do_deallocate_alignment = alignment;
|
||||
}
|
||||
|
||||
virtual bool do_is_equal(const boost::container::pmr::memory_resource& other) const BOOST_NOEXCEPT
|
||||
{
|
||||
do_is_equal_called = true;
|
||||
do_is_equal_other = &other;
|
||||
return static_cast<const derived_from_memory_resource&>(other).id == this->id;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
destructor_called = false;
|
||||
|
||||
do_allocate_return = 0;
|
||||
do_allocate_called = false;
|
||||
do_allocate_bytes = 0u;
|
||||
do_allocate_alignment = 0u;
|
||||
|
||||
do_deallocate_called = false;
|
||||
do_deallocate_p = 0;
|
||||
do_deallocate_bytes = 0u;
|
||||
do_deallocate_alignment = 0u;
|
||||
|
||||
do_is_equal_called = false;
|
||||
do_is_equal_other = 0;
|
||||
}
|
||||
//checkers
|
||||
static bool destructor_called;
|
||||
|
||||
unsigned id;
|
||||
void *do_allocate_return;
|
||||
mutable bool do_allocate_called;
|
||||
mutable std::size_t do_allocate_bytes;
|
||||
mutable std::size_t do_allocate_alignment;
|
||||
|
||||
mutable bool do_deallocate_called;
|
||||
mutable void *do_deallocate_p;
|
||||
mutable std::size_t do_deallocate_bytes;
|
||||
mutable std::size_t do_deallocate_alignment;
|
||||
|
||||
mutable bool do_is_equal_called;
|
||||
mutable const boost::container::pmr::memory_resource *do_is_equal_other;
|
||||
};
|
||||
|
||||
bool derived_from_memory_resource::destructor_called = false;
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_TEST_DERIVED_FROM_MEMORY_RESOURCE_HPP
|
||||
@@ -0,0 +1,116 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/global_resource.hpp>
|
||||
#include <boost/container/pmr/memory_resource.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
|
||||
#include "derived_from_memory_resource.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <new>
|
||||
|
||||
using namespace boost::container;
|
||||
using namespace boost::container::pmr;
|
||||
|
||||
std::size_t allocation_count = 0;
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable : 4290)
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40700) && (__cplusplus >= 201103L)
|
||||
#define BOOST_CONTAINER_NEW_EXCEPTION_SPECIFIER
|
||||
#define BOOST_CONTAINER_DELETE_EXCEPTION_SPECIFIER noexcept
|
||||
#else
|
||||
#define BOOST_CONTAINER_NEW_EXCEPTION_SPECIFIER throw(std::bad_alloc)
|
||||
#define BOOST_CONTAINER_DELETE_EXCEPTION_SPECIFIER throw()
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 50000)
|
||||
#pragma GCC diagnostic ignored "-Wsized-deallocation"
|
||||
#endif
|
||||
|
||||
void* operator new[](std::size_t count) BOOST_CONTAINER_NEW_EXCEPTION_SPECIFIER
|
||||
{
|
||||
++allocation_count;
|
||||
return std::malloc(count);
|
||||
}
|
||||
|
||||
void operator delete[](void *p) BOOST_CONTAINER_DELETE_EXCEPTION_SPECIFIER
|
||||
{
|
||||
--allocation_count;
|
||||
return std::free(p);
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
void test_new_delete_resource()
|
||||
{
|
||||
//Make sure new_delete_resource calls new[]/delete[]
|
||||
std::size_t memcount = allocation_count;
|
||||
memory_resource *mr = new_delete_resource();
|
||||
//each time should return the same pointer
|
||||
BOOST_TEST(mr == new_delete_resource());
|
||||
#if !defined(BOOST_CONTAINER_DYNAMIC_LINKING) //No new delete replacement possible new_delete is a DLL
|
||||
BOOST_TEST(memcount == allocation_count);
|
||||
#endif
|
||||
void *addr = mr->allocate(16, 1);
|
||||
#if !defined(BOOST_CONTAINER_DYNAMIC_LINKING) //No new delete replacement possible new_delete is a DLL
|
||||
BOOST_TEST((allocation_count - memcount) == 1);
|
||||
#endif
|
||||
mr->deallocate(addr, 16, 1);
|
||||
BOOST_TEST(memcount == allocation_count);
|
||||
}
|
||||
|
||||
void test_null_memory_resource()
|
||||
{
|
||||
//Make sure it throw or returns null
|
||||
memory_resource *mr = null_memory_resource();
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
bool bad_allocexception_thrown = false;
|
||||
try{
|
||||
mr->allocate(1, 1);
|
||||
}
|
||||
catch(std::bad_alloc&) {
|
||||
bad_allocexception_thrown = true;
|
||||
}
|
||||
catch(...) {
|
||||
}
|
||||
BOOST_TEST(bad_allocexception_thrown == true);
|
||||
#else
|
||||
BOOST_TEST(0 == mr->allocate(1, 1));
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_default_resource()
|
||||
{
|
||||
//Default resource must be new/delete before set_default_resource
|
||||
BOOST_TEST(get_default_resource() == new_delete_resource());
|
||||
//Set default resource and obtain previous
|
||||
derived_from_memory_resource d;
|
||||
memory_resource *prev_default = set_default_resource(&d);
|
||||
BOOST_TEST(get_default_resource() == &d);
|
||||
//Set default resource with null, which should be new/delete
|
||||
prev_default = set_default_resource(0);
|
||||
BOOST_TEST(prev_default == &d);
|
||||
BOOST_TEST(get_default_resource() == new_delete_resource());
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_new_delete_resource();
|
||||
test_null_memory_resource();
|
||||
test_default_resource();
|
||||
return ::boost::report_errors();
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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_MEMORY_RESOURCE_TESTER_HPP
|
||||
#define BOOST_CONTAINER_TEST_MEMORY_RESOURCE_TESTER_HPP
|
||||
|
||||
#include <boost/container/pmr/memory_resource.hpp>
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <cstdlib>
|
||||
|
||||
class memory_resource_logger
|
||||
: public boost::container::pmr::memory_resource
|
||||
{
|
||||
public:
|
||||
struct allocation_info
|
||||
{
|
||||
char *address;
|
||||
std::size_t bytes;
|
||||
std::size_t alignment;
|
||||
};
|
||||
|
||||
boost::container::vector<allocation_info> m_info;
|
||||
unsigned m_mismatches;
|
||||
|
||||
explicit memory_resource_logger()
|
||||
: m_info()
|
||||
, m_mismatches()
|
||||
{}
|
||||
|
||||
virtual ~memory_resource_logger()
|
||||
{ this->reset(); }
|
||||
|
||||
virtual void* do_allocate(std::size_t bytes, std::size_t alignment)
|
||||
{
|
||||
char *addr =(char*)std::malloc(bytes);
|
||||
if(!addr){
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
allocation_info info;
|
||||
info.address = addr;
|
||||
info.bytes = bytes;
|
||||
info.alignment = alignment;
|
||||
m_info.push_back(info);
|
||||
return addr;
|
||||
}
|
||||
|
||||
virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment)
|
||||
{
|
||||
std::size_t i = 0, max = m_info.size();
|
||||
while(i != max && m_info[i].address != p){
|
||||
++i;
|
||||
}
|
||||
if(i == max){
|
||||
++m_mismatches;
|
||||
}
|
||||
else{
|
||||
const allocation_info &info = m_info[i];
|
||||
m_mismatches += info.bytes != bytes || info.alignment != alignment;
|
||||
std::free(p);
|
||||
m_info.erase(m_info.nth(i));
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool do_is_equal(const boost::container::pmr::memory_resource& other) const BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<const memory_resource *>(this) == &other;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
while(!m_info.empty()){
|
||||
std::free(m_info.back().address);
|
||||
m_info.pop_back();
|
||||
}
|
||||
m_mismatches = 0u;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_TEST_MEMORY_RESOURCE_TESTER_HPP
|
||||
@@ -0,0 +1,135 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/memory_resource.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include "derived_from_memory_resource.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace boost::container;
|
||||
using namespace boost::container::pmr;
|
||||
|
||||
void test_allocate()
|
||||
{
|
||||
derived_from_memory_resource d;
|
||||
memory_resource &mr = d;
|
||||
|
||||
d.reset();
|
||||
BOOST_TEST(d.do_allocate_called == false);
|
||||
BOOST_TEST(d.do_allocate_bytes == 0);
|
||||
BOOST_TEST(d.do_allocate_alignment == 0);
|
||||
|
||||
mr.allocate(2, 4);
|
||||
BOOST_TEST(d.do_allocate_called == true);
|
||||
BOOST_TEST(d.do_allocate_bytes == 2);
|
||||
BOOST_TEST(d.do_allocate_alignment == 4);
|
||||
}
|
||||
|
||||
void test_deallocate()
|
||||
{
|
||||
derived_from_memory_resource d;
|
||||
memory_resource &mr = d;
|
||||
|
||||
d.reset();
|
||||
BOOST_TEST(d.do_deallocate_called == false);
|
||||
BOOST_TEST(d.do_deallocate_p == 0);
|
||||
BOOST_TEST(d.do_allocate_bytes == 0);
|
||||
BOOST_TEST(d.do_allocate_alignment == 0);
|
||||
|
||||
mr.deallocate(&d, 2, 4);
|
||||
BOOST_TEST(d.do_deallocate_called == true);
|
||||
BOOST_TEST(d.do_deallocate_p == &d);
|
||||
BOOST_TEST(d.do_deallocate_bytes == 2);
|
||||
BOOST_TEST(d.do_deallocate_alignment == 4);
|
||||
}
|
||||
|
||||
void test_destructor()
|
||||
{
|
||||
{
|
||||
derived_from_memory_resource d;
|
||||
d.reset();
|
||||
BOOST_TEST(derived_from_memory_resource::destructor_called == false);
|
||||
}
|
||||
BOOST_TEST(derived_from_memory_resource::destructor_called == true);
|
||||
}
|
||||
|
||||
void test_is_equal()
|
||||
{
|
||||
derived_from_memory_resource d;
|
||||
memory_resource &mr = d;
|
||||
|
||||
d.reset();
|
||||
BOOST_TEST(d.do_is_equal_called == false);
|
||||
BOOST_TEST(d.do_is_equal_other == 0);
|
||||
|
||||
mr.is_equal(d);
|
||||
BOOST_TEST(d.do_is_equal_called == true);
|
||||
BOOST_TEST(d.do_is_equal_other == &d);
|
||||
}
|
||||
|
||||
void test_equality_operator()
|
||||
{
|
||||
derived_from_memory_resource d;
|
||||
memory_resource &mr = d;
|
||||
|
||||
d.reset();
|
||||
BOOST_TEST(d.do_is_equal_called == false);
|
||||
BOOST_TEST(d.do_is_equal_other == 0);
|
||||
|
||||
//equal addresses are shorcircuited
|
||||
BOOST_TEST((mr == mr) == true);
|
||||
BOOST_TEST(d.do_is_equal_called == false);
|
||||
BOOST_TEST(d.do_is_equal_other == 0);
|
||||
|
||||
//unequal addresses are dispatched to is_equal which in turn calls do_is_equal
|
||||
derived_from_memory_resource d2(1);
|
||||
d.reset();
|
||||
d2.reset();
|
||||
memory_resource &mr2 = d2;
|
||||
BOOST_TEST((mr == mr2) == false);
|
||||
BOOST_TEST(d.do_is_equal_called == true);
|
||||
BOOST_TEST(d.do_is_equal_other == &d2);
|
||||
}
|
||||
|
||||
void test_inequality_operator()
|
||||
{
|
||||
derived_from_memory_resource d;
|
||||
memory_resource &mr = d;
|
||||
|
||||
d.reset();
|
||||
BOOST_TEST(d.do_is_equal_called == false);
|
||||
BOOST_TEST(d.do_is_equal_other == 0);
|
||||
|
||||
//equal addresses are shorcircuited
|
||||
BOOST_TEST((mr != mr) == false);
|
||||
BOOST_TEST(d.do_is_equal_called == false);
|
||||
BOOST_TEST(d.do_is_equal_other == 0);
|
||||
|
||||
//unequal addresses are dispatched to is_equal which in turn calls do_is_equal
|
||||
derived_from_memory_resource d2(1);
|
||||
d.reset();
|
||||
d2.reset();
|
||||
memory_resource &mr2 = d2;
|
||||
BOOST_TEST((mr != mr2) == true);
|
||||
BOOST_TEST(d.do_is_equal_called == true);
|
||||
BOOST_TEST(d.do_is_equal_other == &d2);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_destructor();
|
||||
test_allocate();
|
||||
test_deallocate();
|
||||
test_is_equal();
|
||||
test_equality_operator();
|
||||
test_inequality_operator();
|
||||
return ::boost::report_errors();
|
||||
}
|
||||
@@ -0,0 +1,462 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/monotonic_buffer_resource.hpp>
|
||||
#include <boost/container/pmr/global_resource.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include "derived_from_memory_resource.hpp"
|
||||
#include "memory_resource_logger.hpp"
|
||||
|
||||
using namespace boost::container::pmr;
|
||||
|
||||
static const std::size_t AllocCount = 32u;
|
||||
|
||||
namespace test_block_chain{
|
||||
|
||||
//explicit block_slist(memory_resource &upstream_rsrc)
|
||||
void test_constructor()
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
block_slist bc(mrl);
|
||||
//Resource stored
|
||||
BOOST_TEST(&bc.upstream_resource() == &mrl);
|
||||
//No allocation performed
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
}
|
||||
|
||||
//void *allocate(std::size_t size)
|
||||
void test_allocate()
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
block_slist bc(mrl);
|
||||
|
||||
for(unsigned i = 0; i != unsigned(AllocCount); ++i){
|
||||
//Allocate and trace data
|
||||
const std::size_t alloc = i+1;
|
||||
char *const addr = (char*)bc.allocate(alloc);
|
||||
//Should have allocated a new entry
|
||||
BOOST_TEST(mrl.m_info.size() == (i+1));
|
||||
//Requested size must be bigger to include metadata
|
||||
BOOST_TEST(mrl.m_info[i].bytes > alloc);
|
||||
BOOST_TEST(mrl.m_info[i].alignment == memory_resource::max_align);
|
||||
//Returned address should be between the allocated buffer
|
||||
BOOST_TEST(mrl.m_info[i].address < addr);
|
||||
BOOST_TEST(addr < (mrl.m_info[i].address + mrl.m_info[i].bytes));
|
||||
//Allocate size should include all requested size
|
||||
BOOST_TEST((addr + alloc) <= (mrl.m_info[i].address + mrl.m_info[i].bytes));
|
||||
//Allocation must be max-aligned
|
||||
BOOST_TEST((std::size_t(addr) % memory_resource::max_align) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
//void release() BOOST_NOEXCEPT
|
||||
void test_release()
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
block_slist bc(mrl);
|
||||
|
||||
//Allocate and trace data
|
||||
char *bufs[AllocCount];
|
||||
for(unsigned i = 0; i != unsigned(AllocCount); ++i){
|
||||
bufs[i] = (char*)bc.allocate(i+1);
|
||||
}
|
||||
(void)bufs;
|
||||
//Should have allocated a new entry
|
||||
BOOST_TEST(mrl.m_info.size() == AllocCount);
|
||||
|
||||
//Now release and check all allocations match deallocations
|
||||
bc.release();
|
||||
BOOST_TEST(mrl.m_mismatches == 0);
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
}
|
||||
|
||||
//memory_resource* upstream_resource()
|
||||
void test_memory_resource()
|
||||
{
|
||||
derived_from_memory_resource d;
|
||||
block_slist bc(d);
|
||||
//Resource stored
|
||||
BOOST_TEST(&bc.upstream_resource() == &d);
|
||||
}
|
||||
|
||||
//~block_slist() { this->release(); }
|
||||
void test_destructor()
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
{
|
||||
block_slist bc(mrl);
|
||||
|
||||
//Allocate and trace data
|
||||
char *bufs[AllocCount];
|
||||
for(unsigned i = 0; i != unsigned(AllocCount); ++i){
|
||||
bufs[i] = (char*)bc.allocate(i+1);
|
||||
}
|
||||
(void)bufs;
|
||||
//Should have allocated a new entry
|
||||
BOOST_TEST(mrl.m_info.size() == AllocCount);
|
||||
|
||||
//Destructor should release all memory
|
||||
}
|
||||
BOOST_TEST(mrl.m_mismatches == 0);
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
}
|
||||
|
||||
} //namespace test_block_chain {
|
||||
|
||||
void test_resource_constructor()
|
||||
{
|
||||
//First constructor, null resource
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
set_default_resource(&mrl);
|
||||
monotonic_buffer_resource m;
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == get_default_resource());
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
set_default_resource(0);
|
||||
}
|
||||
//First constructor, non-null resource
|
||||
{
|
||||
derived_from_memory_resource dmr;
|
||||
dmr.reset();
|
||||
monotonic_buffer_resource m(&dmr);
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == &dmr);
|
||||
BOOST_TEST(m.next_buffer_size() == monotonic_buffer_resource::initial_next_buffer_size);
|
||||
BOOST_TEST(m.current_buffer() == 0);
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(dmr.do_allocate_called == false);
|
||||
}
|
||||
}
|
||||
|
||||
void test_initial_size_constructor()
|
||||
{
|
||||
//Second constructor, null resource
|
||||
const std::size_t initial_size = monotonic_buffer_resource::initial_next_buffer_size*2;
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
set_default_resource(&mrl);
|
||||
monotonic_buffer_resource m(initial_size);
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == get_default_resource());
|
||||
BOOST_TEST(m.next_buffer_size() >= initial_size);
|
||||
BOOST_TEST(m.current_buffer() == 0);
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
set_default_resource(0);
|
||||
}
|
||||
//Second constructor, non-null resource
|
||||
{
|
||||
derived_from_memory_resource dmr;
|
||||
dmr.reset();
|
||||
monotonic_buffer_resource m(initial_size, &dmr);
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == &dmr);
|
||||
BOOST_TEST(m.next_buffer_size() >= initial_size);
|
||||
BOOST_TEST(m.current_buffer() == 0);
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(dmr.do_allocate_called == false);
|
||||
}
|
||||
}
|
||||
|
||||
void test_buffer_constructor()
|
||||
{
|
||||
const std::size_t BufSz = monotonic_buffer_resource::initial_next_buffer_size*2;
|
||||
unsigned char buf[BufSz];
|
||||
//Third constructor, null resource
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
set_default_resource(&mrl);
|
||||
monotonic_buffer_resource m(buf, BufSz);
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == get_default_resource());
|
||||
BOOST_TEST(m.next_buffer_size() >= BufSz*2);
|
||||
BOOST_TEST(m.current_buffer() == buf);
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
set_default_resource(0);
|
||||
}
|
||||
//Third constructor, non-null resource
|
||||
{
|
||||
derived_from_memory_resource dmr;
|
||||
dmr.reset();
|
||||
monotonic_buffer_resource m(buf, sizeof(buf), &dmr);
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == &dmr);
|
||||
BOOST_TEST(m.next_buffer_size() >= sizeof(buf)*2);
|
||||
BOOST_TEST(m.current_buffer() == buf);
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(dmr.do_allocate_called == false);
|
||||
}
|
||||
//Check for empty buffers
|
||||
{
|
||||
monotonic_buffer_resource m(buf, 0);
|
||||
BOOST_TEST(m.upstream_resource() == get_default_resource());
|
||||
BOOST_TEST(m.next_buffer_size() > 1);
|
||||
BOOST_TEST(m.current_buffer() == buf);
|
||||
}
|
||||
}
|
||||
|
||||
struct derived_from_monotonic_buffer_resource
|
||||
: public monotonic_buffer_resource
|
||||
{
|
||||
explicit derived_from_monotonic_buffer_resource(memory_resource *p)
|
||||
: monotonic_buffer_resource(p)
|
||||
{}
|
||||
|
||||
explicit derived_from_monotonic_buffer_resource(std::size_t initial_size, memory_resource* upstream)
|
||||
: monotonic_buffer_resource(initial_size, upstream)
|
||||
{}
|
||||
|
||||
explicit derived_from_monotonic_buffer_resource(void* buffer, std::size_t buffer_size, memory_resource* upstream)
|
||||
: monotonic_buffer_resource(buffer, buffer_size, upstream)
|
||||
{}
|
||||
|
||||
using monotonic_buffer_resource::do_allocate;
|
||||
using monotonic_buffer_resource::do_deallocate;
|
||||
using monotonic_buffer_resource::do_is_equal;
|
||||
};
|
||||
|
||||
void test_upstream_resource()
|
||||
{
|
||||
//Test stores the resource and uses it to allocate memory
|
||||
derived_from_memory_resource dmr;
|
||||
dmr.reset();
|
||||
derived_from_monotonic_buffer_resource dmbr(&dmr);
|
||||
//Resource must be stored and initial values given (no current buffer)
|
||||
BOOST_TEST(dmbr.upstream_resource() == &dmr);
|
||||
BOOST_TEST(dmbr.next_buffer_size() == monotonic_buffer_resource::initial_next_buffer_size);
|
||||
BOOST_TEST(dmbr.current_buffer() == 0);
|
||||
//Test it does not allocate any memory
|
||||
BOOST_TEST(dmr.do_allocate_called == false);
|
||||
const std::size_t BufSz = monotonic_buffer_resource::initial_next_buffer_size;
|
||||
//Now allocate storage, and stub it as the return buffer
|
||||
//for "derived_from_memory_resource":
|
||||
boost::move_detail::aligned_storage<BufSz+block_slist::header_size>::type buf;
|
||||
dmr.do_allocate_return = &buf;
|
||||
//Test that allocation uses the upstream_resource()
|
||||
void *addr = dmbr.do_allocate(1u, 1u);
|
||||
//Test returns stubbed memory with the internal initial size plus metadata size
|
||||
BOOST_TEST(addr > (char*)&buf);
|
||||
BOOST_TEST(addr < (char*)(&buf+1));
|
||||
BOOST_TEST(dmr.do_allocate_called == true);
|
||||
BOOST_TEST(dmr.do_allocate_bytes > BufSz);
|
||||
//Alignment for the resource must be max_align
|
||||
BOOST_TEST(dmr.do_allocate_alignment == memory_resource::max_align);
|
||||
}
|
||||
|
||||
void test_do_allocate()
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
{
|
||||
std::size_t remaining_storage = 0u;
|
||||
derived_from_monotonic_buffer_resource dmbr(&mrl);
|
||||
//First test, no buffer
|
||||
{
|
||||
dmbr.do_allocate(1, 1);
|
||||
//It should allocate initial size
|
||||
BOOST_TEST(mrl.m_info.size() == 1u);
|
||||
//... which requests the initial size plus the header size to the allcoator
|
||||
BOOST_TEST(mrl.m_info[0].bytes == monotonic_buffer_resource::initial_next_buffer_size+block_slist::header_size);
|
||||
std::size_t remaining = dmbr.remaining_storage(1u);
|
||||
//Remaining storage should be one less than initial, as we requested 1 byte with minimal alignment
|
||||
BOOST_TEST(remaining == monotonic_buffer_resource::initial_next_buffer_size-1u);
|
||||
remaining_storage = remaining;
|
||||
}
|
||||
//Now ask for more internal storage with misaligned current buffer
|
||||
{
|
||||
//Test wasted space
|
||||
std::size_t wasted_due_to_alignment;
|
||||
dmbr.remaining_storage(4u, wasted_due_to_alignment);
|
||||
BOOST_TEST(wasted_due_to_alignment == 3u);
|
||||
dmbr.do_allocate(4, 4);
|
||||
//It should not have allocated
|
||||
BOOST_TEST(mrl.m_info.size() == 1u);
|
||||
std::size_t remaining = dmbr.remaining_storage(1u);
|
||||
//We wasted some bytes due to alignment plus 4 bytes of real storage
|
||||
BOOST_TEST(remaining == remaining_storage - 4 - wasted_due_to_alignment);
|
||||
remaining_storage = remaining;
|
||||
}
|
||||
//Now request the same alignment to test no storage is wasted
|
||||
{
|
||||
std::size_t wasted_due_to_alignment;
|
||||
std::size_t remaining = dmbr.remaining_storage(1u, wasted_due_to_alignment);
|
||||
BOOST_TEST(mrl.m_info.size() == 1u);
|
||||
dmbr.do_allocate(4, 4);
|
||||
//It should not have allocated
|
||||
BOOST_TEST(mrl.m_info.size() == 1u);
|
||||
remaining = dmbr.remaining_storage(1u);
|
||||
//We wasted no bytes due to alignment plus 4 bytes of real storage
|
||||
BOOST_TEST(remaining == remaining_storage - 4u);
|
||||
remaining_storage = remaining;
|
||||
}
|
||||
//Now exhaust the remaining storage with 2 byte alignment (the last allocation
|
||||
//was 4 bytes with 4 byte alignment) so it should be already 2-byte aligned.
|
||||
{
|
||||
dmbr.do_allocate(remaining_storage, 2);
|
||||
std::size_t wasted_due_to_alignment;
|
||||
std::size_t remaining = dmbr.remaining_storage(1u, wasted_due_to_alignment);
|
||||
BOOST_TEST(wasted_due_to_alignment == 0u);
|
||||
BOOST_TEST(remaining == 0u);
|
||||
//It should not have allocated
|
||||
BOOST_TEST(mrl.m_info.size() == 1u);
|
||||
remaining_storage = 0u;
|
||||
}
|
||||
//The next allocation should trigger the upstream resource, even with a 1 byte
|
||||
//allocation.
|
||||
{
|
||||
dmbr.do_allocate(1u, 1u);
|
||||
BOOST_TEST(mrl.m_info.size() == 2u);
|
||||
//The next allocation should be geometrically bigger.
|
||||
BOOST_TEST(mrl.m_info[1].bytes == 2*monotonic_buffer_resource::initial_next_buffer_size+block_slist::header_size);
|
||||
std::size_t wasted_due_to_alignment;
|
||||
//For a 2 byte alignment one byte will be wasted from the previous 1 byte allocation
|
||||
std::size_t remaining = dmbr.remaining_storage(2u, wasted_due_to_alignment);
|
||||
BOOST_TEST(wasted_due_to_alignment == 1u);
|
||||
BOOST_TEST(remaining == (mrl.m_info[1].bytes - 1u - wasted_due_to_alignment - block_slist::header_size));
|
||||
//It should not have allocated
|
||||
remaining_storage = dmbr.remaining_storage(1u);
|
||||
}
|
||||
//Now try a bigger than next allocation and see if next_buffer_size is doubled.
|
||||
{
|
||||
std::size_t next_alloc = 5*monotonic_buffer_resource::initial_next_buffer_size;
|
||||
dmbr.do_allocate(next_alloc, 1u);
|
||||
BOOST_TEST(mrl.m_info.size() == 3u);
|
||||
//The next allocation should be geometrically bigger.
|
||||
BOOST_TEST(mrl.m_info[2].bytes == 8*monotonic_buffer_resource::initial_next_buffer_size+block_slist::header_size);
|
||||
remaining_storage = dmbr.remaining_storage(1u);
|
||||
}
|
||||
}
|
||||
//derived_from_monotonic_buffer_resource dmbr(&mrl) is destroyed
|
||||
BOOST_TEST(mrl.m_mismatches == 0u);
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
|
||||
//Now use a local buffer
|
||||
{
|
||||
boost::move_detail::aligned_storage
|
||||
<monotonic_buffer_resource::initial_next_buffer_size>::type buf;
|
||||
//Supply an external buffer
|
||||
derived_from_monotonic_buffer_resource dmbr(&buf, sizeof(buf), &mrl);
|
||||
BOOST_TEST(dmbr.remaining_storage(1u) == sizeof(buf));
|
||||
//Allocate all remaining storage
|
||||
dmbr.do_allocate(dmbr.remaining_storage(1u), 1u);
|
||||
//No new allocation should have ocurred
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
BOOST_TEST(dmbr.remaining_storage(1u) == 0u);
|
||||
}
|
||||
BOOST_TEST(mrl.m_mismatches == 0u);
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
}
|
||||
|
||||
void test_do_deallocate()
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
const std::size_t initial_size = 1u;
|
||||
{
|
||||
derived_from_monotonic_buffer_resource dmbr(initial_size, &mrl);
|
||||
//First test, no buffer
|
||||
const unsigned iterations = 8;
|
||||
char *bufs[iterations];
|
||||
std::size_t sizes[iterations];
|
||||
//Test each iteration allocates memory
|
||||
for(unsigned i = 0; i != iterations; ++i)
|
||||
{
|
||||
sizes[i] = dmbr.remaining_storage()+1;
|
||||
bufs[i] = (char*)dmbr.do_allocate(sizes[i], 1);
|
||||
BOOST_TEST(mrl.m_info.size() == (i+1));
|
||||
}
|
||||
std::size_t remaining = dmbr.remaining_storage();
|
||||
//Test do_deallocate does not release any storage
|
||||
for(unsigned i = 0; i != iterations; ++i)
|
||||
{
|
||||
dmbr.do_deallocate(bufs[i], sizes[i], 1u);
|
||||
BOOST_TEST(mrl.m_info.size() == iterations);
|
||||
BOOST_TEST(remaining == dmbr.remaining_storage());
|
||||
BOOST_TEST(mrl.m_mismatches == 0u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void test_do_is_equal()
|
||||
{
|
||||
//! <b>Returns</b>:
|
||||
//! `this == dynamic_cast<const monotonic_buffer_resource*>(&other)`.
|
||||
memory_resource_logger mrl;
|
||||
derived_from_monotonic_buffer_resource dmbr(&mrl);
|
||||
derived_from_monotonic_buffer_resource dmbr2(&mrl);
|
||||
BOOST_TEST(true == dmbr.do_is_equal(dmbr));
|
||||
BOOST_TEST(false == dmbr.do_is_equal(dmbr2));
|
||||
//A different type should be always different
|
||||
derived_from_memory_resource dmr;
|
||||
BOOST_TEST(false == dmbr.do_is_equal(dmr));
|
||||
}
|
||||
|
||||
void test_release()
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
const std::size_t initial_size = 1u;
|
||||
derived_from_monotonic_buffer_resource dmbr(initial_size, &mrl);
|
||||
//First test, no buffer
|
||||
const unsigned iterations = 8;
|
||||
//Test each iteration allocates memory
|
||||
for(unsigned i = 0; i != iterations; ++i)
|
||||
{
|
||||
dmbr.do_allocate(dmbr.remaining_storage()+1, 1);
|
||||
BOOST_TEST(mrl.m_info.size() == (i+1));
|
||||
}
|
||||
//Release and check memory was released
|
||||
dmbr.release();
|
||||
BOOST_TEST(mrl.m_mismatches == 0u);
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
}
|
||||
|
||||
void test_destructor()
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
const std::size_t initial_size = 1u;
|
||||
{
|
||||
derived_from_monotonic_buffer_resource dmbr(initial_size, &mrl);
|
||||
//First test, no buffer
|
||||
const unsigned iterations = 8;
|
||||
//Test each iteration allocates memory
|
||||
for(unsigned i = 0; i != iterations; ++i)
|
||||
{
|
||||
dmbr.do_allocate(dmbr.remaining_storage()+1, 1);
|
||||
BOOST_TEST(mrl.m_info.size() == (i+1));
|
||||
}
|
||||
} //dmbr is destroyed, memory should be released
|
||||
BOOST_TEST(mrl.m_mismatches == 0u);
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_block_chain::test_constructor();
|
||||
test_block_chain::test_allocate();
|
||||
test_block_chain::test_release();
|
||||
test_block_chain::test_memory_resource();
|
||||
test_block_chain::test_destructor();
|
||||
|
||||
test_resource_constructor();
|
||||
test_initial_size_constructor();
|
||||
test_buffer_constructor();
|
||||
|
||||
test_upstream_resource();
|
||||
test_do_allocate();
|
||||
test_do_deallocate();
|
||||
test_do_is_equal();
|
||||
test_release();
|
||||
test_destructor();
|
||||
return ::boost::report_errors();
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/deque.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
using boost::container::container_detail::is_same;
|
||||
|
||||
typedef deque<int, pmr::polymorphic_allocator<int> > intcontainer_t;
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::deque_of<int>::type >::value ));
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::deque<int> >::value ));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/flat_map.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
using boost::container::container_detail::is_same;
|
||||
|
||||
typedef flat_map<int, float, std::less<int>, pmr::polymorphic_allocator<std::pair<int, float> > > intcontainer_t;
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::flat_map_of<int, float>::type >::value ));
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::flat_map<int, float> >::value ));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/flat_set.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
using boost::container::container_detail::is_same;
|
||||
|
||||
typedef flat_set<int, std::less<int>, pmr::polymorphic_allocator<int> > intcontainer_t;
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::flat_set_of<int>::type >::value ));
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::flat_set<int> >::value ));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/list.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
using boost::container::container_detail::is_same;
|
||||
|
||||
typedef list<int, pmr::polymorphic_allocator<int> > intcontainer_t;
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::list_of<int>::type >::value ));
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::list<int> >::value ));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/map.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
using boost::container::container_detail::is_same;
|
||||
|
||||
typedef map<int, float, std::less<int>, pmr::polymorphic_allocator<std::pair<const int, float> > > intcontainer_t;
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::map_of<int, float>::type >::value ));
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::map<int, float> >::value ));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/set.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
using boost::container::container_detail::is_same;
|
||||
|
||||
typedef set<int, std::less<int>, pmr::polymorphic_allocator<int> > intcontainer_t;
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::set_of<int>::type >::value ));
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::set<int> >::value ));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/slist.hpp>
|
||||
|
||||
struct empty
|
||||
{
|
||||
friend bool operator == (const empty &, const empty &){ return true; }
|
||||
friend bool operator < (const empty &, const empty &){ return true; }
|
||||
};
|
||||
|
||||
template class ::boost::container::slist<empty>;
|
||||
|
||||
int main()
|
||||
{
|
||||
::boost::container::slist<empty> dummy;
|
||||
(void)dummy;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/small_vector.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
using boost::container::container_detail::is_same;
|
||||
|
||||
typedef small_vector<int, 2, pmr::polymorphic_allocator<int> > intcontainer_t;
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::small_vector_of<int, 2>::type >::value ));
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::small_vector<int, 2> >::value ));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/stable_vector.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
using boost::container::container_detail::is_same;
|
||||
|
||||
typedef stable_vector<int, pmr::polymorphic_allocator<int> > intcontainer_t;
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::stable_vector_of<int>::type >::value ));
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::stable_vector<int> >::value ));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/static_vector.hpp>
|
||||
|
||||
struct empty
|
||||
{
|
||||
friend bool operator == (const empty &, const empty &){ return true; }
|
||||
friend bool operator < (const empty &, const empty &){ return true; }
|
||||
};
|
||||
|
||||
template class ::boost::container::static_vector<empty, 2>;
|
||||
|
||||
int main()
|
||||
{
|
||||
::boost::container::static_vector<empty, 2> dummy;
|
||||
(void)dummy;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/string.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
using boost::container::container_detail::is_same;
|
||||
|
||||
typedef basic_string<char, std::char_traits<char>, pmr::polymorphic_allocator<char> > string_t;
|
||||
typedef basic_string<wchar_t, std::char_traits<wchar_t>, pmr::polymorphic_allocator<wchar_t> > wstring_t;
|
||||
BOOST_STATIC_ASSERT(( is_same<string_t, pmr::string>::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same<string_t, pmr::basic_string_of<char>::type>::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same<wstring_t, pmr::wstring>::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same<wstring_t, pmr::basic_string_of<wchar_t>::type>::value ));
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
BOOST_STATIC_ASSERT(( is_same<string_t, pmr::string >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same<wstring_t, pmr::wstring >::value ));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/vector.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
using boost::container::container_detail::is_same;
|
||||
|
||||
typedef vector<int, pmr::polymorphic_allocator<int> > intcontainer_t;
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::vector_of<int>::type >::value ));
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::vector<int> >::value ));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/polymorphic_allocator.hpp>
|
||||
#include <boost/container/pmr/global_resource.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#include "derived_from_memory_resource.hpp"
|
||||
#include "propagation_test_allocator.hpp"
|
||||
|
||||
using namespace boost::container::pmr;
|
||||
using namespace boost::container;
|
||||
|
||||
void test_default_constructor()
|
||||
{
|
||||
polymorphic_allocator<int> a;
|
||||
BOOST_TEST(a.resource() == get_default_resource());
|
||||
}
|
||||
|
||||
void test_resource_constructor()
|
||||
{
|
||||
polymorphic_allocator<int> a(0);
|
||||
BOOST_TEST(a.resource() == get_default_resource());
|
||||
|
||||
derived_from_memory_resource d;
|
||||
polymorphic_allocator<int> b(&d);
|
||||
BOOST_TEST(&d == b.resource());
|
||||
}
|
||||
|
||||
void test_copy_constructor()
|
||||
{
|
||||
derived_from_memory_resource d;
|
||||
polymorphic_allocator<int> b(&d);
|
||||
polymorphic_allocator<int> c(b);
|
||||
BOOST_TEST(b.resource() == c.resource());
|
||||
}
|
||||
|
||||
void test_copy_assignment()
|
||||
{
|
||||
derived_from_memory_resource d;
|
||||
polymorphic_allocator<int> b(&d);
|
||||
polymorphic_allocator<int> c;
|
||||
BOOST_TEST(c.resource() == get_default_resource());
|
||||
c = b;
|
||||
BOOST_TEST(c.resource() == b.resource());
|
||||
}
|
||||
|
||||
void test_allocate()
|
||||
{
|
||||
int dummy;
|
||||
derived_from_memory_resource d;
|
||||
polymorphic_allocator<int> p(&d);
|
||||
d.reset();
|
||||
d.do_allocate_return = &dummy;
|
||||
p.allocate(2);
|
||||
BOOST_TEST(d.do_allocate_called == true);
|
||||
BOOST_TEST(d.do_allocate_return == &dummy);
|
||||
//It shall allocate 2*sizeof(int), alignment_of<int>
|
||||
BOOST_TEST(d.do_allocate_bytes == 2*sizeof(int));
|
||||
BOOST_TEST(d.do_allocate_alignment == container_detail::alignment_of<int>::value);
|
||||
}
|
||||
|
||||
void test_deallocate()
|
||||
{
|
||||
int dummy;
|
||||
derived_from_memory_resource d;
|
||||
polymorphic_allocator<int> p(&d);
|
||||
d.reset();
|
||||
p.deallocate(&dummy, 3);
|
||||
BOOST_TEST(d.do_deallocate_called == true);
|
||||
//It shall deallocate 2*sizeof(int), alignment_of<int>
|
||||
BOOST_TEST(d.do_deallocate_p == &dummy);
|
||||
BOOST_TEST(d.do_deallocate_bytes == 3*sizeof(int));
|
||||
BOOST_TEST(d.do_deallocate_alignment == container_detail::alignment_of<int>::value);
|
||||
}
|
||||
|
||||
void test_construct()
|
||||
{
|
||||
//0 arg
|
||||
{
|
||||
typedef allocator_argument_tester<NotUsesAllocator, 0> value_type;
|
||||
value_type value;
|
||||
value.~value_type();
|
||||
polymorphic_allocator<int> pa;
|
||||
pa.construct(&value);
|
||||
BOOST_TEST(value.construction_type == NotUsesAllocator);
|
||||
BOOST_TEST(value.value == 0);
|
||||
value.~value_type();
|
||||
}
|
||||
{
|
||||
typedef allocator_argument_tester<ErasedTypePrefix, 0> value_type;
|
||||
value_type value;
|
||||
value.~value_type();
|
||||
polymorphic_allocator<int> pa;
|
||||
pa.construct(&value);
|
||||
BOOST_TEST(value.construction_type == ConstructiblePrefix);
|
||||
BOOST_TEST(value.value == 0);
|
||||
value.~value_type();
|
||||
}
|
||||
{
|
||||
typedef allocator_argument_tester<ErasedTypeSuffix, 0> value_type;
|
||||
value_type value;
|
||||
value.~value_type();
|
||||
polymorphic_allocator<int> pa;
|
||||
pa.construct(&value);
|
||||
BOOST_TEST(value.construction_type == ConstructibleSuffix);
|
||||
BOOST_TEST(value.value == 0);
|
||||
value.~value_type();
|
||||
}
|
||||
//1 arg
|
||||
{
|
||||
typedef allocator_argument_tester<NotUsesAllocator, 0> value_type;
|
||||
value_type value;
|
||||
value.~value_type();
|
||||
polymorphic_allocator<int> pa;
|
||||
pa.construct(&value, 2);
|
||||
BOOST_TEST(value.construction_type == NotUsesAllocator);
|
||||
BOOST_TEST(value.value == 2);
|
||||
value.~value_type();
|
||||
}
|
||||
{
|
||||
typedef allocator_argument_tester<ErasedTypePrefix, 0> value_type;
|
||||
value_type value;
|
||||
value.~value_type();
|
||||
polymorphic_allocator<int> pa;
|
||||
pa.construct(&value, 3);
|
||||
BOOST_TEST(value.construction_type == ConstructiblePrefix);
|
||||
BOOST_TEST(value.value == 3);
|
||||
value.~value_type();
|
||||
}
|
||||
{
|
||||
typedef allocator_argument_tester<ErasedTypeSuffix, 0> value_type;
|
||||
value_type value;
|
||||
value.~value_type();
|
||||
polymorphic_allocator<int> pa;
|
||||
pa.construct(&value, 4);
|
||||
BOOST_TEST(value.construction_type == ConstructibleSuffix);
|
||||
BOOST_TEST(value.value == 4);
|
||||
value.~value_type();
|
||||
}
|
||||
}
|
||||
|
||||
struct char_holder
|
||||
{
|
||||
char m_char;
|
||||
~char_holder()
|
||||
{ destructor_called = true; }
|
||||
static bool destructor_called;
|
||||
};
|
||||
|
||||
bool char_holder::destructor_called = false;
|
||||
|
||||
void test_destroy()
|
||||
{
|
||||
char_holder ch;
|
||||
polymorphic_allocator<int> p;
|
||||
BOOST_TEST(char_holder::destructor_called == false);
|
||||
p.destroy(&ch);
|
||||
BOOST_TEST(char_holder::destructor_called == true);
|
||||
}
|
||||
|
||||
void test_select_on_container_copy_construction()
|
||||
{
|
||||
//select_on_container_copy_construction shall return
|
||||
//a default constructed polymorphic_allocator
|
||||
//which uses the default resource.
|
||||
derived_from_memory_resource d;
|
||||
polymorphic_allocator<int> p(&d);
|
||||
BOOST_TEST(get_default_resource() == p.select_on_container_copy_construction().resource());
|
||||
}
|
||||
|
||||
void test_resource()
|
||||
{
|
||||
derived_from_memory_resource d;
|
||||
polymorphic_allocator<int> p(&d);
|
||||
BOOST_TEST(&d == p.resource());
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_default_constructor();
|
||||
test_resource_constructor();
|
||||
test_copy_constructor();
|
||||
test_copy_assignment();
|
||||
test_allocate();
|
||||
test_deallocate();
|
||||
test_construct();
|
||||
test_destroy();
|
||||
test_select_on_container_copy_construction();
|
||||
test_resource();
|
||||
return ::boost::report_errors();
|
||||
}
|
||||
@@ -0,0 +1,493 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/global_resource.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#include <boost/intrusive/detail/math.hpp>
|
||||
|
||||
#include "derived_from_memory_resource.hpp"
|
||||
#include "memory_resource_logger.hpp"
|
||||
|
||||
using namespace boost::container::pmr;
|
||||
|
||||
template<class PoolResource>
|
||||
struct derived_from_pool_resource
|
||||
: public PoolResource
|
||||
{
|
||||
derived_from_pool_resource(const pool_options& opts, memory_resource* upstream)
|
||||
: PoolResource(opts, upstream)
|
||||
{}
|
||||
|
||||
explicit derived_from_pool_resource(memory_resource *p)
|
||||
: PoolResource(p)
|
||||
{}
|
||||
|
||||
explicit derived_from_pool_resource(const pool_options &opts)
|
||||
: PoolResource(opts)
|
||||
{}
|
||||
|
||||
derived_from_pool_resource()
|
||||
: PoolResource()
|
||||
{}
|
||||
|
||||
using PoolResource::do_allocate;
|
||||
using PoolResource::do_deallocate;
|
||||
using PoolResource::do_is_equal;
|
||||
};
|
||||
|
||||
template<class PoolResource>
|
||||
void test_default_constructor()
|
||||
{
|
||||
//With default options/resource
|
||||
{
|
||||
derived_from_memory_resource dmr;
|
||||
dmr.reset();
|
||||
PoolResource m;
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == get_default_resource());
|
||||
BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
|
||||
BOOST_TEST(m.options().largest_required_pool_block == pool_options_default_largest_required_pool_block);
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(dmr.do_allocate_called == false);
|
||||
}
|
||||
}
|
||||
|
||||
template<class PoolResource>
|
||||
void test_upstream_constructor()
|
||||
{
|
||||
//With a resource, default options
|
||||
{
|
||||
derived_from_memory_resource dmr;
|
||||
dmr.reset();
|
||||
PoolResource m(&dmr);
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == &dmr);
|
||||
BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
|
||||
BOOST_TEST(m.options().largest_required_pool_block == pool_options_default_largest_required_pool_block);
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(dmr.do_allocate_called == false);
|
||||
}
|
||||
}
|
||||
|
||||
template<class PoolResource>
|
||||
void test_options_constructor()
|
||||
{
|
||||
//Default options
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
set_default_resource(&mrl);
|
||||
pool_options opts;
|
||||
PoolResource m(opts);
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == get_default_resource());
|
||||
BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
|
||||
BOOST_TEST(m.options().largest_required_pool_block == pool_options_default_largest_required_pool_block);
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
}
|
||||
//Too large option values
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
set_default_resource(&mrl);
|
||||
pool_options opts;
|
||||
opts.max_blocks_per_chunk = pool_options_default_max_blocks_per_chunk+1;
|
||||
opts.largest_required_pool_block = pool_options_default_largest_required_pool_block+1;
|
||||
PoolResource m(opts);
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == get_default_resource());
|
||||
BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
|
||||
BOOST_TEST(m.options().largest_required_pool_block == pool_options_default_largest_required_pool_block);
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
}
|
||||
//Too small option values
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
set_default_resource(&mrl);
|
||||
pool_options opts;
|
||||
opts.largest_required_pool_block = pool_options_minimum_largest_required_pool_block-1u;
|
||||
PoolResource m(opts);
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == get_default_resource());
|
||||
BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
|
||||
BOOST_TEST(m.options().largest_required_pool_block == pool_options_minimum_largest_required_pool_block);
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
}
|
||||
//In range option values
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
set_default_resource(&mrl);
|
||||
pool_options opts;
|
||||
opts.max_blocks_per_chunk = pool_options_default_max_blocks_per_chunk;
|
||||
opts.largest_required_pool_block = pool_options_minimum_largest_required_pool_block;
|
||||
PoolResource m(opts);
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == get_default_resource());
|
||||
BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
|
||||
BOOST_TEST(m.options().largest_required_pool_block == pool_options_minimum_largest_required_pool_block);
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
}
|
||||
}
|
||||
|
||||
template<class PoolResource>
|
||||
void test_options_upstream_constructor()
|
||||
{
|
||||
//Default options
|
||||
{
|
||||
derived_from_memory_resource dmr;
|
||||
dmr.reset();
|
||||
pool_options opts;
|
||||
PoolResource m(opts, &dmr);
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == &dmr);
|
||||
BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
|
||||
BOOST_TEST(m.options().largest_required_pool_block == pool_options_default_largest_required_pool_block);
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(dmr.do_allocate_called == false);
|
||||
}
|
||||
//Too large option values
|
||||
{
|
||||
derived_from_memory_resource dmr;
|
||||
dmr.reset();
|
||||
pool_options opts;
|
||||
opts.max_blocks_per_chunk = pool_options_default_max_blocks_per_chunk+1;
|
||||
opts.largest_required_pool_block = pool_options_default_largest_required_pool_block+1;
|
||||
PoolResource m(opts, &dmr);
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == &dmr);
|
||||
BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
|
||||
BOOST_TEST(m.options().largest_required_pool_block == pool_options_default_largest_required_pool_block);
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(dmr.do_allocate_called == false);
|
||||
}
|
||||
//Too small option values
|
||||
{
|
||||
derived_from_memory_resource dmr;
|
||||
dmr.reset();
|
||||
pool_options opts;
|
||||
opts.largest_required_pool_block = pool_options_minimum_largest_required_pool_block-1u;
|
||||
PoolResource m(opts, &dmr);
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == &dmr);
|
||||
BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
|
||||
BOOST_TEST(m.options().largest_required_pool_block == pool_options_minimum_largest_required_pool_block);
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(dmr.do_allocate_called == false);
|
||||
}
|
||||
//In range option values
|
||||
{
|
||||
derived_from_memory_resource dmr;
|
||||
dmr.reset();
|
||||
pool_options opts;
|
||||
opts.max_blocks_per_chunk = pool_options_default_max_blocks_per_chunk;
|
||||
opts.largest_required_pool_block = pool_options_minimum_largest_required_pool_block;
|
||||
PoolResource m(opts, &dmr);
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == &dmr);
|
||||
//max blocks is unchanged in this implementation
|
||||
BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
|
||||
//largest block is rounded to pow2
|
||||
BOOST_TEST(m.options().largest_required_pool_block == bi::detail::ceil_pow2(opts.largest_required_pool_block));
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(dmr.do_allocate_called == false);
|
||||
}
|
||||
}
|
||||
|
||||
template<class PoolResource>
|
||||
void test_options()
|
||||
{
|
||||
//In range option values
|
||||
{
|
||||
derived_from_memory_resource dmr;
|
||||
dmr.reset();
|
||||
pool_options opts;
|
||||
opts.max_blocks_per_chunk = pool_options_default_max_blocks_per_chunk/2u;
|
||||
opts.largest_required_pool_block = (pool_options_default_largest_required_pool_block
|
||||
- pool_options_minimum_largest_required_pool_block) | std::size_t(1); //guaranteed to be non power of 2.
|
||||
PoolResource m(opts, &dmr);
|
||||
//test postconditions
|
||||
BOOST_TEST(m.upstream_resource() == &dmr);
|
||||
//max blocks is unchanged in this implementation
|
||||
BOOST_TEST(m.options().max_blocks_per_chunk == opts.max_blocks_per_chunk);
|
||||
//largest block is rounded to pow2
|
||||
BOOST_TEST(m.options().largest_required_pool_block == bi::detail::ceil_pow2(opts.largest_required_pool_block));
|
||||
//test it does not allocate any memory
|
||||
BOOST_TEST(dmr.do_allocate_called == false);
|
||||
}
|
||||
}
|
||||
|
||||
template<class PoolResource>
|
||||
void test_do_allocate_deallocate()
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
{
|
||||
derived_from_pool_resource<PoolResource> dmbr(&mrl);
|
||||
{
|
||||
//First block from pool 0
|
||||
dmbr.do_allocate(1, 1);
|
||||
//It should allocate the pool array plus an initial block
|
||||
BOOST_TEST(mrl.m_info.size() == 2u);
|
||||
//Second block from pool 0
|
||||
dmbr.do_allocate(1, 1);
|
||||
//It should allocate again (with 2 chunks per block)
|
||||
BOOST_TEST(mrl.m_info.size() == 3u);
|
||||
//Third block from pool 0
|
||||
dmbr.do_allocate(1, 1);
|
||||
//It should NOT allocate again (previous was a 2 block chunk)
|
||||
BOOST_TEST(mrl.m_info.size() == 3u);
|
||||
}
|
||||
}
|
||||
BOOST_TEST(mrl.m_mismatches == 0u);
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
|
||||
//Allocate and deallocate from the same chunk to test block caching
|
||||
{
|
||||
derived_from_pool_resource<PoolResource> dmbr(&mrl);
|
||||
{
|
||||
//First block from pool 0
|
||||
void *p = dmbr.do_allocate(1, 1);
|
||||
//It should allocate the pool array plus an initial block
|
||||
BOOST_TEST(mrl.m_info.size() == 2u);
|
||||
//No cached, as initial blocks per chunk is 1
|
||||
BOOST_TEST(dmbr.pool_cached_blocks(0u) == 0u);
|
||||
//Deallocate and allocate again
|
||||
dmbr.do_deallocate(p, 1, 1);
|
||||
//Cached
|
||||
BOOST_TEST(dmbr.pool_cached_blocks(0u) == 1u);
|
||||
p = dmbr.do_allocate(1, 1);
|
||||
//Reused
|
||||
BOOST_TEST(dmbr.pool_cached_blocks(0u) == 0u);
|
||||
//It should have NOT allocated (block reuse)
|
||||
BOOST_TEST(mrl.m_info.size() == 2u);
|
||||
|
||||
//Allocate again 2 times (a 2 block chunk is exhausted)
|
||||
void *p2 = dmbr.do_allocate(1, 1);
|
||||
//1 left cached
|
||||
BOOST_TEST(dmbr.pool_cached_blocks(0u) == 1u);
|
||||
void *p3 = dmbr.do_allocate(1, 1);
|
||||
//Cache exhausted
|
||||
BOOST_TEST(dmbr.pool_cached_blocks(0u) == 0u);
|
||||
//Single chunk allocation happened
|
||||
BOOST_TEST(mrl.m_info.size() == 3u);
|
||||
|
||||
//Now deallocate all (no memory is freed, all cached)
|
||||
dmbr.do_deallocate(p2, 1, 1);
|
||||
dmbr.do_deallocate(p3, 1, 1);
|
||||
dmbr.do_deallocate(p, 1, 1);
|
||||
BOOST_TEST(dmbr.pool_cached_blocks(0u) == 3u);
|
||||
BOOST_TEST(mrl.m_info.size() == 3u);
|
||||
}
|
||||
}
|
||||
BOOST_TEST(mrl.m_mismatches == 0u);
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
|
||||
//Now test max block per chunk
|
||||
{
|
||||
pool_options opts;
|
||||
//so after max_blocks_per_chunk*2-1 allocations, all new chunks must hold max_blocks_per_chunk blocks
|
||||
opts.max_blocks_per_chunk = 32u;
|
||||
derived_from_pool_resource<PoolResource> dmbr(opts, &mrl);
|
||||
{
|
||||
std::size_t loops = opts.max_blocks_per_chunk*2-1u;
|
||||
while(loops--){
|
||||
dmbr.do_allocate(1, 1);
|
||||
}
|
||||
//pool array + log2(max_blocks_per_chunk)+1 chunks (sizes [1, 2, 4, ...])
|
||||
const std::size_t num_chunks = bi::detail::floor_log2(opts.max_blocks_per_chunk)+1u;
|
||||
BOOST_TEST(mrl.m_info.size() == 1u + num_chunks);
|
||||
//Next allocation should allocate max_blocks_per_chunk blocks in a chunk so max_blocks_per_chunk-1 should remain free
|
||||
dmbr.do_allocate(1, 1);
|
||||
BOOST_TEST(mrl.m_info.size() == 1u + num_chunks + 1u);
|
||||
BOOST_TEST(dmbr.pool_cached_blocks(0u) == (opts.max_blocks_per_chunk-1u));
|
||||
//Exhaust the chunk and allocate a new one, test max_blocks_per_chunk is not passed again
|
||||
loops = opts.max_blocks_per_chunk;
|
||||
while(loops--){
|
||||
dmbr.do_allocate(1, 1);
|
||||
}
|
||||
BOOST_TEST(mrl.m_info.size() == 1u + num_chunks + 2u);
|
||||
BOOST_TEST(dmbr.pool_cached_blocks(0u) == (opts.max_blocks_per_chunk-1u));
|
||||
}
|
||||
}
|
||||
BOOST_TEST(mrl.m_mismatches == 0u);
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
|
||||
//Now test max block per chunk
|
||||
{
|
||||
pool_options opts;
|
||||
//so after max_blocks_per_chunk*2-1 allocations, all new chunks must hold max_blocks_per_chunk blocks
|
||||
opts.max_blocks_per_chunk = 32u;
|
||||
derived_from_pool_resource<PoolResource> dmbr(opts, &mrl);
|
||||
{
|
||||
std::size_t loops = opts.max_blocks_per_chunk*2-1u;
|
||||
while(loops--){
|
||||
dmbr.do_allocate(1, 1);
|
||||
}
|
||||
//pool array + log2(max_blocks_per_chunk)+1 chunks (sizes [1, 2, 4, ...])
|
||||
BOOST_TEST(dmbr.pool_next_blocks_per_chunk(0u) == opts.max_blocks_per_chunk);
|
||||
const std::size_t num_chunks = bi::detail::floor_log2(opts.max_blocks_per_chunk)+1u;
|
||||
BOOST_TEST(mrl.m_info.size() == 1u + num_chunks);
|
||||
//Next allocation should allocate max_blocks_per_chunk blocks in a chunk so max_blocks_per_chunk-1 should remain free
|
||||
dmbr.do_allocate(1, 1);
|
||||
BOOST_TEST(dmbr.pool_next_blocks_per_chunk(0u) == opts.max_blocks_per_chunk);
|
||||
BOOST_TEST(mrl.m_info.size() == 1u + num_chunks + 1u);
|
||||
BOOST_TEST(dmbr.pool_cached_blocks(0u) == (opts.max_blocks_per_chunk-1u));
|
||||
}
|
||||
}
|
||||
BOOST_TEST(mrl.m_mismatches == 0u);
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
|
||||
//Now test different pool sizes
|
||||
{
|
||||
pool_options opts;
|
||||
//so after max_blocks_per_chunk*2-1 allocations, all new chunks must hold max_blocks_per_chunk blocks
|
||||
opts.max_blocks_per_chunk = 1u;
|
||||
derived_from_pool_resource<PoolResource> dmbr(opts, &mrl);
|
||||
const pool_options &final_opts = dmbr.options();
|
||||
|
||||
//Force pool creation
|
||||
dmbr.do_deallocate(dmbr.do_allocate(1, 1), 1, 1);
|
||||
//pool array plus first pool's chunk allocation
|
||||
BOOST_TEST(mrl.m_info.size() == 2u);
|
||||
//pool count must be:
|
||||
// log2(the maximum block) - log2(the minimum block) + 1. Example if minimum block is 8, and maximum 32:
|
||||
// log(32) - log2(8) + 1u = 3 pools (block sizes: 8, 16, and 32)
|
||||
const std::size_t minimum_size = dmbr.pool_block(0u);
|
||||
const std::size_t maximum_size = final_opts.largest_required_pool_block;
|
||||
BOOST_TEST(dmbr.pool_count() == (1u + bi::detail::floor_log2(maximum_size) - bi::detail::floor_log2(minimum_size)));
|
||||
for(std::size_t i = 0, s = minimum_size, max = dmbr.pool_count(); i != max; ++i, s*=2){
|
||||
//Except in the first pool, each cache should be empty
|
||||
BOOST_TEST(dmbr.pool_cached_blocks(i) == std::size_t(i == 0));
|
||||
dmbr.do_deallocate(dmbr.do_allocate(s/2+1, 1), s/2+1, 1);
|
||||
dmbr.do_deallocate(dmbr.do_allocate(s-1, 1), s-1, 1);
|
||||
dmbr.do_deallocate(dmbr.do_allocate(s, 1), s, 1);
|
||||
//pool array plus each previous chunk allocation
|
||||
BOOST_TEST(mrl.m_info.size() == (1u + i + 1u));
|
||||
//as we limited max_blocks_per_chunk to 1, no cached blocks should be available except one
|
||||
BOOST_TEST(dmbr.pool_cached_blocks(i) == 1u);
|
||||
}
|
||||
//Now test out of maximum values, which should go directly to upstream
|
||||
//it should be directly deallocated.
|
||||
void *p = dmbr.do_allocate(maximum_size+1, 1);
|
||||
BOOST_TEST(mrl.m_info.size() == (1u + dmbr.pool_count() + 1u));
|
||||
dmbr.do_deallocate(p, maximum_size+1, 1);
|
||||
BOOST_TEST(mrl.m_info.size() == (1u + dmbr.pool_count()));
|
||||
}
|
||||
BOOST_TEST(mrl.m_mismatches == 0u);
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
}
|
||||
|
||||
template<class PoolResource>
|
||||
void test_do_is_equal()
|
||||
{
|
||||
//`this == dynamic_cast<const PoolResource*>(&other)`.
|
||||
memory_resource_logger mrl;
|
||||
derived_from_pool_resource<PoolResource> dmbr(&mrl);
|
||||
derived_from_pool_resource<PoolResource> dmbr2(&mrl);
|
||||
BOOST_TEST(true == dmbr.do_is_equal(dmbr));
|
||||
BOOST_TEST(false == dmbr.do_is_equal(dmbr2));
|
||||
//A different type should be always different
|
||||
derived_from_memory_resource dmr;
|
||||
BOOST_TEST(false == dmbr.do_is_equal(dmr));
|
||||
}
|
||||
|
||||
template<class PoolResource>
|
||||
void test_release()
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
{
|
||||
pool_options opts;
|
||||
//so after max_blocks_per_chunk*2-1 allocations, all new chunks must hold max_blocks_per_chunk blocks
|
||||
opts.max_blocks_per_chunk = 4u;
|
||||
derived_from_pool_resource<PoolResource> dmbr(opts, &mrl);
|
||||
const pool_options &final_opts = dmbr.options();
|
||||
const std::size_t minimum_size = dmbr.pool_block(0u);
|
||||
const std::size_t maximum_size = final_opts.largest_required_pool_block;
|
||||
const std::size_t pool_count = 1u + bi::detail::floor_log2(maximum_size) - bi::detail::floor_log2(minimum_size);
|
||||
|
||||
std::size_t expected_memory_allocs = 0;
|
||||
for(std::size_t i = 0, imax = pool_count, s = minimum_size; i != imax; s*=2, ++i){
|
||||
for(std::size_t j = 0, j_max = opts.max_blocks_per_chunk*2u-1u; j != j_max; ++j){
|
||||
dmbr.do_allocate(s, 1);
|
||||
}
|
||||
//One due to the pool array, and for each pool, log2(max_blocks_per_chunk)+1 allocations
|
||||
expected_memory_allocs = 1 + (bid::floor_log2(opts.max_blocks_per_chunk) + 1u)*(i+1);
|
||||
//pool array plus each previous chunk allocation
|
||||
BOOST_TEST(mrl.m_info.size() == expected_memory_allocs);
|
||||
}
|
||||
//Now with out-of-pool sizes
|
||||
for(std::size_t j = 0, j_max = opts.max_blocks_per_chunk*2u-1u; j != j_max; ++j){
|
||||
dmbr.do_allocate(maximum_size+1, 1);
|
||||
BOOST_TEST(mrl.m_info.size() == ++expected_memory_allocs);
|
||||
}
|
||||
//Now release memory and check all memory allocated through do_allocate was deallocated to upstream
|
||||
dmbr.release();
|
||||
BOOST_TEST(mrl.m_info.size() == 1u);
|
||||
}
|
||||
BOOST_TEST(mrl.m_mismatches == 0u);
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
}
|
||||
|
||||
template<class PoolResource>
|
||||
void test_destructor()
|
||||
{
|
||||
memory_resource_logger mrl;
|
||||
{
|
||||
pool_options opts;
|
||||
//so after max_blocks_per_chunk*2-1 allocations, all new chunks must hold max_blocks_per_chunk blocks
|
||||
opts.max_blocks_per_chunk = 4u;
|
||||
derived_from_pool_resource<PoolResource> dmbr(opts, &mrl);
|
||||
const pool_options &final_opts = dmbr.options();
|
||||
const std::size_t minimum_size = dmbr.pool_block(0u);
|
||||
const std::size_t maximum_size = final_opts.largest_required_pool_block;
|
||||
const std::size_t pool_count = 1u + bi::detail::floor_log2(maximum_size) - bi::detail::floor_log2(minimum_size);
|
||||
|
||||
std::size_t expected_memory_allocs = 0;
|
||||
for(std::size_t i = 0, imax = pool_count, s = minimum_size; i != imax; s*=2, ++i){
|
||||
for(std::size_t j = 0, j_max = opts.max_blocks_per_chunk*2u-1u; j != j_max; ++j){
|
||||
dmbr.do_allocate(s, 1);
|
||||
}
|
||||
//One due to the pool array, and for each pool, log2(max_blocks_per_chunk)+1 allocations
|
||||
expected_memory_allocs = 1 + (bid::floor_log2(opts.max_blocks_per_chunk) + 1u)*(i+1);
|
||||
//pool array plus each previous chunk allocation
|
||||
BOOST_TEST(mrl.m_info.size() == expected_memory_allocs);
|
||||
}
|
||||
//Now with out-of-pool sizes
|
||||
for(std::size_t j = 0, j_max = opts.max_blocks_per_chunk*2u-1u; j != j_max; ++j){
|
||||
dmbr.do_allocate(maximum_size+1, 1);
|
||||
BOOST_TEST(mrl.m_info.size() == ++expected_memory_allocs);
|
||||
}
|
||||
//Don't release, all memory, including internal allocations, should be automatically
|
||||
//after the destructor is run
|
||||
}
|
||||
BOOST_TEST(mrl.m_mismatches == 0u);
|
||||
BOOST_TEST(mrl.m_info.size() == 0u);
|
||||
}
|
||||
|
||||
|
||||
template<class PoolResource>
|
||||
void test_pool_resource()
|
||||
{
|
||||
test_options_upstream_constructor<PoolResource>();
|
||||
test_default_constructor<PoolResource>();
|
||||
test_upstream_constructor<PoolResource>();
|
||||
test_options_constructor<PoolResource>();
|
||||
test_options<PoolResource>();
|
||||
test_do_allocate_deallocate<PoolResource>();
|
||||
test_do_is_equal<PoolResource>();
|
||||
test_release<PoolResource>();
|
||||
test_destructor<PoolResource>();
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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_ALLOCATOR_ARGUMENT_TESTER_HPP
|
||||
#define BOOST_CONTAINER_TEST_ALLOCATOR_ARGUMENT_TESTER_HPP
|
||||
|
||||
#include <boost/container/uses_allocator.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/container/pmr/polymorphic_allocator.hpp>
|
||||
|
||||
|
||||
template<class T, unsigned int Id, bool HasTrueTypes = false>
|
||||
class propagation_test_allocator
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(propagation_test_allocator)
|
||||
public:
|
||||
|
||||
template<class U>
|
||||
struct rebind
|
||||
{
|
||||
typedef propagation_test_allocator<U, Id, HasTrueTypes> other;
|
||||
};
|
||||
|
||||
typedef boost::container::container_detail::bool_<HasTrueTypes> propagate_on_container_copy_assignment;
|
||||
typedef boost::container::container_detail::bool_<HasTrueTypes> propagate_on_container_move_assignment;
|
||||
typedef boost::container::container_detail::bool_<HasTrueTypes> propagate_on_container_swap;
|
||||
typedef boost::container::container_detail::bool_<HasTrueTypes> is_always_equal;
|
||||
typedef T value_type;
|
||||
|
||||
propagation_test_allocator()
|
||||
: m_default_contructed(true), m_move_contructed(false), m_move_assigned(false)
|
||||
{}
|
||||
|
||||
propagation_test_allocator(const propagation_test_allocator&)
|
||||
: m_default_contructed(false), m_move_contructed(false), m_move_assigned(false)
|
||||
{}
|
||||
|
||||
propagation_test_allocator(BOOST_RV_REF(propagation_test_allocator) )
|
||||
: m_default_contructed(false), m_move_contructed(true), m_move_assigned(false)
|
||||
{}
|
||||
|
||||
template<class U>
|
||||
propagation_test_allocator(BOOST_RV_REF_BEG propagation_test_allocator<U, Id, HasTrueTypes> BOOST_RV_REF_END)
|
||||
: m_default_contructed(false), m_move_contructed(true), m_move_assigned(false)
|
||||
{}
|
||||
|
||||
template<class U>
|
||||
propagation_test_allocator(const propagation_test_allocator<U, Id, HasTrueTypes> &)
|
||||
{}
|
||||
|
||||
propagation_test_allocator & operator=(BOOST_COPY_ASSIGN_REF(propagation_test_allocator))
|
||||
{ return *this; }
|
||||
|
||||
propagation_test_allocator & operator=(BOOST_RV_REF(propagation_test_allocator))
|
||||
{
|
||||
m_move_assigned = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::size_t max_size() const
|
||||
{ return std::size_t(-1); }
|
||||
|
||||
T* allocate(std::size_t n)
|
||||
{ return (T*)::new char[n*sizeof(T)]; }
|
||||
|
||||
void deallocate(T*p, std::size_t)
|
||||
{ delete []static_cast<char*>(static_cast<void*>(p)); }
|
||||
|
||||
bool m_default_contructed;
|
||||
bool m_move_contructed;
|
||||
bool m_move_assigned;
|
||||
};
|
||||
|
||||
template <class T1, class T2, unsigned int Id, bool HasTrueTypes>
|
||||
bool operator==( const propagation_test_allocator<T1, Id, HasTrueTypes>&
|
||||
, const propagation_test_allocator<T2, Id, HasTrueTypes>&)
|
||||
{ return true; }
|
||||
|
||||
template <class T1, class T2, unsigned int Id, bool HasTrueTypes>
|
||||
bool operator!=( const propagation_test_allocator<T1, Id, HasTrueTypes>&
|
||||
, const propagation_test_allocator<T2, Id, HasTrueTypes>&)
|
||||
{ return false; }
|
||||
|
||||
//This enum lists the construction options
|
||||
//for an allocator-aware type
|
||||
enum ConstructionTypeEnum
|
||||
{
|
||||
ConstructiblePrefix,
|
||||
ConstructibleSuffix,
|
||||
ErasedTypePrefix,
|
||||
ErasedTypeSuffix,
|
||||
NotUsesAllocator
|
||||
};
|
||||
|
||||
//This base class provices types for
|
||||
//the derived class to implement each construction
|
||||
//type. If a construction type does not apply
|
||||
//the typedef is set to an internal nat
|
||||
//so that the class is not constructible from
|
||||
//the user arguments.
|
||||
template<ConstructionTypeEnum ConstructionType, unsigned int AllocatorTag>
|
||||
struct uses_allocator_base;
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct uses_allocator_base<ConstructibleSuffix, AllocatorTag>
|
||||
{
|
||||
typedef propagation_test_allocator<int, AllocatorTag> allocator_type;
|
||||
typedef allocator_type allocator_constructor_type;
|
||||
struct nat{};
|
||||
typedef nat allocator_arg_type;
|
||||
};
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct uses_allocator_base<ConstructiblePrefix, AllocatorTag>
|
||||
{
|
||||
typedef propagation_test_allocator<int, AllocatorTag> allocator_type;
|
||||
typedef allocator_type allocator_constructor_type;
|
||||
typedef boost::container::allocator_arg_t allocator_arg_type;
|
||||
};
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct uses_allocator_base<ErasedTypePrefix, AllocatorTag>
|
||||
{
|
||||
typedef boost::container::erased_type allocator_type;
|
||||
typedef boost::container::pmr::polymorphic_allocator<int> allocator_constructor_type;
|
||||
typedef boost::container::allocator_arg_t allocator_arg_type;
|
||||
};
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct uses_allocator_base<ErasedTypeSuffix, AllocatorTag>
|
||||
{
|
||||
typedef boost::container::erased_type allocator_type;
|
||||
typedef boost::container::pmr::polymorphic_allocator<int> allocator_constructor_type;
|
||||
struct nat{};
|
||||
typedef nat allocator_arg_type;
|
||||
};
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct uses_allocator_base<NotUsesAllocator, AllocatorTag>
|
||||
{
|
||||
struct nat{};
|
||||
typedef nat allocator_constructor_type;
|
||||
typedef nat allocator_arg_type;
|
||||
};
|
||||
|
||||
template<ConstructionTypeEnum ConstructionType, unsigned int AllocatorTag>
|
||||
struct allocator_argument_tester
|
||||
: uses_allocator_base<ConstructionType, AllocatorTag>
|
||||
{
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(allocator_argument_tester)
|
||||
|
||||
public:
|
||||
|
||||
typedef uses_allocator_base<ConstructionType, AllocatorTag> base_type;
|
||||
|
||||
//0 user argument constructors
|
||||
allocator_argument_tester()
|
||||
: construction_type(NotUsesAllocator), value(0)
|
||||
{}
|
||||
|
||||
explicit allocator_argument_tester
|
||||
(typename base_type::allocator_constructor_type)
|
||||
: construction_type(ConstructibleSuffix), value(0)
|
||||
{}
|
||||
|
||||
explicit allocator_argument_tester
|
||||
(typename base_type::allocator_arg_type, typename base_type::allocator_constructor_type)
|
||||
: construction_type(ConstructiblePrefix), value(0)
|
||||
{}
|
||||
|
||||
//1 user argument constructors
|
||||
explicit allocator_argument_tester(int i)
|
||||
: construction_type(NotUsesAllocator), value(i)
|
||||
{}
|
||||
|
||||
allocator_argument_tester
|
||||
(int i, typename base_type::allocator_constructor_type)
|
||||
: construction_type(ConstructibleSuffix), value(i)
|
||||
{}
|
||||
|
||||
allocator_argument_tester
|
||||
( typename base_type::allocator_arg_type
|
||||
, typename base_type::allocator_constructor_type
|
||||
, int i)
|
||||
: construction_type(ConstructiblePrefix), value(i)
|
||||
{}
|
||||
|
||||
//Copy constructors
|
||||
allocator_argument_tester(const allocator_argument_tester &other)
|
||||
: construction_type(NotUsesAllocator), value(other.value)
|
||||
{}
|
||||
|
||||
allocator_argument_tester( const allocator_argument_tester &other
|
||||
, typename base_type::allocator_constructor_type)
|
||||
: construction_type(ConstructibleSuffix), value(other.value)
|
||||
{}
|
||||
|
||||
allocator_argument_tester( typename base_type::allocator_arg_type
|
||||
, typename base_type::allocator_constructor_type
|
||||
, const allocator_argument_tester &other)
|
||||
: construction_type(ConstructiblePrefix), value(other.value)
|
||||
{}
|
||||
|
||||
//Move constructors
|
||||
allocator_argument_tester(BOOST_RV_REF(allocator_argument_tester) other)
|
||||
: construction_type(NotUsesAllocator), value(other.value)
|
||||
{ other.value = 0; other.construction_type = NotUsesAllocator; }
|
||||
|
||||
allocator_argument_tester( BOOST_RV_REF(allocator_argument_tester) other
|
||||
, typename base_type::allocator_constructor_type)
|
||||
: construction_type(ConstructibleSuffix), value(other.value)
|
||||
{ other.value = 0; other.construction_type = ConstructibleSuffix; }
|
||||
|
||||
allocator_argument_tester( typename base_type::allocator_arg_type
|
||||
, typename base_type::allocator_constructor_type
|
||||
, BOOST_RV_REF(allocator_argument_tester) other)
|
||||
: construction_type(ConstructiblePrefix), value(other.value)
|
||||
{ other.value = 0; other.construction_type = ConstructiblePrefix; }
|
||||
|
||||
ConstructionTypeEnum construction_type;
|
||||
int value;
|
||||
};
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct constructible_with_allocator_prefix
|
||||
< ::allocator_argument_tester<ConstructiblePrefix, AllocatorTag> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct constructible_with_allocator_prefix
|
||||
< ::allocator_argument_tester<ErasedTypePrefix, AllocatorTag> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct constructible_with_allocator_suffix
|
||||
< ::allocator_argument_tester<ConstructibleSuffix, AllocatorTag> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct constructible_with_allocator_suffix
|
||||
< ::allocator_argument_tester<ErasedTypeSuffix, AllocatorTag> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //BOOST_CONTAINER_TEST_ALLOCATOR_ARGUMENT_TESTER_HPP
|
||||
@@ -0,0 +1,186 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/resource_adaptor.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include "propagation_test_allocator.hpp"
|
||||
#include "derived_from_memory_resource.hpp"
|
||||
|
||||
using namespace boost::container::pmr;
|
||||
|
||||
void test_default_constructor()
|
||||
{
|
||||
typedef propagation_test_allocator<char, 0> alloc_t;
|
||||
resource_adaptor<alloc_t> ra;
|
||||
BOOST_TEST(ra.get_allocator().m_default_contructed == true);
|
||||
}
|
||||
|
||||
void test_copy_constructor()
|
||||
{
|
||||
typedef propagation_test_allocator<char, 0> alloc_t;
|
||||
resource_adaptor<alloc_t> ra;
|
||||
BOOST_TEST(ra.get_allocator().m_default_contructed == true);
|
||||
resource_adaptor<alloc_t> rb(ra);
|
||||
BOOST_TEST(rb.get_allocator().m_default_contructed == false);
|
||||
BOOST_TEST(rb.get_allocator().m_move_contructed == false);
|
||||
}
|
||||
|
||||
void test_move_constructor()
|
||||
{
|
||||
typedef propagation_test_allocator<char, 0> alloc_t;
|
||||
resource_adaptor<alloc_t> ra;
|
||||
BOOST_TEST(ra.get_allocator().m_default_contructed == true);
|
||||
resource_adaptor<alloc_t> rb(::boost::move(ra));
|
||||
BOOST_TEST(rb.get_allocator().m_default_contructed == false);
|
||||
BOOST_TEST(rb.get_allocator().m_move_contructed == true);
|
||||
}
|
||||
|
||||
void test_lvalue_alloc_constructor()
|
||||
{
|
||||
typedef propagation_test_allocator<char, 0> alloc_t;
|
||||
alloc_t a;
|
||||
resource_adaptor<alloc_t> ra(a);
|
||||
BOOST_TEST(ra.get_allocator().m_default_contructed == false);
|
||||
BOOST_TEST(ra.get_allocator().m_move_contructed == false);
|
||||
}
|
||||
|
||||
void test_rvalue_alloc_constructor()
|
||||
{
|
||||
typedef propagation_test_allocator<char, 0> alloc_t;
|
||||
alloc_t a;
|
||||
resource_adaptor<alloc_t> ra(::boost::move(a));
|
||||
BOOST_TEST(ra.get_allocator().m_default_contructed == false);
|
||||
BOOST_TEST(ra.get_allocator().m_move_contructed == true);
|
||||
}
|
||||
|
||||
void test_copy_assign()
|
||||
{
|
||||
typedef propagation_test_allocator<char, 0> alloc_t;
|
||||
resource_adaptor<alloc_t> ra;
|
||||
BOOST_TEST(ra.get_allocator().m_default_contructed == true);
|
||||
resource_adaptor<alloc_t> rb;
|
||||
BOOST_TEST(ra.get_allocator().m_default_contructed == true);
|
||||
rb = ra;
|
||||
BOOST_TEST(rb.get_allocator().m_move_contructed == false);
|
||||
BOOST_TEST(rb.get_allocator().m_move_assigned == false);
|
||||
}
|
||||
|
||||
void test_move_assign()
|
||||
{
|
||||
typedef propagation_test_allocator<char, 0> alloc_t;
|
||||
resource_adaptor<alloc_t> ra;
|
||||
BOOST_TEST(ra.get_allocator().m_default_contructed == true);
|
||||
resource_adaptor<alloc_t> rb;
|
||||
BOOST_TEST(ra.get_allocator().m_default_contructed == true);
|
||||
rb = ::boost::move(ra);
|
||||
BOOST_TEST(rb.get_allocator().m_move_contructed == false);
|
||||
BOOST_TEST(rb.get_allocator().m_move_assigned == true);
|
||||
}
|
||||
|
||||
struct stateful
|
||||
{
|
||||
public:
|
||||
typedef char value_type;
|
||||
|
||||
template<class U>
|
||||
struct rebind
|
||||
{ typedef stateful other; };
|
||||
|
||||
char *allocate(std::size_t n)
|
||||
{ allocate_size = n; return allocate_return; }
|
||||
|
||||
void deallocate(char *p, std::size_t n)
|
||||
{ deallocate_p = p; deallocate_size = n; }
|
||||
|
||||
friend bool operator==(const stateful &l, const stateful &r)
|
||||
{ return l.m_u == r.m_u; }
|
||||
|
||||
friend bool operator!=(const stateful &l, const stateful &r)
|
||||
{ return l.m_u != r.m_u; }
|
||||
|
||||
public:
|
||||
unsigned m_u;
|
||||
std::size_t allocate_size;
|
||||
char *allocate_return;
|
||||
std::size_t deallocate_size;
|
||||
char *deallocate_p;
|
||||
};
|
||||
|
||||
void test_get_allocator()
|
||||
{
|
||||
stateful a;
|
||||
a.m_u = 999;
|
||||
resource_adaptor<stateful> ra(a);
|
||||
const resource_adaptor<stateful> & cra = ra;
|
||||
BOOST_TEST( ra.get_allocator().m_u == 999);
|
||||
BOOST_TEST(cra.get_allocator().m_u == 999);
|
||||
}
|
||||
|
||||
typedef resource_adaptor<stateful> stateful_resource_adaptor_t;
|
||||
|
||||
struct derived_from_resource_adaptor_stateful
|
||||
: public stateful_resource_adaptor_t
|
||||
{
|
||||
public:
|
||||
typedef stateful_resource_adaptor_t base_t;
|
||||
using base_t::do_allocate;
|
||||
using base_t::do_deallocate;
|
||||
using base_t::do_is_equal;
|
||||
};
|
||||
|
||||
void test_do_allocate()
|
||||
{
|
||||
derived_from_resource_adaptor_stateful dra;
|
||||
char dummy = 0;
|
||||
dra.get_allocator().allocate_return = &dummy;
|
||||
void *allocate_ret = dra.do_allocate(998, 1234);
|
||||
BOOST_TEST(allocate_ret == &dummy);
|
||||
BOOST_TEST(dra.get_allocator().allocate_size == 998);
|
||||
}
|
||||
|
||||
void test_do_deallocate()
|
||||
{
|
||||
derived_from_resource_adaptor_stateful dra;
|
||||
char dummy = 0;
|
||||
dra.do_deallocate(&dummy, 1234, 753);
|
||||
BOOST_TEST(dra.get_allocator().deallocate_p == &dummy);
|
||||
BOOST_TEST(dra.get_allocator().deallocate_size == 1234);
|
||||
}
|
||||
|
||||
void test_do_is_equal()
|
||||
{
|
||||
derived_from_resource_adaptor_stateful dra;
|
||||
derived_from_memory_resource dmr;
|
||||
//Different dynamic type must return false
|
||||
BOOST_TEST(dra.do_is_equal(dmr) == false);
|
||||
|
||||
//Same dynamic type with same state must return true
|
||||
derived_from_resource_adaptor_stateful dra2;
|
||||
BOOST_TEST(dra.do_is_equal(dra2) == true);
|
||||
|
||||
//Same dynamic type with different state must return false
|
||||
dra2.get_allocator().m_u = 1234;
|
||||
BOOST_TEST(dra.do_is_equal(dra2) == false);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_default_constructor();
|
||||
test_copy_constructor();
|
||||
test_move_constructor();
|
||||
test_lvalue_alloc_constructor();
|
||||
test_rvalue_alloc_constructor();
|
||||
test_copy_assign();
|
||||
test_move_assign();
|
||||
test_get_allocator();
|
||||
test_do_allocate();
|
||||
test_do_deallocate();
|
||||
test_do_is_equal();
|
||||
return ::boost::report_errors();
|
||||
}
|
||||
@@ -19,81 +19,7 @@
|
||||
#include <memory>
|
||||
#include <cstddef>
|
||||
|
||||
using namespace boost::container;
|
||||
|
||||
template<class T, unsigned int Id, bool HasTrueTypes = false>
|
||||
class test_allocator
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(test_allocator)
|
||||
public:
|
||||
|
||||
template<class U>
|
||||
struct rebind
|
||||
{
|
||||
typedef test_allocator<U, Id, HasTrueTypes> other;
|
||||
};
|
||||
|
||||
typedef container_detail::bool_<HasTrueTypes> propagate_on_container_copy_assignment;
|
||||
typedef container_detail::bool_<HasTrueTypes> propagate_on_container_move_assignment;
|
||||
typedef container_detail::bool_<HasTrueTypes> propagate_on_container_swap;
|
||||
typedef container_detail::bool_<HasTrueTypes> is_always_equal;
|
||||
typedef T value_type;
|
||||
|
||||
test_allocator()
|
||||
: m_move_contructed(false), m_move_assigned(false)
|
||||
{}
|
||||
|
||||
test_allocator(const test_allocator&)
|
||||
: m_move_contructed(false), m_move_assigned(false)
|
||||
{}
|
||||
|
||||
test_allocator(BOOST_RV_REF(test_allocator) )
|
||||
: m_move_contructed(true), m_move_assigned(false)
|
||||
{}
|
||||
|
||||
template<class U>
|
||||
test_allocator(BOOST_RV_REF_BEG test_allocator<U, Id, HasTrueTypes> BOOST_RV_REF_END)
|
||||
: m_move_contructed(true), m_move_assigned(false)
|
||||
{}
|
||||
|
||||
template<class U>
|
||||
test_allocator(const test_allocator<U, Id, HasTrueTypes> &)
|
||||
{}
|
||||
|
||||
test_allocator & operator=(BOOST_COPY_ASSIGN_REF(test_allocator))
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
test_allocator & operator=(BOOST_RV_REF(test_allocator))
|
||||
{
|
||||
m_move_assigned = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::size_t max_size() const
|
||||
{ return std::size_t(-1); }
|
||||
|
||||
T* allocate(std::size_t n)
|
||||
{ return (T*)::new char[n*sizeof(T)]; }
|
||||
|
||||
void deallocate(T*p, std::size_t)
|
||||
{ delete []static_cast<char*>(static_cast<void*>(p)); }
|
||||
|
||||
bool m_move_contructed;
|
||||
bool m_move_assigned;
|
||||
};
|
||||
|
||||
template <class T1, class T2, unsigned int Id, bool HasTrueTypes>
|
||||
bool operator==( const test_allocator<T1, Id, HasTrueTypes>&
|
||||
, const test_allocator<T2, Id, HasTrueTypes>&)
|
||||
{ return true; }
|
||||
|
||||
template <class T1, class T2, unsigned int Id, bool HasTrueTypes>
|
||||
bool operator!=( const test_allocator<T1, Id, HasTrueTypes>&
|
||||
, const test_allocator<T2, Id, HasTrueTypes>&)
|
||||
{ return false; }
|
||||
|
||||
#include "allocator_argument_tester.hpp"
|
||||
|
||||
template<unsigned int Type>
|
||||
struct tagged_integer
|
||||
@@ -113,148 +39,6 @@ struct mark_on_destructor
|
||||
bool destroyed;
|
||||
};
|
||||
|
||||
//This enum lists the construction options
|
||||
//for an allocator-aware type
|
||||
enum ConstructionTypeEnum
|
||||
{
|
||||
ConstructiblePrefix,
|
||||
ConstructibleSuffix,
|
||||
NotUsesAllocator
|
||||
};
|
||||
|
||||
//This base class provices types for
|
||||
//the derived class to implement each construction
|
||||
//type. If a construction type does not apply
|
||||
//the typedef is set to an internal nat
|
||||
//so that the class is not constructible from
|
||||
//the user arguments.
|
||||
template<ConstructionTypeEnum ConstructionType, unsigned int AllocatorTag>
|
||||
struct uses_allocator_base;
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct uses_allocator_base<ConstructibleSuffix, AllocatorTag>
|
||||
{
|
||||
typedef test_allocator<int, AllocatorTag> allocator_type;
|
||||
typedef allocator_type allocator_constructor_type;
|
||||
struct nat{};
|
||||
typedef nat allocator_arg_type;
|
||||
};
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct uses_allocator_base<ConstructiblePrefix, AllocatorTag>
|
||||
{
|
||||
typedef test_allocator<int, AllocatorTag> allocator_type;
|
||||
typedef allocator_type allocator_constructor_type;
|
||||
typedef allocator_arg_t allocator_arg_type;
|
||||
};
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct uses_allocator_base<NotUsesAllocator, AllocatorTag>
|
||||
{
|
||||
struct nat{};
|
||||
typedef nat allocator_constructor_type;
|
||||
typedef nat allocator_arg_type;
|
||||
};
|
||||
|
||||
template<ConstructionTypeEnum ConstructionType, unsigned int AllocatorTag>
|
||||
struct mark_on_scoped_allocation
|
||||
: uses_allocator_base<ConstructionType, AllocatorTag>
|
||||
{
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(mark_on_scoped_allocation)
|
||||
|
||||
public:
|
||||
|
||||
typedef uses_allocator_base<ConstructionType, AllocatorTag> base_type;
|
||||
|
||||
//0 user argument constructors
|
||||
mark_on_scoped_allocation()
|
||||
: construction_type(NotUsesAllocator), value(0)
|
||||
{}
|
||||
|
||||
explicit mark_on_scoped_allocation
|
||||
(typename base_type::allocator_constructor_type)
|
||||
: construction_type(ConstructibleSuffix), value(0)
|
||||
{}
|
||||
|
||||
explicit mark_on_scoped_allocation
|
||||
(typename base_type::allocator_arg_type, typename base_type::allocator_constructor_type)
|
||||
: construction_type(ConstructiblePrefix), value(0)
|
||||
{}
|
||||
|
||||
//1 user argument constructors
|
||||
explicit mark_on_scoped_allocation(int i)
|
||||
: construction_type(NotUsesAllocator), value(i)
|
||||
{}
|
||||
|
||||
mark_on_scoped_allocation
|
||||
(int i, typename base_type::allocator_constructor_type)
|
||||
: construction_type(ConstructibleSuffix), value(i)
|
||||
{}
|
||||
|
||||
mark_on_scoped_allocation
|
||||
( typename base_type::allocator_arg_type
|
||||
, typename base_type::allocator_constructor_type
|
||||
, int i)
|
||||
: construction_type(ConstructiblePrefix), value(i)
|
||||
{}
|
||||
|
||||
//Copy constructors
|
||||
mark_on_scoped_allocation(const mark_on_scoped_allocation &other)
|
||||
: construction_type(NotUsesAllocator), value(other.value)
|
||||
{}
|
||||
|
||||
mark_on_scoped_allocation( const mark_on_scoped_allocation &other
|
||||
, typename base_type::allocator_constructor_type)
|
||||
: construction_type(ConstructibleSuffix), value(other.value)
|
||||
{}
|
||||
|
||||
mark_on_scoped_allocation( typename base_type::allocator_arg_type
|
||||
, typename base_type::allocator_constructor_type
|
||||
, const mark_on_scoped_allocation &other)
|
||||
: construction_type(ConstructiblePrefix), value(other.value)
|
||||
{}
|
||||
|
||||
//Move constructors
|
||||
mark_on_scoped_allocation(BOOST_RV_REF(mark_on_scoped_allocation) other)
|
||||
: construction_type(NotUsesAllocator), value(other.value)
|
||||
{ other.value = 0; other.construction_type = NotUsesAllocator; }
|
||||
|
||||
mark_on_scoped_allocation( BOOST_RV_REF(mark_on_scoped_allocation) other
|
||||
, typename base_type::allocator_constructor_type)
|
||||
: construction_type(ConstructibleSuffix), value(other.value)
|
||||
{ other.value = 0; other.construction_type = ConstructibleSuffix; }
|
||||
|
||||
mark_on_scoped_allocation( typename base_type::allocator_arg_type
|
||||
, typename base_type::allocator_constructor_type
|
||||
, BOOST_RV_REF(mark_on_scoped_allocation) other)
|
||||
: construction_type(ConstructiblePrefix), value(other.value)
|
||||
{ other.value = 0; other.construction_type = ConstructiblePrefix; }
|
||||
|
||||
ConstructionTypeEnum construction_type;
|
||||
int value;
|
||||
};
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct constructible_with_allocator_prefix
|
||||
< ::mark_on_scoped_allocation<ConstructiblePrefix, AllocatorTag> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<unsigned int AllocatorTag>
|
||||
struct constructible_with_allocator_suffix
|
||||
< ::mark_on_scoped_allocation<ConstructibleSuffix, AllocatorTag> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
#include <boost/container/scoped_allocator.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
@@ -263,19 +47,21 @@ struct constructible_with_allocator_suffix
|
||||
|
||||
int main()
|
||||
{
|
||||
typedef test_allocator<tagged_integer<0>, 0> OuterAlloc;
|
||||
typedef test_allocator<tagged_integer<0>, 10> Outer10IdAlloc;
|
||||
typedef test_allocator<tagged_integer<9>, 0> Rebound9OuterAlloc;
|
||||
typedef test_allocator<tagged_integer<1>, 1> InnerAlloc1;
|
||||
typedef test_allocator<tagged_integer<2>, 2> InnerAlloc2;
|
||||
typedef test_allocator<tagged_integer<1>, 11> Inner11IdAlloc1;
|
||||
using namespace boost::container;
|
||||
|
||||
typedef test_allocator<tagged_integer<0>, 0, false> OuterAllocFalseHasTrueTypes;
|
||||
typedef test_allocator<tagged_integer<0>, 0, true> OuterAllocTrueHasTrueTypes;
|
||||
typedef test_allocator<tagged_integer<1>, 1, false> InnerAlloc1FalseHasTrueTypes;
|
||||
typedef test_allocator<tagged_integer<1>, 1, true> InnerAlloc1TrueHasTrueTypes;
|
||||
typedef test_allocator<tagged_integer<2>, 2, false> InnerAlloc2FalseHasTrueTypes;
|
||||
typedef test_allocator<tagged_integer<2>, 2, true> InnerAlloc2TrueHasTrueTypes;
|
||||
typedef propagation_test_allocator<tagged_integer<0>, 0> OuterAlloc;
|
||||
typedef propagation_test_allocator<tagged_integer<0>, 10> Outer10IdAlloc;
|
||||
typedef propagation_test_allocator<tagged_integer<9>, 0> Rebound9OuterAlloc;
|
||||
typedef propagation_test_allocator<tagged_integer<1>, 1> InnerAlloc1;
|
||||
typedef propagation_test_allocator<tagged_integer<2>, 2> InnerAlloc2;
|
||||
typedef propagation_test_allocator<tagged_integer<1>, 11> Inner11IdAlloc1;
|
||||
|
||||
typedef propagation_test_allocator<tagged_integer<0>, 0, false> OuterAllocFalseHasTrueTypes;
|
||||
typedef propagation_test_allocator<tagged_integer<0>, 0, true> OuterAllocTrueHasTrueTypes;
|
||||
typedef propagation_test_allocator<tagged_integer<1>, 1, false> InnerAlloc1FalseHasTrueTypes;
|
||||
typedef propagation_test_allocator<tagged_integer<1>, 1, true> InnerAlloc1TrueHasTrueTypes;
|
||||
typedef propagation_test_allocator<tagged_integer<2>, 2, false> InnerAlloc2FalseHasTrueTypes;
|
||||
typedef propagation_test_allocator<tagged_integer<2>, 2, true> InnerAlloc2TrueHasTrueTypes;
|
||||
|
||||
//
|
||||
typedef scoped_allocator_adaptor< OuterAlloc > Scoped0Inner;
|
||||
@@ -301,81 +87,81 @@ int main()
|
||||
, InnerAlloc2 > Rebound9Scoped2Inner;
|
||||
|
||||
//outer_allocator_type
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< OuterAlloc
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< OuterAlloc
|
||||
, Scoped0Inner::outer_allocator_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< OuterAlloc
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< OuterAlloc
|
||||
, Scoped1Inner::outer_allocator_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< OuterAlloc
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< OuterAlloc
|
||||
, Scoped2Inner::outer_allocator_type>::value ));
|
||||
//value_type
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::value_type
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::value_type
|
||||
, Scoped0Inner::value_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::value_type
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::value_type
|
||||
, Scoped1Inner::value_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::value_type
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::value_type
|
||||
, Scoped2Inner::value_type>::value ));
|
||||
//size_type
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::size_type
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::size_type
|
||||
, Scoped0Inner::size_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::size_type
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::size_type
|
||||
, Scoped1Inner::size_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::size_type
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::size_type
|
||||
, Scoped2Inner::size_type>::value ));
|
||||
|
||||
//difference_type
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::difference_type
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::difference_type
|
||||
, Scoped0Inner::difference_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::difference_type
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::difference_type
|
||||
, Scoped1Inner::difference_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::difference_type
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::difference_type
|
||||
, Scoped2Inner::difference_type>::value ));
|
||||
|
||||
//pointer
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::pointer
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::pointer
|
||||
, Scoped0Inner::pointer>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::pointer
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::pointer
|
||||
, Scoped1Inner::pointer>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::pointer
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::pointer
|
||||
, Scoped2Inner::pointer>::value ));
|
||||
|
||||
//const_pointer
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::const_pointer
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::const_pointer
|
||||
, Scoped0Inner::const_pointer>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::const_pointer
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::const_pointer
|
||||
, Scoped1Inner::const_pointer>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::const_pointer
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::const_pointer
|
||||
, Scoped2Inner::const_pointer>::value ));
|
||||
|
||||
//void_pointer
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::void_pointer
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::void_pointer
|
||||
, Scoped0Inner::void_pointer>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::void_pointer
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::void_pointer
|
||||
, Scoped1Inner::void_pointer>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::void_pointer
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::void_pointer
|
||||
, Scoped2Inner::void_pointer>::value ));
|
||||
|
||||
//const_void_pointer
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::const_void_pointer
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::const_void_pointer
|
||||
, Scoped0Inner::const_void_pointer>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::const_void_pointer
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::const_void_pointer
|
||||
, Scoped1Inner::const_void_pointer>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits<OuterAlloc>::const_void_pointer
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< allocator_traits<OuterAlloc>::const_void_pointer
|
||||
, Scoped2Inner::const_void_pointer>::value ));
|
||||
|
||||
//rebind
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same<Scoped0Inner::rebind< tagged_integer<9> >::other
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same<Scoped0Inner::rebind< tagged_integer<9> >::other
|
||||
, Rebound9Scoped0Inner >::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same<Scoped1Inner::rebind< tagged_integer<9> >::other
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same<Scoped1Inner::rebind< tagged_integer<9> >::other
|
||||
, Rebound9Scoped1Inner >::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same<Scoped2Inner::rebind< tagged_integer<9> >::other
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same<Scoped2Inner::rebind< tagged_integer<9> >::other
|
||||
, Rebound9Scoped2Inner >::value ));
|
||||
|
||||
//inner_allocator_type
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< Scoped0Inner
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< Scoped0Inner
|
||||
, Scoped0Inner::inner_allocator_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< scoped_allocator_adaptor<InnerAlloc1>
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< scoped_allocator_adaptor<InnerAlloc1>
|
||||
, Scoped1Inner::inner_allocator_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< scoped_allocator_adaptor<InnerAlloc1, InnerAlloc2>
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same< scoped_allocator_adaptor<InnerAlloc1, InnerAlloc2>
|
||||
, Scoped2Inner::inner_allocator_type>::value ));
|
||||
|
||||
{
|
||||
@@ -746,7 +532,7 @@ int main()
|
||||
}
|
||||
|
||||
{
|
||||
vector<int, scoped_allocator_adaptor< test_allocator<int, 0> > > dummy;
|
||||
vector<int, scoped_allocator_adaptor< propagation_test_allocator<int, 0> > > dummy;
|
||||
dummy.push_back(0);
|
||||
}
|
||||
|
||||
@@ -781,34 +567,16 @@ int main()
|
||||
|
||||
//construct
|
||||
{
|
||||
|
||||
BOOST_STATIC_ASSERT(( !boost::container::uses_allocator
|
||||
< ::mark_on_scoped_allocation<NotUsesAllocator, 0>
|
||||
, test_allocator<float, 0>
|
||||
>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::uses_allocator
|
||||
< ::mark_on_scoped_allocation<ConstructiblePrefix, 0>
|
||||
, test_allocator<float, 0>
|
||||
>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::uses_allocator
|
||||
< ::mark_on_scoped_allocation<ConstructibleSuffix, 0>
|
||||
, test_allocator<float, 0>
|
||||
>::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::constructible_with_allocator_prefix
|
||||
< ::mark_on_scoped_allocation<ConstructiblePrefix, 0> >::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::container::constructible_with_allocator_suffix
|
||||
< ::mark_on_scoped_allocation<ConstructibleSuffix, 0> >::value ));
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//First check scoped allocator with just OuterAlloc.
|
||||
//In this case OuterAlloc (test_allocator with tag 0) should be
|
||||
//In this case OuterAlloc (propagation_test_allocator with tag 0) should be
|
||||
//used to construct types.
|
||||
////////////////////////////////////////////////////////////
|
||||
{
|
||||
Scoped0Inner s0i;
|
||||
//Check construction with 0 user arguments
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<NotUsesAllocator, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<NotUsesAllocator, 0> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
s0i.construct(&dummy);
|
||||
@@ -820,7 +588,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructibleSuffix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructibleSuffix, 0> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
s0i.construct(&dummy);
|
||||
@@ -832,7 +600,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructiblePrefix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructiblePrefix, 0> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
s0i.construct(&dummy);
|
||||
@@ -846,7 +614,7 @@ int main()
|
||||
|
||||
//Check construction with 1 user arguments
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<NotUsesAllocator, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<NotUsesAllocator, 0> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
s0i.construct(&dummy, 1);
|
||||
@@ -858,7 +626,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructibleSuffix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructibleSuffix, 0> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
s0i.construct(&dummy, 2);
|
||||
@@ -870,7 +638,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructiblePrefix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructiblePrefix, 0> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
s0i.construct(&dummy, 3);
|
||||
@@ -884,14 +652,14 @@ int main()
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
//Then check scoped allocator with OuterAlloc and InnerAlloc.
|
||||
//In this case InnerAlloc (test_allocator with tag 1) should be
|
||||
//In this case InnerAlloc (propagation_test_allocator with tag 1) should be
|
||||
//used to construct types.
|
||||
////////////////////////////////////////////////////////////
|
||||
{
|
||||
Scoped1Inner s1i;
|
||||
//Check construction with 0 user arguments
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<NotUsesAllocator, 1> MarkType;
|
||||
typedef ::allocator_argument_tester<NotUsesAllocator, 1> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
s1i.construct(&dummy);
|
||||
@@ -903,7 +671,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructibleSuffix, 1> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructibleSuffix, 1> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
s1i.construct(&dummy);
|
||||
@@ -915,7 +683,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructiblePrefix, 1> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructiblePrefix, 1> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
s1i.construct(&dummy);
|
||||
@@ -929,7 +697,7 @@ int main()
|
||||
|
||||
//Check construction with 1 user arguments
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<NotUsesAllocator, 1> MarkType;
|
||||
typedef ::allocator_argument_tester<NotUsesAllocator, 1> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
s1i.construct(&dummy, 1);
|
||||
@@ -941,7 +709,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructibleSuffix, 1> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructibleSuffix, 1> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
s1i.construct(&dummy, 2);
|
||||
@@ -953,7 +721,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructiblePrefix, 1> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructiblePrefix, 1> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
s1i.construct(&dummy, 3);
|
||||
@@ -972,31 +740,31 @@ int main()
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//First check scoped allocator with just OuterAlloc.
|
||||
//In this case OuterAlloc (test_allocator with tag 0) should be
|
||||
//In this case OuterAlloc (propagation_test_allocator with tag 0) should be
|
||||
//used to construct types.
|
||||
////////////////////////////////////////////////////////////
|
||||
{
|
||||
//Check outer_allocator_type is scoped
|
||||
BOOST_STATIC_ASSERT(( boost::container::is_scoped_allocator
|
||||
BOOST_STATIC_ASSERT(( is_scoped_allocator
|
||||
<ScopedScoped0Inner::outer_allocator_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( ::boost::container::container_detail::is_same
|
||||
< boost::container::outermost_allocator<ScopedScoped0Inner>::type
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same
|
||||
< outermost_allocator<ScopedScoped0Inner>::type
|
||||
, Outer10IdAlloc
|
||||
>::value ));
|
||||
BOOST_STATIC_ASSERT(( ::boost::container::container_detail::is_same
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same
|
||||
< ScopedScoped0Inner::outer_allocator_type
|
||||
, scoped_allocator_adaptor<Outer10IdAlloc>
|
||||
>::value ));
|
||||
BOOST_STATIC_ASSERT(( ::boost::container::container_detail::is_same
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same
|
||||
< scoped_allocator_adaptor<Outer10IdAlloc>::outer_allocator_type
|
||||
, Outer10IdAlloc
|
||||
>::value ));
|
||||
ScopedScoped0Inner ssro0i;
|
||||
Outer10IdAlloc & val = boost::container::outermost_allocator<ScopedScoped0Inner>::get(ssro0i);
|
||||
Outer10IdAlloc & val = outermost_allocator<ScopedScoped0Inner>::get(ssro0i);
|
||||
(void)val;
|
||||
//Check construction with 0 user arguments
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<NotUsesAllocator, 10> MarkType;
|
||||
typedef ::allocator_argument_tester<NotUsesAllocator, 10> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
ssro0i.construct(&dummy);
|
||||
@@ -1008,7 +776,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructibleSuffix, 10> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructibleSuffix, 10> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
ssro0i.construct(&dummy);
|
||||
@@ -1020,7 +788,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructiblePrefix, 10> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructiblePrefix, 10> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
ssro0i.construct(&dummy);
|
||||
@@ -1034,7 +802,7 @@ int main()
|
||||
|
||||
//Check construction with 1 user arguments
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<NotUsesAllocator, 10> MarkType;
|
||||
typedef ::allocator_argument_tester<NotUsesAllocator, 10> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
ssro0i.construct(&dummy, 1);
|
||||
@@ -1046,7 +814,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructibleSuffix, 10> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructibleSuffix, 10> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
ssro0i.construct(&dummy, 2);
|
||||
@@ -1058,7 +826,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructiblePrefix, 10> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructiblePrefix, 10> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
ssro0i.construct(&dummy, 3);
|
||||
@@ -1073,37 +841,37 @@ int main()
|
||||
////////////////////////////////////////////////////////////
|
||||
//Then check scoped allocator with OuterAlloc and InnerAlloc.
|
||||
//In this case inner_allocator_type is not convertible to
|
||||
//::mark_on_scoped_allocation<XXX, 10> so uses_allocator
|
||||
//::allocator_argument_tester<XXX, 10> so uses_allocator
|
||||
//should be false on all tests.
|
||||
////////////////////////////////////////////////////////////
|
||||
{
|
||||
//Check outer_allocator_type is scoped
|
||||
BOOST_STATIC_ASSERT(( boost::container::is_scoped_allocator
|
||||
BOOST_STATIC_ASSERT(( is_scoped_allocator
|
||||
<ScopedScoped1Inner::outer_allocator_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( ::boost::container::container_detail::is_same
|
||||
< boost::container::outermost_allocator<ScopedScoped1Inner>::type
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same
|
||||
< outermost_allocator<ScopedScoped1Inner>::type
|
||||
, Outer10IdAlloc
|
||||
>::value ));
|
||||
BOOST_STATIC_ASSERT(( ::boost::container::container_detail::is_same
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same
|
||||
< ScopedScoped1Inner::outer_allocator_type
|
||||
, scoped_allocator_adaptor<Outer10IdAlloc, Inner11IdAlloc1>
|
||||
>::value ));
|
||||
BOOST_STATIC_ASSERT(( ::boost::container::container_detail::is_same
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same
|
||||
< scoped_allocator_adaptor<Outer10IdAlloc, Inner11IdAlloc1>::outer_allocator_type
|
||||
, Outer10IdAlloc
|
||||
>::value ));
|
||||
BOOST_STATIC_ASSERT(( !
|
||||
::boost::container::uses_allocator
|
||||
< ::mark_on_scoped_allocation<ConstructibleSuffix, 10>
|
||||
uses_allocator
|
||||
< ::allocator_argument_tester<ConstructibleSuffix, 10>
|
||||
, ScopedScoped1Inner::inner_allocator_type::outer_allocator_type
|
||||
>::value ));
|
||||
ScopedScoped1Inner ssro1i;
|
||||
Outer10IdAlloc & val = boost::container::outermost_allocator<ScopedScoped1Inner>::get(ssro1i);
|
||||
Outer10IdAlloc & val = outermost_allocator<ScopedScoped1Inner>::get(ssro1i);
|
||||
(void)val;
|
||||
|
||||
//Check construction with 0 user arguments
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<NotUsesAllocator, 10> MarkType;
|
||||
typedef ::allocator_argument_tester<NotUsesAllocator, 10> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
ssro1i.construct(&dummy);
|
||||
@@ -1115,7 +883,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructibleSuffix, 10> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructibleSuffix, 10> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
ssro1i.construct(&dummy);
|
||||
@@ -1127,7 +895,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructiblePrefix, 10> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructiblePrefix, 10> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
ssro1i.construct(&dummy);
|
||||
@@ -1141,7 +909,7 @@ int main()
|
||||
|
||||
//Check construction with 1 user arguments
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<NotUsesAllocator, 10> MarkType;
|
||||
typedef ::allocator_argument_tester<NotUsesAllocator, 10> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
ssro1i.construct(&dummy, 1);
|
||||
@@ -1153,7 +921,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructibleSuffix, 10> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructibleSuffix, 10> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
ssro1i.construct(&dummy, 2);
|
||||
@@ -1165,7 +933,7 @@ int main()
|
||||
dummy.~MarkType();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructiblePrefix, 10> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructiblePrefix, 10> MarkType;
|
||||
MarkType dummy;
|
||||
dummy.~MarkType();
|
||||
ssro1i.construct(&dummy, 3);
|
||||
@@ -1182,12 +950,12 @@ int main()
|
||||
//Now check propagation to pair
|
||||
////////////////////////////////////////////////////////////
|
||||
//First check scoped allocator with just OuterAlloc.
|
||||
//In this case OuterAlloc (test_allocator with tag 0) should be
|
||||
//In this case OuterAlloc (propagation_test_allocator with tag 0) should be
|
||||
//used to construct types.
|
||||
////////////////////////////////////////////////////////////
|
||||
{
|
||||
using boost::container::container_detail::pair;
|
||||
typedef test_allocator< pair< tagged_integer<0>
|
||||
using container_detail::pair;
|
||||
typedef propagation_test_allocator< pair< tagged_integer<0>
|
||||
, tagged_integer<0> >, 0> OuterPairAlloc;
|
||||
//
|
||||
typedef scoped_allocator_adaptor < OuterPairAlloc > ScopedPair0Inner;
|
||||
@@ -1195,7 +963,7 @@ int main()
|
||||
ScopedPair0Inner s0i;
|
||||
//Check construction with 0 user arguments
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<NotUsesAllocator, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<NotUsesAllocator, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy;
|
||||
dummy.~MarkTypePair();
|
||||
@@ -1210,7 +978,7 @@ int main()
|
||||
dummy.~MarkTypePair();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructibleSuffix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructibleSuffix, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy;
|
||||
dummy.~MarkTypePair();
|
||||
@@ -1225,7 +993,7 @@ int main()
|
||||
dummy.~MarkTypePair();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructiblePrefix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructiblePrefix, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy;
|
||||
dummy.~MarkTypePair();
|
||||
@@ -1242,7 +1010,7 @@ int main()
|
||||
|
||||
//Check construction with 1 user arguments for each pair
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<NotUsesAllocator, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<NotUsesAllocator, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy;
|
||||
dummy.~MarkTypePair();
|
||||
@@ -1257,7 +1025,7 @@ int main()
|
||||
dummy.~MarkTypePair();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructibleSuffix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructibleSuffix, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy;
|
||||
dummy.~MarkTypePair();
|
||||
@@ -1272,7 +1040,7 @@ int main()
|
||||
dummy.~MarkTypePair();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructiblePrefix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructiblePrefix, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy;
|
||||
dummy.~MarkTypePair();
|
||||
@@ -1288,7 +1056,7 @@ int main()
|
||||
}
|
||||
//Check construction with pair copy construction
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<NotUsesAllocator, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<NotUsesAllocator, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy, dummy2;
|
||||
dummy.~MarkTypePair();
|
||||
@@ -1303,7 +1071,7 @@ int main()
|
||||
dummy.~MarkTypePair();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructibleSuffix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructibleSuffix, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy, dummy2(1, 1);
|
||||
dummy.~MarkTypePair();
|
||||
@@ -1318,7 +1086,7 @@ int main()
|
||||
dummy.~MarkTypePair();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructiblePrefix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructiblePrefix, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy, dummy2(2, 2);
|
||||
dummy.~MarkTypePair();
|
||||
@@ -1334,7 +1102,7 @@ int main()
|
||||
}
|
||||
//Check construction with pair move construction
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<NotUsesAllocator, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<NotUsesAllocator, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy, dummy2(3, 3);
|
||||
dummy2.first.construction_type = dummy2.second.construction_type = ConstructibleSuffix;
|
||||
@@ -1354,7 +1122,7 @@ int main()
|
||||
dummy.~MarkTypePair();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructibleSuffix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructibleSuffix, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy, dummy2(1, 1);
|
||||
dummy.~MarkTypePair();
|
||||
@@ -1373,7 +1141,7 @@ int main()
|
||||
dummy.~MarkTypePair();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructiblePrefix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructiblePrefix, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy, dummy2(2, 2);
|
||||
dummy.~MarkTypePair();
|
||||
@@ -1393,7 +1161,7 @@ int main()
|
||||
}
|
||||
//Check construction with related pair copy construction
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<NotUsesAllocator, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<NotUsesAllocator, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy;
|
||||
pair<int, int> dummy2;
|
||||
@@ -1409,7 +1177,7 @@ int main()
|
||||
dummy.~MarkTypePair();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructibleSuffix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructibleSuffix, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy;
|
||||
pair<int, int> dummy2(1, 1);
|
||||
@@ -1425,7 +1193,7 @@ int main()
|
||||
dummy.~MarkTypePair();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructiblePrefix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructiblePrefix, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy;
|
||||
pair<int, int> dummy2(2, 2);
|
||||
@@ -1442,7 +1210,7 @@ int main()
|
||||
}
|
||||
//Check construction with related pair move construction
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<NotUsesAllocator, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<NotUsesAllocator, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy;
|
||||
pair<int, int> dummy2(3, 3);
|
||||
@@ -1458,7 +1226,7 @@ int main()
|
||||
dummy.~MarkTypePair();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructibleSuffix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructibleSuffix, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy;
|
||||
pair<int, int> dummy2(1, 1);
|
||||
@@ -1474,7 +1242,7 @@ int main()
|
||||
dummy.~MarkTypePair();
|
||||
}
|
||||
{
|
||||
typedef ::mark_on_scoped_allocation<ConstructiblePrefix, 0> MarkType;
|
||||
typedef ::allocator_argument_tester<ConstructiblePrefix, 0> MarkType;
|
||||
typedef pair<MarkType, MarkType> MarkTypePair;
|
||||
MarkTypePair dummy;
|
||||
pair<int, int> dummy2(2, 2);
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/synchronized_pool_resource.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include "pool_resource_test.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
test_pool_resource<boost::container::pmr::synchronized_pool_resource>();
|
||||
return ::boost::report_errors();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/pmr/unsynchronized_pool_resource.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include "pool_resource_test.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
test_pool_resource<boost::container::pmr::unsynchronized_pool_resource>();
|
||||
return ::boost::report_errors();
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/uses_allocator_fwd.hpp>
|
||||
|
||||
#include <boost/container/uses_allocator.hpp>
|
||||
#include "propagation_test_allocator.hpp"
|
||||
|
||||
struct not_uses_allocator
|
||||
{};
|
||||
|
||||
struct uses_allocator_and_not_convertible_to_int
|
||||
{
|
||||
typedef uses_allocator_and_not_convertible_to_int allocator_type;
|
||||
};
|
||||
|
||||
struct uses_allocator_and_convertible_to_int
|
||||
{
|
||||
typedef char allocator_type;
|
||||
};
|
||||
|
||||
struct uses_erased_type_allocator
|
||||
{
|
||||
typedef boost::container::erased_type allocator_type;
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
//Using dummy classes
|
||||
BOOST_STATIC_ASSERT(( false == uses_allocator
|
||||
< not_uses_allocator, int>::value ));
|
||||
|
||||
BOOST_STATIC_ASSERT(( false == uses_allocator
|
||||
< uses_allocator_and_not_convertible_to_int, int>::value ));
|
||||
|
||||
BOOST_STATIC_ASSERT(( true == uses_allocator
|
||||
< uses_allocator_and_convertible_to_int, int>::value ));
|
||||
|
||||
BOOST_STATIC_ASSERT(( true == uses_allocator
|
||||
< uses_erased_type_allocator, int>::value ));
|
||||
|
||||
//Using an allocator-like class
|
||||
BOOST_STATIC_ASSERT(( false == uses_allocator
|
||||
< allocator_argument_tester<NotUsesAllocator, 0>
|
||||
, propagation_test_allocator<float, 0>
|
||||
>::value ));
|
||||
BOOST_STATIC_ASSERT(( true == uses_allocator
|
||||
< allocator_argument_tester<ConstructiblePrefix, 0>
|
||||
, propagation_test_allocator<float, 0>
|
||||
>::value ));
|
||||
BOOST_STATIC_ASSERT(( true == uses_allocator
|
||||
< allocator_argument_tester<ConstructibleSuffix, 0>
|
||||
, propagation_test_allocator<float, 0>
|
||||
>::value ));
|
||||
BOOST_STATIC_ASSERT(( true == uses_allocator
|
||||
< allocator_argument_tester<ErasedTypeSuffix, 0>
|
||||
, propagation_test_allocator<float, 0>
|
||||
>::value ));
|
||||
BOOST_STATIC_ASSERT(( true == uses_allocator
|
||||
< allocator_argument_tester<ErasedTypePrefix, 0>
|
||||
, propagation_test_allocator<float, 0>
|
||||
>::value ));
|
||||
BOOST_STATIC_ASSERT(( true == constructible_with_allocator_prefix
|
||||
< allocator_argument_tester<ConstructiblePrefix, 0> >::value ));
|
||||
|
||||
BOOST_STATIC_ASSERT(( true == constructible_with_allocator_suffix
|
||||
< allocator_argument_tester<ConstructibleSuffix, 0> >::value ));
|
||||
|
||||
BOOST_STATIC_ASSERT(( true == constructible_with_allocator_prefix
|
||||
< allocator_argument_tester<ErasedTypePrefix, 0> >::value ));
|
||||
|
||||
BOOST_STATIC_ASSERT(( true == constructible_with_allocator_suffix
|
||||
< allocator_argument_tester<ErasedTypeSuffix, 0> >::value ));
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user