mirror of
https://github.com/boostorg/container.git
synced 2026-01-19 04:02:17 +00:00
Merge branch 'develop'
This commit is contained in:
@@ -21,7 +21,7 @@ rule test_all
|
||||
|
||||
for local fileb in [ glob *.cpp ]
|
||||
{
|
||||
all_rules += [ run $(fileb) /boost/timer//boost_timer
|
||||
all_rules += [ run $(fileb) /boost/timer//boost_timer /boost/container//boost_container
|
||||
: # additional args
|
||||
: # test-files
|
||||
: # requirements
|
||||
@@ -31,4 +31,4 @@ rule test_all
|
||||
return $(all_rules) ;
|
||||
}
|
||||
|
||||
test-suite container_test : [ test_all r ] ;
|
||||
test-suite container_bench : [ test_all r ] ;
|
||||
|
||||
327
bench/bench_adaptive_node_pool.cpp
Normal file
327
bench/bench_adaptive_node_pool.cpp
Normal file
@@ -0,0 +1,327 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable : 4512)
|
||||
#pragma warning (disable : 4127)
|
||||
#pragma warning (disable : 4244)
|
||||
#pragma warning (disable : 4267)
|
||||
#endif
|
||||
|
||||
#include <boost/container/adaptive_pool.hpp>
|
||||
#include <boost/container/node_allocator.hpp>
|
||||
#include <boost/container/allocator.hpp>
|
||||
#include <boost/container/list.hpp>
|
||||
#include <memory> //std::allocator
|
||||
#include <iostream> //std::cout, std::endl
|
||||
#include <vector> //std::vector
|
||||
#include <cstddef> //std::size_t
|
||||
#include <boost/timer/timer.hpp>
|
||||
using boost::timer::cpu_timer;
|
||||
using boost::timer::cpu_times;
|
||||
using boost::timer::nanosecond_type;
|
||||
|
||||
namespace bc = boost::container;
|
||||
|
||||
typedef std::allocator<int> StdAllocator;
|
||||
typedef bc::allocator<int, 2> AllocatorPlusV2;
|
||||
typedef bc::allocator<int, 1> AllocatorPlusV1;
|
||||
typedef bc::adaptive_pool
|
||||
< int
|
||||
, bc::ADP_nodes_per_block
|
||||
, bc::ADP_max_free_blocks
|
||||
, bc::ADP_only_alignment
|
||||
, 1> AdPoolAlignOnlyV1;
|
||||
typedef bc::adaptive_pool
|
||||
< int
|
||||
, bc::ADP_nodes_per_block
|
||||
, bc::ADP_max_free_blocks
|
||||
, bc::ADP_only_alignment
|
||||
, 2> AdPoolAlignOnlyV2;
|
||||
typedef bc::adaptive_pool
|
||||
< int
|
||||
, bc::ADP_nodes_per_block
|
||||
, bc::ADP_max_free_blocks
|
||||
, 2
|
||||
, 1> AdPool2PercentV1;
|
||||
typedef bc::adaptive_pool
|
||||
< int
|
||||
, bc::ADP_nodes_per_block
|
||||
, bc::ADP_max_free_blocks
|
||||
, 2
|
||||
, 2> AdPool2PercentV2;
|
||||
typedef bc::node_allocator
|
||||
< int
|
||||
, bc::NodeAlloc_nodes_per_block
|
||||
, 1> SimpleSegregatedStorageV1;
|
||||
typedef bc::node_allocator
|
||||
< int
|
||||
, bc::NodeAlloc_nodes_per_block
|
||||
, 2> SimpleSegregatedStorageV2;
|
||||
|
||||
//Explicit instantiation
|
||||
template class bc::adaptive_pool
|
||||
< int
|
||||
, bc::ADP_nodes_per_block
|
||||
, bc::ADP_max_free_blocks
|
||||
, bc::ADP_only_alignment
|
||||
, 2>;
|
||||
|
||||
template class bc::node_allocator
|
||||
< int
|
||||
, bc::NodeAlloc_nodes_per_block
|
||||
, 2>;
|
||||
|
||||
template<class Allocator> struct get_allocator_name;
|
||||
|
||||
template<> struct get_allocator_name<StdAllocator>
|
||||
{ static const char *get() { return "StdAllocator"; } };
|
||||
|
||||
template<> struct get_allocator_name<AllocatorPlusV2>
|
||||
{ static const char *get() { return "AllocatorPlusV2"; } };
|
||||
|
||||
template<> struct get_allocator_name<AllocatorPlusV1>
|
||||
{ static const char *get() { return "AllocatorPlusV1"; } };
|
||||
|
||||
template<> struct get_allocator_name<AdPoolAlignOnlyV1>
|
||||
{ static const char *get() { return "AdPoolAlignOnlyV1"; } };
|
||||
|
||||
template<> struct get_allocator_name<AdPoolAlignOnlyV2>
|
||||
{ static const char *get() { return "AdPoolAlignOnlyV2"; } };
|
||||
|
||||
template<> struct get_allocator_name<AdPool2PercentV1>
|
||||
{ static const char *get() { return "AdPool2PercentV1"; } };
|
||||
|
||||
template<> struct get_allocator_name<AdPool2PercentV2>
|
||||
{ static const char *get() { return "AdPool2PercentV2"; } };
|
||||
|
||||
template<> struct get_allocator_name<SimpleSegregatedStorageV1>
|
||||
{ static const char *get() { return "SimpleSegregatedStorageV1"; } };
|
||||
|
||||
template<> struct get_allocator_name<SimpleSegregatedStorageV2>
|
||||
{ static const char *get() { return "SimpleSegregatedStorageV2"; } };
|
||||
|
||||
class MyInt
|
||||
{
|
||||
std::size_t int_;
|
||||
|
||||
public:
|
||||
explicit MyInt(std::size_t i = 0) : int_(i){}
|
||||
MyInt(const MyInt &other)
|
||||
: int_(other.int_)
|
||||
{}
|
||||
MyInt & operator=(const MyInt &other)
|
||||
{
|
||||
int_ = other.int_;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template<class Allocator>
|
||||
void list_test_template(std::size_t num_iterations, std::size_t num_elements, bool csv_output)
|
||||
{
|
||||
typedef typename Allocator::template rebind<MyInt>::other IntAllocator;
|
||||
nanosecond_type tinsert, terase;
|
||||
boost_cont_malloc_stats_t insert_stats, erase_stats;
|
||||
std::size_t insert_inuse, erase_inuse;
|
||||
const size_t sizeof_node = 2*sizeof(void*)+sizeof(int);
|
||||
|
||||
typedef bc::list<MyInt, IntAllocator> list_t;
|
||||
typedef typename list_t::iterator iterator_t;
|
||||
{
|
||||
cpu_timer timer;
|
||||
timer.resume();
|
||||
list_t l;
|
||||
for(std::size_t r = 0; r != num_iterations; ++r){
|
||||
l.insert(l.end(), num_elements, MyInt(r));
|
||||
}
|
||||
timer.stop();
|
||||
tinsert = timer.elapsed().wall;
|
||||
|
||||
insert_inuse = boost_cont_in_use_memory();
|
||||
insert_stats = boost_cont_malloc_stats();
|
||||
/*
|
||||
iterator_t it(l.begin());
|
||||
iterator_t last(--l.end());
|
||||
for(std::size_t n_elem = 0, n_max = l.size()/2-1; n_elem != n_max; ++n_elem)
|
||||
{
|
||||
l.splice(it++, l, last--);
|
||||
}
|
||||
*/
|
||||
//l.reverse();
|
||||
|
||||
//Now preprocess erase ranges
|
||||
std::vector<iterator_t> ranges_to_erase;
|
||||
ranges_to_erase.push_back(l.begin());
|
||||
for(std::size_t r = 0; r != num_iterations; ++r){
|
||||
iterator_t next_pos(ranges_to_erase[r]);
|
||||
std::size_t n = num_elements;
|
||||
while(n--){ ++next_pos; }
|
||||
ranges_to_erase.push_back(next_pos);
|
||||
}
|
||||
|
||||
//Measure range erasure function
|
||||
timer.start();
|
||||
for(std::size_t r = 0; r != num_iterations; ++r){
|
||||
assert((r+1) < ranges_to_erase.size());
|
||||
l.erase(ranges_to_erase[r], ranges_to_erase[r+1]);
|
||||
}
|
||||
timer.stop();
|
||||
terase = timer.elapsed().wall;
|
||||
erase_inuse = boost_cont_in_use_memory();
|
||||
erase_stats = boost_cont_malloc_stats();
|
||||
}
|
||||
|
||||
|
||||
if(csv_output){
|
||||
std::cout << get_allocator_name<Allocator>::get()
|
||||
<< ";"
|
||||
<< num_iterations
|
||||
<< ";"
|
||||
<< num_elements
|
||||
<< ";"
|
||||
<< float(tinsert)/(num_iterations*num_elements)
|
||||
<< ";"
|
||||
<< (unsigned int)insert_stats.system_bytes
|
||||
<< ";"
|
||||
<< float(insert_stats.system_bytes)/(num_iterations*num_elements*sizeof_node)*100.0-100.0
|
||||
<< ";"
|
||||
<< (unsigned int)insert_inuse
|
||||
<< ";"
|
||||
<< (float(insert_inuse)/(num_iterations*num_elements*sizeof_node)*100.0)-100.0
|
||||
<< ";";
|
||||
std::cout << float(terase)/(num_iterations*num_elements)
|
||||
<< ";"
|
||||
<< (unsigned int)erase_stats.system_bytes
|
||||
<< ";"
|
||||
<< (unsigned int)erase_inuse
|
||||
<< std::endl;
|
||||
}
|
||||
else{
|
||||
std::cout << std::endl
|
||||
<< "Allocator: " << get_allocator_name<Allocator>::get()
|
||||
<< std::endl
|
||||
<< " allocation/deallocation(ns): " << float(tinsert)/(num_iterations*num_elements) << '\t' << float(terase)/(num_iterations*num_elements)
|
||||
<< std::endl
|
||||
<< " Sys MB(overh.)/Inuse MB(overh.): " << (float)insert_stats.system_bytes/(1024*1024) << "(" << float(insert_stats.system_bytes)/(num_iterations*num_elements*sizeof_node)*100.0-100.0 << "%)"
|
||||
<< " / "
|
||||
<< (float)insert_inuse/(1024*1024) << "(" << (float(insert_inuse)/(num_iterations*num_elements*sizeof_node)*100.0)-100.0 << "%)"
|
||||
<< std::endl
|
||||
<< " system MB/inuse bytes after: " << (float)erase_stats.system_bytes/(1024*1024) << '\t' << boost_cont_in_use_memory()
|
||||
<< std::endl << std::endl;
|
||||
}
|
||||
|
||||
//Release node_allocator cache
|
||||
typedef boost::container::container_detail::shared_node_pool
|
||||
< (2*sizeof(void*)+sizeof(int))
|
||||
, AdPoolAlignOnlyV2::nodes_per_block> shared_node_pool_t;
|
||||
boost::container::container_detail::singleton_default
|
||||
<shared_node_pool_t>::instance().purge_blocks();
|
||||
|
||||
//Release adaptive_pool cache
|
||||
typedef boost::container::container_detail::shared_adaptive_node_pool
|
||||
< (2*sizeof(void*)+sizeof(int))
|
||||
, AdPool2PercentV2::nodes_per_block
|
||||
, AdPool2PercentV2::max_free_blocks
|
||||
, AdPool2PercentV2::overhead_percent> shared_adaptive_pool_plus_t;
|
||||
boost::container::container_detail::singleton_default
|
||||
<shared_adaptive_pool_plus_t>::instance().deallocate_free_blocks();
|
||||
|
||||
//Release adaptive_pool cache
|
||||
typedef boost::container::container_detail::shared_adaptive_node_pool
|
||||
< (2*sizeof(void*)+sizeof(int))
|
||||
, AdPool2PercentV2::nodes_per_block
|
||||
, AdPool2PercentV2::max_free_blocks
|
||||
, 0u> shared_adaptive_pool_plus_align_only_t;
|
||||
boost::container::container_detail::singleton_default
|
||||
<shared_adaptive_pool_plus_align_only_t>::instance().deallocate_free_blocks();
|
||||
//Release dlmalloc memory
|
||||
boost_cont_trim(0);
|
||||
}
|
||||
|
||||
void print_header()
|
||||
{
|
||||
std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";"
|
||||
<< "Insertion time(ns)" << ";"
|
||||
<< "System bytes" << ";"
|
||||
<< "System overhead(%)" << ";"
|
||||
<< "In use bytes" << ";"
|
||||
<< "In use overhead(%)" << ";"
|
||||
<< "Erasure time (ns)" << ";"
|
||||
<< "System bytes after" << ";"
|
||||
<< "In use bytes after"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
#define SINGLE_TEST
|
||||
#ifndef SINGLE_TEST
|
||||
#ifdef NDEBUG
|
||||
std::size_t numrep [] = { 3000, 30000, 300000, 3000000, 6000000, 15000000, 30000000 };
|
||||
#else
|
||||
std::size_t numrep [] = { 20, 200, 2000, 20000, 40000, 100000, 200000 };
|
||||
#endif
|
||||
std::size_t numele [] = { 10000, 1000, 100, 10, 5, 2, 1 };
|
||||
#else
|
||||
#ifdef NDEBUG
|
||||
std::size_t numrep [] = { 1500000 };
|
||||
#else
|
||||
std::size_t numrep [] = { 10000 };
|
||||
#endif
|
||||
std::size_t numele [] = { 10 };
|
||||
#endif
|
||||
|
||||
bool csv_output = argc == 2 && (strcmp(argv[1], "--csv-output") == 0);
|
||||
|
||||
if(csv_output){/*
|
||||
print_header();
|
||||
for(std::size_t i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
list_test_template<AllocatorPlusV1>(numrep[i], numele[i], csv_output);
|
||||
}
|
||||
for(std::size_t i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
list_test_template<AllocatorPlusV2>(numrep[i], numele[i], csv_output);
|
||||
}
|
||||
for(std::size_t i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
list_test_template<AdPoolAlignOnlyV1>(numrep[i], numele[i], csv_output);
|
||||
}
|
||||
for(std::size_t i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
list_test_template<AdPoolAlignOnlyV2>(numrep[i], numele[i], csv_output);
|
||||
}
|
||||
for(std::size_t i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
list_test_template<AdPool2PercentV1>(numrep[i], numele[i], csv_output);
|
||||
}
|
||||
for(std::size_t i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
list_test_template<AdPool2PercentV2>(numrep[i], numele[i], csv_output);
|
||||
}
|
||||
for(std::size_t i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
list_test_template<SimpleSegregatedStorageV1>(numrep[i], numele[i], csv_output);
|
||||
}
|
||||
for(std::size_t i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
list_test_template<SimpleSegregatedStorageV2>(numrep[i], numele[i], csv_output);
|
||||
}*/
|
||||
}
|
||||
else{
|
||||
for(std::size_t i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
std::cout << "\n ----------------------------------- \n"
|
||||
<< " Iterations/Elements: " << numrep[i] << "/" << numele[i]
|
||||
<< "\n ----------------------------------- \n";
|
||||
list_test_template<AllocatorPlusV1>(numrep[i], numele[i], csv_output);
|
||||
list_test_template<AllocatorPlusV2>(numrep[i], numele[i], csv_output);
|
||||
list_test_template<AdPoolAlignOnlyV1>(numrep[i], numele[i], csv_output);
|
||||
list_test_template<AdPoolAlignOnlyV2>(numrep[i], numele[i], csv_output);
|
||||
list_test_template<AdPool2PercentV1>(numrep[i], numele[i], csv_output);
|
||||
list_test_template<AdPool2PercentV2>(numrep[i], numele[i], csv_output);
|
||||
list_test_template<SimpleSegregatedStorageV1>(numrep[i], numele[i], csv_output);
|
||||
list_test_template<SimpleSegregatedStorageV2>(numrep[i], numele[i], csv_output);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
181
bench/bench_alloc.cpp
Normal file
181
bench/bench_alloc.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable : 4512)
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/alloc_lib_auto_link.hpp>
|
||||
|
||||
#define BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
|
||||
|
||||
#include <iostream> //std::cout, std::endl
|
||||
#include <typeinfo> //typeid
|
||||
|
||||
#include <boost/timer/timer.hpp>
|
||||
using boost::timer::cpu_timer;
|
||||
using boost::timer::cpu_times;
|
||||
using boost::timer::nanosecond_type;
|
||||
|
||||
template <class POD>
|
||||
void allocation_timing_test(unsigned int num_iterations, unsigned int num_elements)
|
||||
{
|
||||
size_t capacity = 0;
|
||||
unsigned int numalloc = 0, numexpand = 0;
|
||||
|
||||
std::cout
|
||||
<< " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \n"
|
||||
<< " Iterations/Elements: " << num_iterations << "/" << num_elements << '\n'
|
||||
<< " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \n"
|
||||
<< std::endl;
|
||||
|
||||
|
||||
allocation_type malloc_types[] = { BOOST_CONTAINER_EXPAND_BWD, BOOST_CONTAINER_EXPAND_FWD, BOOST_CONTAINER_ALLOCATE_NEW };
|
||||
const char * malloc_names[] = { "Backwards expansion", "Forward expansion", "New allocation" };
|
||||
for(size_t i = 0; i < sizeof(malloc_types)/sizeof(allocation_type); ++i){
|
||||
numalloc = 0; numexpand = 0;
|
||||
const allocation_type m_mode = malloc_types[i];
|
||||
const char *malloc_name = malloc_names[i];
|
||||
|
||||
cpu_timer timer;
|
||||
timer.resume();
|
||||
|
||||
for(unsigned int r = 0; r != num_iterations; ++r){
|
||||
void *first_mem = 0;
|
||||
if(m_mode != BOOST_CONTAINER_EXPAND_FWD)
|
||||
first_mem = boost_cont_malloc(sizeof(POD)*num_elements*3/2);
|
||||
void *addr = boost_cont_malloc(1*sizeof(POD));
|
||||
if(m_mode == BOOST_CONTAINER_EXPAND_FWD)
|
||||
first_mem = boost_cont_malloc(sizeof(POD)*num_elements*3/2);
|
||||
capacity = boost_cont_size(addr)/sizeof(POD);
|
||||
boost_cont_free(first_mem);
|
||||
++numalloc;
|
||||
|
||||
try{
|
||||
boost_cont_command_ret_t ret;
|
||||
for(size_t e = capacity + 1; e < num_elements; ++e){
|
||||
size_t received_size;
|
||||
size_t min = (capacity+1)*sizeof(POD);
|
||||
size_t max = (capacity*3/2)*sizeof(POD);
|
||||
if(min > max)
|
||||
max = min;
|
||||
ret = boost_cont_allocation_command
|
||||
( m_mode, sizeof(POD)
|
||||
, min, max, &received_size, addr);
|
||||
if(!ret.first){
|
||||
std::cout << "(!ret.first)!" << std::endl;
|
||||
throw int(0);
|
||||
}
|
||||
if(!ret.second){
|
||||
assert(m_mode == BOOST_CONTAINER_ALLOCATE_NEW);
|
||||
if(m_mode != BOOST_CONTAINER_ALLOCATE_NEW){
|
||||
std::cout << "m_mode != BOOST_CONTAINER_ALLOCATE_NEW!" << std::endl;
|
||||
return;
|
||||
}
|
||||
boost_cont_free(addr);
|
||||
addr = ret.first;
|
||||
++numalloc;
|
||||
}
|
||||
else{
|
||||
assert(m_mode != BOOST_CONTAINER_ALLOCATE_NEW);
|
||||
if(m_mode == BOOST_CONTAINER_ALLOCATE_NEW){
|
||||
std::cout << "m_mode == BOOST_CONTAINER_ALLOCATE_NEW!" << std::endl;
|
||||
return;
|
||||
}
|
||||
++numexpand;
|
||||
}
|
||||
capacity = received_size/sizeof(POD);
|
||||
addr = ret.first;
|
||||
e = capacity + 1;
|
||||
}
|
||||
boost_cont_free(addr);
|
||||
}
|
||||
catch(...){
|
||||
boost_cont_free(addr);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
assert( boost_cont_allocated_memory() == 0);
|
||||
if(boost_cont_allocated_memory()!= 0){
|
||||
std::cout << "Memory leak!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
timer.stop();
|
||||
nanosecond_type nseconds = timer.elapsed().wall;
|
||||
|
||||
std::cout << " Malloc type: " << malloc_name
|
||||
<< std::endl
|
||||
<< " allocation ns: "
|
||||
<< float(nseconds)/(num_iterations*num_elements)
|
||||
<< std::endl
|
||||
<< " capacity - alloc calls (new/expand): "
|
||||
<< (unsigned int)capacity << " - "
|
||||
<< (float(numalloc) + float(numexpand))/num_iterations
|
||||
<< "(" << float(numalloc)/num_iterations << "/" << float(numexpand)/num_iterations << ")"
|
||||
<< std::endl << std::endl;
|
||||
boost_cont_trim(0);
|
||||
}
|
||||
}
|
||||
|
||||
template<unsigned N>
|
||||
struct char_holder
|
||||
{
|
||||
char ints_[N];
|
||||
};
|
||||
|
||||
template<class POD>
|
||||
int allocation_loop()
|
||||
{
|
||||
std::cout << std::endl
|
||||
<< "-------------------------------------------\n"
|
||||
<< "-------------------------------------------\n"
|
||||
<< " Type(sizeof): " << typeid(POD).name() << " (" << sizeof(POD) << ")\n"
|
||||
<< "-------------------------------------------\n"
|
||||
<< "-------------------------------------------\n"
|
||||
<< std::endl;
|
||||
|
||||
#define SINGLE_TEST
|
||||
#ifndef SINGLE_TEST
|
||||
#ifdef NDEBUG
|
||||
unsigned int numrep [] = { /*10000, */100000, 1000000, 10000000 };
|
||||
#else
|
||||
unsigned int numrep [] = { /*10000, */10000, 100000, 1000000 };
|
||||
#endif
|
||||
unsigned int numele [] = { /*10000, */1000, 100, 10 };
|
||||
#else
|
||||
#ifdef NDEBUG
|
||||
unsigned int numrep [] = { 500000 };
|
||||
#else
|
||||
unsigned int numrep [] = { 50000 };
|
||||
#endif
|
||||
unsigned int numele [] = { 100 };
|
||||
#endif
|
||||
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
allocation_timing_test<POD>(numrep[i], numele[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
boost_cont_mallopt( (-3)//M_MMAP_THRESHOLD
|
||||
, 100*10000000);
|
||||
//allocation_loop<char_holder<4> >();
|
||||
//allocation_loop<char_holder<6> >();
|
||||
allocation_loop<char_holder<8> >();
|
||||
allocation_loop<char_holder<12> >();
|
||||
//allocation_loop<char_holder<14> >();
|
||||
allocation_loop<char_holder<24> >();
|
||||
return 0;
|
||||
}
|
||||
216
bench/bench_alloc_expand_bwd.cpp
Normal file
216
bench/bench_alloc_expand_bwd.cpp
Normal file
@@ -0,0 +1,216 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable : 4512)
|
||||
#endif
|
||||
|
||||
#include <boost/container/allocator.hpp>
|
||||
|
||||
#define BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <memory> //std::allocator
|
||||
#include <iostream> //std::cout, std::endl
|
||||
|
||||
#include <boost/timer/timer.hpp>
|
||||
using boost::timer::cpu_timer;
|
||||
using boost::timer::cpu_times;
|
||||
using boost::timer::nanosecond_type;
|
||||
|
||||
namespace bc = boost::container;
|
||||
|
||||
typedef std::allocator<int> StdAllocator;
|
||||
typedef bc::allocator<int, 2, bc::expand_bwd | bc::expand_fwd> AllocatorPlusV2Mask;
|
||||
typedef bc::allocator<int, 2, bc::expand_fwd> AllocatorPlusV2;
|
||||
typedef bc::allocator<int, 1> AllocatorPlusV1;
|
||||
|
||||
template<class Allocator> struct get_allocator_name;
|
||||
|
||||
template<> struct get_allocator_name<StdAllocator>
|
||||
{ static const char *get() { return "StdAllocator"; } };
|
||||
|
||||
template<> struct get_allocator_name<AllocatorPlusV2Mask>
|
||||
{ static const char *get() { return "AllocatorPlusV2Mask"; } };
|
||||
|
||||
template<> struct get_allocator_name<AllocatorPlusV2>
|
||||
{ static const char *get() { return "AllocatorPlusV2"; } };
|
||||
|
||||
template<> struct get_allocator_name<AllocatorPlusV1>
|
||||
{ static const char *get() { return "AllocatorPlusV1"; } };
|
||||
|
||||
//typedef int MyInt;
|
||||
|
||||
class MyInt
|
||||
{
|
||||
int int_;
|
||||
|
||||
public:
|
||||
MyInt(int i = 0)
|
||||
: int_(i)
|
||||
{}
|
||||
|
||||
MyInt(const MyInt &other)
|
||||
: int_(other.int_)
|
||||
{}
|
||||
|
||||
MyInt & operator=(const MyInt &other)
|
||||
{
|
||||
int_ = other.int_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~MyInt()
|
||||
{
|
||||
int_ = 0;
|
||||
}
|
||||
};
|
||||
namespace boost{
|
||||
|
||||
template<>
|
||||
struct has_trivial_destructor_after_move<MyInt>
|
||||
{
|
||||
static const bool value = true;
|
||||
//static const bool value = false;
|
||||
};
|
||||
|
||||
} //namespace boost{
|
||||
|
||||
|
||||
void print_header()
|
||||
{
|
||||
std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";"
|
||||
<< "Capacity" << ";" << "push_back(ns)" << ";" << "Allocator calls" << ";"
|
||||
<< "New allocations" << ";" << "Bwd expansions" << std::endl;
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
void vector_test_template(unsigned int num_iterations, unsigned int num_elements, bool csv_output)
|
||||
{
|
||||
typedef typename Allocator::template rebind<MyInt>::other IntAllocator;
|
||||
unsigned int numalloc = 0, numexpand = 0;
|
||||
|
||||
cpu_timer timer;
|
||||
timer.resume();
|
||||
|
||||
unsigned int capacity = 0;
|
||||
for(unsigned int r = 0; r != num_iterations; ++r){
|
||||
bc::vector<MyInt, IntAllocator> v;
|
||||
v.reset_alloc_stats();
|
||||
void *first_mem = 0;
|
||||
try{
|
||||
first_mem = boost_cont_malloc(sizeof(MyInt)*num_elements*3/2);
|
||||
v.push_back(MyInt(0));
|
||||
boost_cont_free(first_mem);
|
||||
|
||||
for(unsigned int e = 0; e != num_elements; ++e){
|
||||
v.push_back(MyInt(e));
|
||||
}
|
||||
numalloc += v.num_alloc;
|
||||
numexpand += v.num_expand_bwd;
|
||||
capacity = static_cast<unsigned int>(v.capacity());
|
||||
}
|
||||
catch(...){
|
||||
boost_cont_free(first_mem);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
assert(boost_cont_allocated_memory() == 0);
|
||||
|
||||
timer.stop();
|
||||
nanosecond_type nseconds = timer.elapsed().wall;
|
||||
|
||||
if(csv_output){
|
||||
std::cout << get_allocator_name<Allocator>::get()
|
||||
<< ";"
|
||||
<< num_iterations
|
||||
<< ";"
|
||||
<< num_elements
|
||||
<< ";"
|
||||
<< capacity
|
||||
<< ";"
|
||||
<< float(nseconds)/(num_iterations*num_elements)
|
||||
<< ";"
|
||||
<< (float(numalloc) + float(numexpand))/num_iterations
|
||||
<< ";"
|
||||
<< float(numalloc)/num_iterations
|
||||
<< ";"
|
||||
<< float(numexpand)/num_iterations
|
||||
<< std::endl;
|
||||
}
|
||||
else{
|
||||
std::cout << std::endl
|
||||
<< "Allocator: " << get_allocator_name<Allocator>::get()
|
||||
<< std::endl
|
||||
<< " push_back ns: "
|
||||
<< float(nseconds)/(num_iterations*num_elements)
|
||||
<< std::endl
|
||||
<< " capacity - alloc calls (new/expand): "
|
||||
<< (unsigned int)capacity << " - "
|
||||
<< (float(numalloc) + float(numexpand))/num_iterations
|
||||
<< "(" << float(numalloc)/num_iterations << "/" << float(numexpand)/num_iterations << ")"
|
||||
<< std::endl;
|
||||
std::cout << '\n'
|
||||
<< " ----------------------------------- "
|
||||
<< std::endl;
|
||||
}
|
||||
boost_cont_trim(0);
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
#define SINGLE_TEST
|
||||
#ifndef SINGLE_TEST
|
||||
#ifdef NDEBUG
|
||||
unsigned int numit [] = { 20000, 200000, 2000000, 20000000 };
|
||||
#else
|
||||
unsigned int numit [] = { 100, 1000, 10000, 100000 };
|
||||
#endif
|
||||
unsigned int numele [] = { 10000, 1000, 100, 10 };
|
||||
#else
|
||||
#ifdef NDEBUG
|
||||
unsigned int numit [] = { 20000 };
|
||||
#else
|
||||
unsigned int numit [] = { 100 };
|
||||
#endif
|
||||
unsigned int numele [] = { 10000 };
|
||||
#endif
|
||||
|
||||
bool csv_output = argc == 2 && (strcmp(argv[1], "--csv-output") == 0);
|
||||
|
||||
if(csv_output){
|
||||
print_header();
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
vector_test_template<StdAllocator>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
vector_test_template<AllocatorPlusV1>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
vector_test_template<AllocatorPlusV2Mask>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
vector_test_template<AllocatorPlusV2>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
std::cout << "\n ----------------------------------- \n"
|
||||
<< " Iterations/Elements: " << numit[i] << "/" << numele[i]
|
||||
<< "\n ----------------------------------- \n";
|
||||
vector_test_template<StdAllocator>(numit[i], numele[i], csv_output);
|
||||
vector_test_template<AllocatorPlusV1>(numit[i], numele[i], csv_output);
|
||||
vector_test_template<AllocatorPlusV2Mask>(numit[i], numele[i], csv_output);
|
||||
vector_test_template<AllocatorPlusV2>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
285
bench/bench_alloc_expand_fwd.cpp
Normal file
285
bench/bench_alloc_expand_fwd.cpp
Normal file
@@ -0,0 +1,285 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable : 4512)
|
||||
#pragma warning (disable : 4267)
|
||||
#pragma warning (disable : 4244)
|
||||
#endif
|
||||
|
||||
#define BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
|
||||
#include <boost/container/allocator.hpp>
|
||||
#include <vector>
|
||||
#include <boost/container/vector.hpp>
|
||||
|
||||
#include <memory> //std::allocator
|
||||
#include <iostream> //std::cout, std::endl
|
||||
#include <cstring> //std::strcmp
|
||||
#include <boost/timer/timer.hpp>
|
||||
using boost::timer::cpu_timer;
|
||||
using boost::timer::cpu_times;
|
||||
using boost::timer::nanosecond_type;
|
||||
|
||||
namespace bc = boost::container;
|
||||
|
||||
typedef std::allocator<int> StdAllocator;
|
||||
typedef bc::allocator<int, 2, bc::expand_bwd | bc::expand_fwd> AllocatorPlusV2Mask;
|
||||
typedef bc::allocator<int, 2> AllocatorPlusV2;
|
||||
typedef bc::allocator<int, 1> AllocatorPlusV1;
|
||||
|
||||
template<class Allocator> struct get_allocator_name;
|
||||
|
||||
template<> struct get_allocator_name<StdAllocator>
|
||||
{ static const char *get() { return "StdAllocator"; } };
|
||||
|
||||
template<> struct get_allocator_name<AllocatorPlusV2Mask>
|
||||
{ static const char *get() { return "AllocatorPlusV2Mask"; } };
|
||||
|
||||
template<> struct get_allocator_name<AllocatorPlusV2>
|
||||
{ static const char *get() { return "AllocatorPlusV2"; } };
|
||||
|
||||
template<> struct get_allocator_name<AllocatorPlusV1>
|
||||
{ static const char *get() { return "AllocatorPlusV1"; } };
|
||||
|
||||
#if defined(BOOST_CONTAINER_VECTOR_ALLOC_STATS)
|
||||
//
|
||||
// stats_traits;
|
||||
//
|
||||
|
||||
template<template<class, class> class Vector>
|
||||
struct stats_traits;
|
||||
|
||||
template<>
|
||||
struct stats_traits<std::vector>
|
||||
{
|
||||
template<class T, class A>
|
||||
static void reset_alloc_stats(std::vector<T, A> &)
|
||||
{}
|
||||
|
||||
template<class T, class A>
|
||||
static std::size_t get_num_alloc(std::vector<T, A> &)
|
||||
{ return 0; }
|
||||
|
||||
template<class T, class A>
|
||||
static std::size_t get_num_expand(std::vector<T, A> &)
|
||||
{ return 0; }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct stats_traits<bc::vector>
|
||||
{
|
||||
template<class T, class A>
|
||||
static void reset_alloc_stats(bc::vector<T, A> &v)
|
||||
{ v.reset_alloc_stats(); }
|
||||
|
||||
template<class T, class A>
|
||||
static std::size_t get_num_alloc(bc::vector<T, A> &v)
|
||||
{ return v.num_alloc; }
|
||||
|
||||
template<class T, class A>
|
||||
static std::size_t get_num_expand(bc::vector<T, A> &v)
|
||||
{ return v.num_expand_fwd; }
|
||||
};
|
||||
|
||||
#endif //BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
|
||||
template<template<class, class> class Vector> struct get_container_name;
|
||||
|
||||
template<> struct get_container_name<std::vector>
|
||||
{ static const char *get() { return "StdVector"; } };
|
||||
|
||||
template<> struct get_container_name<bc::vector>
|
||||
{ static const char *get() { return "BoostContainerVector"; } };
|
||||
|
||||
class MyInt
|
||||
{
|
||||
int int_;
|
||||
|
||||
public:
|
||||
explicit MyInt(int i = 0)
|
||||
: int_(i)
|
||||
{}
|
||||
|
||||
MyInt(const MyInt &other)
|
||||
: int_(other.int_)
|
||||
{}
|
||||
|
||||
MyInt & operator=(const MyInt &other)
|
||||
{
|
||||
int_ = other.int_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~MyInt()
|
||||
{
|
||||
int_ = 0;
|
||||
}
|
||||
};
|
||||
|
||||
template<class Allocator, template <class, class> class Vector>
|
||||
void vector_test_template(unsigned int num_iterations, unsigned int num_elements, bool csv_output)
|
||||
{
|
||||
typedef typename Allocator::template rebind<MyInt>::other IntAllocator;
|
||||
unsigned int numalloc = 0, numexpand = 0;
|
||||
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
typedef stats_traits<Vector> stats_traits_t;
|
||||
#endif
|
||||
|
||||
cpu_timer timer;
|
||||
timer.resume();
|
||||
|
||||
unsigned int capacity = 0;
|
||||
for(unsigned int r = 0; r != num_iterations; ++r){
|
||||
Vector<MyInt, IntAllocator> v;
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
stats_traits_t::reset_alloc_stats(v);
|
||||
#endif
|
||||
//v.reserve(num_elements);
|
||||
//MyInt a[3];
|
||||
/*
|
||||
for(unsigned int e = 0; e != num_elements/3; ++e){
|
||||
v.insert(v.end(), &a[0], &a[0]+3);
|
||||
}*/
|
||||
/*
|
||||
for(unsigned int e = 0; e != num_elements/3; ++e){
|
||||
v.insert(v.end(), 3, MyInt(e));
|
||||
}*/
|
||||
/*
|
||||
for(unsigned int e = 0; e != num_elements/3; ++e){
|
||||
v.insert(v.empty() ? v.end() : --v.end(), &a[0], &a[0]+3);
|
||||
}*/
|
||||
/*
|
||||
for(unsigned int e = 0; e != num_elements/3; ++e){
|
||||
v.insert(v.empty() ? v.end() : --v.end(), 3, MyInt(e));
|
||||
}*/
|
||||
/*
|
||||
for(unsigned int e = 0; e != num_elements/3; ++e){
|
||||
v.insert(v.size() >= 3 ? v.end()-3 : v.begin(), &a[0], &a[0]+3);
|
||||
}*/
|
||||
/*
|
||||
for(unsigned int e = 0; e != num_elements/3; ++e){
|
||||
v.insert(v.size() >= 3 ? v.end()-3 : v.begin(), 3, MyInt(e));
|
||||
}*/
|
||||
/*
|
||||
for(unsigned int e = 0; e != num_elements; ++e){
|
||||
v.insert(v.end(), MyInt(e));
|
||||
}*/
|
||||
/*
|
||||
for(unsigned int e = 0; e != num_elements; ++e){
|
||||
v.insert(v.empty() ? v.end() : --v.end(), MyInt(e));
|
||||
}*/
|
||||
|
||||
for(unsigned int e = 0; e != num_elements; ++e){
|
||||
v.push_back(MyInt(e));
|
||||
}
|
||||
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
numalloc += stats_traits_t::get_num_alloc(v);
|
||||
numexpand += stats_traits_t::get_num_expand(v);
|
||||
#endif
|
||||
capacity = static_cast<unsigned int>(v.capacity());
|
||||
}
|
||||
|
||||
timer.stop();
|
||||
nanosecond_type nseconds = timer.elapsed().wall;
|
||||
|
||||
if(csv_output){
|
||||
std::cout << get_allocator_name<Allocator>::get()
|
||||
<< ";"
|
||||
<< num_iterations
|
||||
<< ";"
|
||||
<< num_elements
|
||||
<< ";"
|
||||
<< capacity
|
||||
<< ";"
|
||||
<< float(nseconds)/(num_iterations*num_elements)
|
||||
<< ";"
|
||||
<< (float(numalloc) + float(numexpand))/num_iterations
|
||||
<< ";"
|
||||
<< float(numalloc)/num_iterations
|
||||
<< ";"
|
||||
<< float(numexpand)/num_iterations
|
||||
<< std::endl;
|
||||
}
|
||||
else{
|
||||
std::cout << std::endl
|
||||
<< "Allocator: " << get_allocator_name<Allocator>::get()
|
||||
<< std::endl
|
||||
<< " push_back ns: "
|
||||
<< float(nseconds)/(num_iterations*num_elements)
|
||||
<< std::endl
|
||||
<< " capacity - alloc calls (new/expand): "
|
||||
<< (unsigned int)capacity << " - "
|
||||
<< (float(numalloc) + float(numexpand))/num_iterations
|
||||
<< "(" << float(numalloc)/num_iterations << "/" << float(numexpand)/num_iterations << ")"
|
||||
<< std::endl << std::endl;
|
||||
}
|
||||
boost_cont_trim(0);
|
||||
}
|
||||
|
||||
void print_header()
|
||||
{
|
||||
std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";"
|
||||
<< "Capacity" << ";" << "push_back(ns)" << ";" << "Allocator calls" << ";"
|
||||
<< "New allocations" << ";" << "Fwd expansions" << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
#define SINGLE_TEST
|
||||
#ifndef SINGLE_TEST
|
||||
#ifdef NDEBUG
|
||||
unsigned int numit [] = { 10000, 100000, 1000000, 10000000 };
|
||||
#else
|
||||
unsigned int numit [] = { 100, 1000, 10000, 100000 };
|
||||
#endif
|
||||
unsigned int numele [] = { 10000, 1000, 100, 10 };
|
||||
#else
|
||||
#ifdef NDEBUG
|
||||
std::size_t numit [] = { 10000 };
|
||||
#else
|
||||
std::size_t numit [] = { 100 };
|
||||
#endif
|
||||
std::size_t numele [] = { 10000 };
|
||||
#endif
|
||||
|
||||
bool csv_output = argc == 2 && (strcmp(argv[1], "--csv-output") == 0);
|
||||
|
||||
if(csv_output){
|
||||
print_header();
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
vector_test_template<StdAllocator, bc::vector>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
vector_test_template<AllocatorPlusV1, bc::vector>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
vector_test_template<AllocatorPlusV2Mask, bc::vector>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
vector_test_template<AllocatorPlusV2, bc::vector>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
std::cout << "\n ----------------------------------- \n"
|
||||
<< " Iterations/Elements: " << numit[i] << "/" << numele[i]
|
||||
<< "\n ----------------------------------- \n";
|
||||
vector_test_template<StdAllocator, std::vector>(numit[i], numele[i], csv_output);
|
||||
vector_test_template<StdAllocator, bc::vector>(numit[i], numele[i], csv_output);
|
||||
vector_test_template<AllocatorPlusV1, bc::vector>(numit[i], numele[i], csv_output);
|
||||
vector_test_template<AllocatorPlusV2Mask, bc::vector>(numit[i], numele[i], csv_output);
|
||||
vector_test_template<AllocatorPlusV2, bc::vector>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
168
bench/bench_alloc_shrink_to_fit.cpp
Normal file
168
bench/bench_alloc_shrink_to_fit.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable : 4512)
|
||||
#endif
|
||||
|
||||
#include <boost/container/allocator.hpp>
|
||||
|
||||
#define BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
|
||||
#include <boost/container/vector.hpp>
|
||||
|
||||
#undef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
|
||||
#include <memory> //std::allocator
|
||||
#include <iostream> //std::cout, std::endl
|
||||
|
||||
#include <boost/timer/timer.hpp>
|
||||
using boost::timer::cpu_timer;
|
||||
using boost::timer::cpu_times;
|
||||
using boost::timer::nanosecond_type;
|
||||
|
||||
namespace bc = boost::container;
|
||||
|
||||
typedef std::allocator<int> StdAllocator;
|
||||
typedef bc::allocator<int, 2> AllocatorPlusV2;
|
||||
typedef bc::allocator<int, 1> AllocatorPlusV1;
|
||||
|
||||
template<class Allocator> struct get_allocator_name;
|
||||
|
||||
template<> struct get_allocator_name<StdAllocator>
|
||||
{ static const char *get() { return "StdAllocator"; } };
|
||||
|
||||
template<> struct get_allocator_name<AllocatorPlusV2>
|
||||
{ static const char *get() { return "AllocatorPlusV2"; } };
|
||||
|
||||
template<> struct get_allocator_name<AllocatorPlusV1>
|
||||
{ static const char *get() { return "AllocatorPlusV1"; } };
|
||||
|
||||
class MyInt
|
||||
{
|
||||
int int_;
|
||||
|
||||
public:
|
||||
MyInt(int i = 0) : int_(i){}
|
||||
|
||||
MyInt(const MyInt &other)
|
||||
: int_(other.int_)
|
||||
{}
|
||||
|
||||
MyInt & operator=(const MyInt &other)
|
||||
{
|
||||
int_ = other.int_;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
void print_header()
|
||||
{
|
||||
std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";"
|
||||
<< "num_shrink" << ";" << "shrink_to_fit(ns)" << std::endl;
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
void vector_test_template(unsigned int num_iterations, unsigned int num_elements, bool csv_output)
|
||||
{
|
||||
typedef typename Allocator::template rebind<MyInt>::other IntAllocator;
|
||||
|
||||
unsigned int capacity = 0;
|
||||
const std::size_t Step = 5;
|
||||
unsigned int num_shrink = 0;
|
||||
(void)capacity;
|
||||
|
||||
cpu_timer timer;
|
||||
timer.resume();
|
||||
|
||||
#ifndef NDEBUG
|
||||
typedef bc::container_detail::integral_constant
|
||||
<unsigned, bc::container_detail::version<Allocator>::value> alloc_version;
|
||||
#endif
|
||||
|
||||
for(unsigned int r = 0; r != num_iterations; ++r){
|
||||
bc::vector<MyInt, IntAllocator> v(num_elements);
|
||||
v.reset_alloc_stats();
|
||||
num_shrink = 0;
|
||||
for(unsigned int e = num_elements; e != 0; e -= Step){
|
||||
v.erase(v.end() - Step, v.end());
|
||||
v.shrink_to_fit();
|
||||
assert( (alloc_version::value != 2) || (e == Step) || (v.num_shrink > num_shrink) );
|
||||
num_shrink = v.num_shrink;
|
||||
}
|
||||
assert(v.empty());
|
||||
assert(0 == v.capacity());
|
||||
}
|
||||
|
||||
timer.stop();
|
||||
nanosecond_type nseconds = timer.elapsed().wall;
|
||||
|
||||
if(csv_output){
|
||||
std::cout << get_allocator_name<Allocator>::get()
|
||||
<< ";"
|
||||
<< num_iterations
|
||||
<< ";"
|
||||
<< num_elements
|
||||
<< ";"
|
||||
<< num_shrink
|
||||
<< ";"
|
||||
<< float(nseconds)/(num_iterations*num_elements)
|
||||
<< std::endl;
|
||||
}
|
||||
else{
|
||||
std::cout << std::endl
|
||||
<< "Allocator: " << get_allocator_name<Allocator>::get()
|
||||
<< std::endl
|
||||
<< " num_shrink: " << num_shrink
|
||||
<< std::endl
|
||||
<< " shrink_to_fit ns: "
|
||||
<< float(nseconds)/(num_iterations*num_elements)
|
||||
<< std::endl << std::endl;
|
||||
}
|
||||
boost_cont_trim(0);
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
#define SINGLE_TEST
|
||||
#ifndef SINGLE_TEST
|
||||
unsigned int numit [] = { 100, 1000, 10000 };
|
||||
unsigned int numele [] = { 10000, 2000, 500 };
|
||||
#else
|
||||
unsigned int numit [] = { 500 };
|
||||
unsigned int numele [] = { 2000 };
|
||||
#endif
|
||||
|
||||
bool csv_output = argc == 2 && (strcmp(argv[1], "--csv-output") == 0);
|
||||
|
||||
if(csv_output){
|
||||
print_header();
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
vector_test_template<StdAllocator>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
vector_test_template<AllocatorPlusV1>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
vector_test_template<AllocatorPlusV2>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
std::cout << "\n ----------------------------------- \n"
|
||||
<< " Iterations/Elements: " << numit[i] << "/" << numele[i]
|
||||
<< "\n ----------------------------------- \n";
|
||||
vector_test_template<StdAllocator>(numit[i], numele[i], csv_output);
|
||||
vector_test_template<AllocatorPlusV1>(numit[i], numele[i], csv_output);
|
||||
vector_test_template<AllocatorPlusV2>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
287
bench/bench_alloc_stable_vector_burst_allocation.cpp
Normal file
287
bench/bench_alloc_stable_vector_burst_allocation.cpp
Normal file
@@ -0,0 +1,287 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable : 4512)
|
||||
#pragma warning (disable : 4541)
|
||||
#pragma warning (disable : 4673)
|
||||
#pragma warning (disable : 4671)
|
||||
#pragma warning (disable : 4244)
|
||||
#endif
|
||||
|
||||
#include <memory> //std::allocator
|
||||
#include <iostream> //std::cout, std::endl
|
||||
#include <vector> //std::vector
|
||||
#include <cstddef> //std::size_t
|
||||
#include <boost/container/allocator.hpp>
|
||||
#include <boost/container/adaptive_pool.hpp>
|
||||
#include <boost/container/stable_vector.hpp>
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/timer/timer.hpp>
|
||||
using boost::timer::cpu_timer;
|
||||
using boost::timer::cpu_times;
|
||||
using boost::timer::nanosecond_type;
|
||||
|
||||
namespace bc = boost::container;
|
||||
|
||||
typedef std::allocator<int> StdAllocator;
|
||||
typedef bc::allocator<int, 1> AllocatorPlusV1;
|
||||
typedef bc::allocator<int, 2> AllocatorPlusV2;
|
||||
typedef bc::adaptive_pool
|
||||
< int
|
||||
, bc::ADP_nodes_per_block
|
||||
, 0//bc::ADP_max_free_blocks
|
||||
, 2
|
||||
, 2> AdPool2PercentV2;
|
||||
|
||||
template<class Allocator> struct get_allocator_name;
|
||||
|
||||
template<> struct get_allocator_name<StdAllocator>
|
||||
{ static const char *get() { return "StdAllocator"; } };
|
||||
|
||||
template<> struct get_allocator_name<AllocatorPlusV1>
|
||||
{ static const char *get() { return "AllocatorPlusV1"; } };
|
||||
|
||||
template<> struct get_allocator_name<AllocatorPlusV2>
|
||||
{ static const char *get() { return "AllocatorPlusV2"; } };
|
||||
|
||||
template<> struct get_allocator_name<AdPool2PercentV2>
|
||||
{ static const char *get() { return "AdPool2PercentV2"; } };
|
||||
|
||||
class MyInt
|
||||
{
|
||||
int int_;
|
||||
|
||||
public:
|
||||
MyInt(int i = 0) : int_(i){}
|
||||
MyInt(const MyInt &other)
|
||||
: int_(other.int_)
|
||||
{}
|
||||
MyInt & operator=(const MyInt &other)
|
||||
{
|
||||
int_ = other.int_;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template<class Allocator>
|
||||
struct get_vector
|
||||
{
|
||||
typedef bc::vector
|
||||
<MyInt, typename Allocator::template rebind<MyInt>::other> type;
|
||||
static const char *vector_name()
|
||||
{
|
||||
return "vector<MyInt>";
|
||||
}
|
||||
};
|
||||
|
||||
template<class Allocator>
|
||||
struct get_stable_vector
|
||||
{
|
||||
typedef bc::stable_vector
|
||||
<MyInt, typename Allocator::template rebind<MyInt>::other> type;
|
||||
static const char *vector_name()
|
||||
{
|
||||
return "stable_vector<MyInt>";
|
||||
}
|
||||
};
|
||||
|
||||
template<template<class> class GetContainer, class Allocator>
|
||||
void stable_vector_test_template(unsigned int num_iterations, unsigned int num_elements, bool csv_output)
|
||||
{
|
||||
typedef typename GetContainer<Allocator>::type vector_type;
|
||||
//std::size_t top_capacity = 0;
|
||||
nanosecond_type nseconds;
|
||||
{
|
||||
{
|
||||
vector_type l;
|
||||
cpu_timer timer;
|
||||
timer.resume();
|
||||
|
||||
for(unsigned int r = 0; r != num_iterations; ++r){
|
||||
l.insert(l.end(), num_elements, MyInt(r));
|
||||
}
|
||||
|
||||
timer.stop();
|
||||
nseconds = timer.elapsed().wall;
|
||||
|
||||
if(csv_output){
|
||||
std::cout << get_allocator_name<Allocator>::get()
|
||||
<< ";"
|
||||
<< GetContainer<Allocator>::vector_name()
|
||||
<< ";"
|
||||
<< num_iterations
|
||||
<< ";"
|
||||
<< num_elements
|
||||
<< ";"
|
||||
<< float(nseconds)/(num_iterations*num_elements)
|
||||
<< ";";
|
||||
}
|
||||
else{
|
||||
std::cout << "Allocator: " << get_allocator_name<Allocator>::get()
|
||||
<< '\t'
|
||||
<< GetContainer<Allocator>::vector_name()
|
||||
<< std::endl
|
||||
<< " allocation ns: "
|
||||
<< float(nseconds)/(num_iterations*num_elements);
|
||||
}
|
||||
// top_capacity = l.capacity();
|
||||
//Now preprocess ranges to erase
|
||||
std::vector<typename vector_type::iterator> ranges_to_erase;
|
||||
ranges_to_erase.push_back(l.begin());
|
||||
for(unsigned int r = 0; r != num_iterations; ++r){
|
||||
typename vector_type::iterator next_pos(ranges_to_erase[r]);
|
||||
std::size_t n = num_elements;
|
||||
while(n--){ ++next_pos; }
|
||||
ranges_to_erase.push_back(next_pos);
|
||||
}
|
||||
|
||||
//Measure range erasure function
|
||||
timer.stop();
|
||||
timer.start();
|
||||
|
||||
for(unsigned int r = 0; r != num_iterations; ++r){
|
||||
std::size_t init_pos = (num_iterations-1)-r;
|
||||
l.erase(ranges_to_erase[init_pos], l.end());
|
||||
}
|
||||
timer.stop();
|
||||
nseconds = timer.elapsed().wall;
|
||||
assert(l.empty());
|
||||
}
|
||||
}
|
||||
|
||||
if(csv_output){
|
||||
std::cout << float(nseconds)/(num_iterations*num_elements)
|
||||
<< std::endl;
|
||||
}
|
||||
else{
|
||||
std::cout << '\t'
|
||||
<< " deallocation ns: "
|
||||
<< float(nseconds)/(num_iterations*num_elements)/*
|
||||
<< std::endl
|
||||
<< " max capacity: "
|
||||
<< static_cast<unsigned int>(top_capacity)
|
||||
<< std::endl
|
||||
<< " remaining cap. "
|
||||
<< static_cast<unsigned int>(top_capacity - num_iterations*num_elements)
|
||||
<< " (" << (float(top_capacity)/float(num_iterations*num_elements) - 1)*100 << " %)"*/
|
||||
<< std::endl << std::endl;
|
||||
}
|
||||
assert(boost_cont_all_deallocated());
|
||||
boost_cont_trim(0);
|
||||
}
|
||||
|
||||
void print_header()
|
||||
{
|
||||
std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";"
|
||||
<< "Insertion time(ns)" << ";" << "Erasure time(ns)" << ";"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
void stable_vector_operations()
|
||||
{
|
||||
{
|
||||
bc::stable_vector<int> a(bc::stable_vector<int>::size_type(5), 4);
|
||||
bc::stable_vector<int> b(a);
|
||||
bc::stable_vector<int> c(a.cbegin(), a.cend());
|
||||
b.insert(b.cend(), 0);
|
||||
c.pop_back();
|
||||
a.assign(b.cbegin(), b.cend());
|
||||
a.assign(c.cbegin(), c.cend());
|
||||
a.assign(1, 2);
|
||||
}
|
||||
{
|
||||
typedef bc::stable_vector<int, std::allocator<int> > stable_vector_t;
|
||||
stable_vector_t a(bc::stable_vector<int>::size_type(5), 4);
|
||||
stable_vector_t b(a);
|
||||
stable_vector_t c(a.cbegin(), a.cend());
|
||||
b.insert(b.cend(), 0);
|
||||
c.pop_back();
|
||||
assert(static_cast<std::size_t>(a.end() - a.begin()) == a.size());
|
||||
a.assign(b.cbegin(), b.cend());
|
||||
assert(static_cast<std::size_t>(a.end() - a.begin()) == a.size());
|
||||
a.assign(c.cbegin(), c.cend());
|
||||
assert(static_cast<std::size_t>(a.end() - a.begin()) == a.size());
|
||||
a.assign(1, 2);
|
||||
assert(static_cast<std::size_t>(a.end() - a.begin()) == a.size());
|
||||
a.reserve(100);
|
||||
assert(static_cast<std::size_t>(a.end() - a.begin()) == a.size());
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
#define SINGLE_TEST
|
||||
#ifndef SINGLE_TEST
|
||||
#ifdef NDEBUG
|
||||
unsigned int numit [] = { 400, 4000, 40000, 400000 };
|
||||
#else
|
||||
unsigned int numit [] = { 4, 40, 400, 4000 };
|
||||
#endif
|
||||
unsigned int numele [] = { 10000, 1000, 100, 10 };
|
||||
#else
|
||||
#ifdef NDEBUG
|
||||
unsigned int numit [] = { 400 };
|
||||
#else
|
||||
unsigned int numit [] = { 4 };
|
||||
#endif
|
||||
unsigned int numele [] = { 10000 };
|
||||
#endif
|
||||
|
||||
//Warning: range erasure is buggy. Vector iterators are not stable, so it is not
|
||||
//possible to cache iterators, but indexes!!!
|
||||
|
||||
bool csv_output = argc == 2 && (strcmp(argv[1], "--csv-output") == 0);
|
||||
|
||||
if(csv_output){
|
||||
print_header();
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
stable_vector_test_template<get_stable_vector, StdAllocator>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
stable_vector_test_template<get_vector, StdAllocator>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
stable_vector_test_template<get_stable_vector, AllocatorPlusV1>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
stable_vector_test_template<get_vector, AllocatorPlusV1>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
stable_vector_test_template<get_stable_vector, AllocatorPlusV2>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
stable_vector_test_template<get_vector, AllocatorPlusV2>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
stable_vector_test_template<get_stable_vector, AdPool2PercentV2>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
stable_vector_test_template<get_vector, AdPool2PercentV2>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
|
||||
std::cout << "\n ----------------------------------- \n"
|
||||
<< " Iterations/Elements: " << numit[i] << "/" << numele[i]
|
||||
<< "\n ----------------------------------- \n";
|
||||
stable_vector_test_template<get_stable_vector, StdAllocator>(numit[i], numele[i], csv_output);
|
||||
stable_vector_test_template<get_vector, StdAllocator>(numit[i], numele[i], csv_output);
|
||||
stable_vector_test_template<get_stable_vector, AllocatorPlusV1>(numit[i], numele[i], csv_output);
|
||||
stable_vector_test_template<get_vector, AllocatorPlusV1>(numit[i], numele[i], csv_output);
|
||||
stable_vector_test_template<get_stable_vector, AllocatorPlusV2>(numit[i], numele[i], csv_output);
|
||||
stable_vector_test_template<get_vector, AllocatorPlusV2>(numit[i], numele[i], csv_output);
|
||||
stable_vector_test_template<get_stable_vector, AdPool2PercentV2>(numit[i], numele[i], csv_output);
|
||||
stable_vector_test_template<get_vector, AdPool2PercentV2>(numit[i], numele[i], csv_output);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
29
bench/bench_flat_multiset.cpp
Normal file
29
bench/bench_flat_multiset.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "boost/container/set.hpp"
|
||||
#include "boost/container/flat_set.hpp"
|
||||
#include "bench_set.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
|
||||
fill_range_ints();
|
||||
fill_range_strings();
|
||||
|
||||
//flat_set vs set
|
||||
launch_tests< flat_multiset<int> , multiset<int> >
|
||||
("flat_multiset<int>", "multiset<int>");
|
||||
launch_tests< flat_multiset<string> , multiset<string> >
|
||||
("flat_multiset<string>", "multiset<string>");
|
||||
|
||||
return 0;
|
||||
}
|
||||
29
bench/bench_flat_set.cpp
Normal file
29
bench/bench_flat_set.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "boost/container/set.hpp"
|
||||
#include "boost/container/flat_set.hpp"
|
||||
#include "bench_set.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
|
||||
fill_range_ints();
|
||||
fill_range_strings();
|
||||
|
||||
//flat_set vs set
|
||||
launch_tests< flat_set<int> , set<int> >
|
||||
("flat_set<int>", "set<int>");
|
||||
launch_tests< flat_set<string> , set<string> >
|
||||
("flat_set<string>", "set<string>");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -9,340 +9,27 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "boost/container/set.hpp"
|
||||
#include "boost/container/flat_set.hpp"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <boost/timer/timer.hpp>
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
|
||||
using boost::timer::cpu_timer;
|
||||
using boost::timer::cpu_times;
|
||||
using boost::timer::nanosecond_type;
|
||||
|
||||
#ifdef NDEBUG
|
||||
static const std::size_t N = 5000;
|
||||
#else
|
||||
static const std::size_t N = 500;
|
||||
#endif
|
||||
|
||||
void compare_times(cpu_times time_numerator, cpu_times time_denominator){
|
||||
std::cout << "----------------------------------------------" << '\n';
|
||||
std::cout << " wall = " << ((double)time_numerator.wall/(double)time_denominator.wall) << std::endl;
|
||||
std::cout << "----------------------------------------------" << '\n' << std::endl;
|
||||
}
|
||||
|
||||
std::vector<int> sorted_unique_range;
|
||||
std::vector<int> sorted_range;
|
||||
std::vector<int> random_unique_range;
|
||||
std::vector<int> random_range;
|
||||
|
||||
void fill_ranges()
|
||||
{
|
||||
sorted_unique_range.resize(N);
|
||||
sorted_range.resize(N);
|
||||
random_unique_range.resize(N);
|
||||
random_range.resize(N);
|
||||
std::srand (0);
|
||||
//random_range
|
||||
std::generate(random_unique_range.begin(), random_unique_range.end(), std::rand);
|
||||
random_unique_range.erase(std::unique(random_unique_range.begin(), random_unique_range.end()), random_unique_range.end());
|
||||
//random_range
|
||||
random_range = random_unique_range;
|
||||
random_range.insert(random_range.end(), random_unique_range.begin(), random_unique_range.end());
|
||||
//sorted_unique_range
|
||||
for(std::size_t i = 0, max = sorted_unique_range.size(); i != max; ++i){
|
||||
sorted_unique_range[i] = static_cast<int>(i);
|
||||
}
|
||||
//sorted_range
|
||||
sorted_range = sorted_unique_range;
|
||||
sorted_range.insert(sorted_range.end(), sorted_unique_range.begin(), sorted_unique_range.end());
|
||||
std::sort(sorted_range.begin(), sorted_range.end());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
cpu_times construct_time()
|
||||
{
|
||||
cpu_timer sur_timer, sr_timer, rur_timer, rr_timer, copy_timer, assign_timer, destroy_timer;
|
||||
//sur_timer.stop();sr_timer.stop();rur_timer.stop();rr_timer.stop();destroy_timer.stop();
|
||||
|
||||
cpu_timer total_time;
|
||||
total_time.resume();
|
||||
|
||||
for(std::size_t i = 0; i != N; ++i){
|
||||
{
|
||||
sur_timer.resume();
|
||||
T t(sorted_unique_range.begin(), sorted_unique_range.end());
|
||||
sur_timer.stop();
|
||||
}
|
||||
{
|
||||
sr_timer.resume();
|
||||
T t(sorted_range.begin(), sorted_range.end());
|
||||
sr_timer.stop();
|
||||
copy_timer.resume();
|
||||
T taux(t);
|
||||
copy_timer.stop();
|
||||
assign_timer.resume();
|
||||
t = taux;;
|
||||
assign_timer.stop();
|
||||
}
|
||||
{
|
||||
rur_timer.resume();
|
||||
T t(random_unique_range.begin(), random_unique_range.end());
|
||||
rur_timer.stop();
|
||||
}
|
||||
{
|
||||
rr_timer.resume();
|
||||
T t(random_range.begin(), random_range.end());
|
||||
rr_timer.stop();
|
||||
destroy_timer.resume();
|
||||
}
|
||||
destroy_timer.stop();
|
||||
}
|
||||
total_time.stop();
|
||||
|
||||
std::cout << " Construct sorted_unique_range " << boost::timer::format(sur_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Construct sorted_range " << boost::timer::format(sr_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Copy sorted range " << boost::timer::format(copy_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Assign sorted range " << boost::timer::format(assign_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Construct random_unique_range " << boost::timer::format(rur_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Construct random_range " << boost::timer::format(rr_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Destroy " << boost::timer::format(destroy_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Total time = " << boost::timer::format(total_time.elapsed(), boost::timer::default_places, "%ws wall\n") << std::endl;
|
||||
return total_time.elapsed();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
cpu_times insert_time()
|
||||
{
|
||||
cpu_timer sur_timer,sr_timer,rur_timer,rr_timer,destroy_timer;
|
||||
sur_timer.stop();sr_timer.stop();rur_timer.stop();rr_timer.stop();
|
||||
|
||||
cpu_timer total_time;
|
||||
total_time.resume();
|
||||
|
||||
for(std::size_t i = 0; i != N; ++i){
|
||||
{
|
||||
sur_timer.resume();
|
||||
T t;
|
||||
t.insert(sorted_unique_range.begin(), sorted_unique_range.end());
|
||||
sur_timer.stop();
|
||||
}
|
||||
{
|
||||
sr_timer.resume();
|
||||
T t;
|
||||
t.insert(sorted_range.begin(), sorted_range.end());
|
||||
sr_timer.stop();
|
||||
}
|
||||
{
|
||||
rur_timer.resume();
|
||||
T t;
|
||||
t.insert(random_unique_range.begin(), random_unique_range.end());
|
||||
rur_timer.stop();
|
||||
}
|
||||
{
|
||||
rr_timer.resume();
|
||||
T t;
|
||||
t.insert(random_range.begin(), random_range.end());
|
||||
rr_timer.stop();
|
||||
}
|
||||
}
|
||||
total_time.stop();
|
||||
|
||||
std::cout << " Insert sorted_unique_range " << boost::timer::format(sur_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Insert sorted_range " << boost::timer::format(sr_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Insert random_unique_range " << boost::timer::format(rur_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Insert random_range " << boost::timer::format(rr_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Total time = " << boost::timer::format(total_time.elapsed(), boost::timer::default_places, "%ws wall\n") << std::endl;
|
||||
return total_time.elapsed();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
cpu_times search_time()
|
||||
{
|
||||
cpu_timer find_timer, lower_timer, upper_timer, equal_range_timer, count_timer;
|
||||
|
||||
T t(sorted_unique_range.begin(), sorted_unique_range.end());
|
||||
|
||||
cpu_timer total_time;
|
||||
total_time.resume();
|
||||
|
||||
for(std::size_t i = 0; i != N; ++i){
|
||||
//Find
|
||||
{
|
||||
std::size_t found = 0;
|
||||
find_timer.resume();
|
||||
for(std::size_t i = 0, max = sorted_unique_range.size(); i != max; ++i){
|
||||
found += static_cast<std::size_t>(t.end() != t.find(sorted_unique_range[i]));
|
||||
}
|
||||
for(std::size_t i = 0, max = sorted_unique_range.size(); i != max; ++i){
|
||||
found += static_cast<std::size_t>(t.end() != t.find(sorted_unique_range[i]));
|
||||
}
|
||||
find_timer.stop();
|
||||
if(found/2 != t.size()){
|
||||
std::cout << "ERROR! all elements not found" << std::endl;
|
||||
}
|
||||
}
|
||||
//Lower
|
||||
{
|
||||
std::size_t found = 0;
|
||||
lower_timer.resume();
|
||||
for(std::size_t i = 0, max = sorted_unique_range.size(); i != max; ++i){
|
||||
found += static_cast<std::size_t>(t.end() != t.lower_bound(sorted_unique_range[i]));
|
||||
}
|
||||
for(std::size_t i = 0, max = sorted_unique_range.size(); i != max; ++i){
|
||||
found += static_cast<std::size_t>(t.end() != t.lower_bound(sorted_unique_range[i]));
|
||||
}
|
||||
lower_timer.stop();
|
||||
if(found/2 != t.size()){
|
||||
std::cout << "ERROR! all elements not found" << std::endl;
|
||||
}
|
||||
}
|
||||
//Upper
|
||||
{
|
||||
std::size_t found = 0;
|
||||
upper_timer.resume();
|
||||
for(std::size_t i = 0, max = sorted_unique_range.size(); i != max; ++i){
|
||||
found += static_cast<std::size_t>(t.end() != t.upper_bound(sorted_unique_range[i]));
|
||||
}
|
||||
for(std::size_t i = 0, max = sorted_unique_range.size(); i != max; ++i){
|
||||
found += static_cast<std::size_t>(t.end() != t.upper_bound(sorted_unique_range[i]));
|
||||
}
|
||||
upper_timer.stop();
|
||||
if(found/2 != (t.size()-1)){
|
||||
std::cout << "ERROR! all elements not found" << std::endl;
|
||||
}
|
||||
}
|
||||
//Equal
|
||||
{
|
||||
std::size_t found = 0;
|
||||
std::pair<typename T::iterator,typename T::iterator> ret;
|
||||
equal_range_timer.resume();
|
||||
for(std::size_t i = 0, max = sorted_unique_range.size(); i != max; ++i){
|
||||
ret = t.equal_range(sorted_unique_range[i]);
|
||||
found += static_cast<std::size_t>(ret.first != ret.second);
|
||||
}
|
||||
for(std::size_t i = 0, max = sorted_unique_range.size(); i != max; ++i){
|
||||
ret = t.equal_range(sorted_unique_range[i]);
|
||||
found += static_cast<std::size_t>(ret.first != ret.second);
|
||||
}
|
||||
equal_range_timer.stop();
|
||||
if(found/2 != t.size()){
|
||||
std::cout << "ERROR! all elements not found" << std::endl;
|
||||
}
|
||||
}
|
||||
//Count
|
||||
{
|
||||
std::size_t found = 0;
|
||||
std::pair<typename T::iterator,typename T::iterator> ret;
|
||||
count_timer.resume();
|
||||
for(std::size_t i = 0, max = sorted_unique_range.size(); i != max; ++i){
|
||||
found += static_cast<std::size_t>(t.count(sorted_unique_range[i]));
|
||||
}
|
||||
for(std::size_t i = 0, max = sorted_unique_range.size(); i != max; ++i){
|
||||
found += static_cast<std::size_t>(t.count(sorted_unique_range[i]));
|
||||
}
|
||||
count_timer.stop();
|
||||
if(found/2 != t.size()){
|
||||
std::cout << "ERROR! all elements not found" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
total_time.stop();
|
||||
|
||||
std::cout << " Find " << boost::timer::format(find_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Lower Bound " << boost::timer::format(lower_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Upper Bound " << boost::timer::format(upper_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Equal Range " << boost::timer::format(equal_range_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Count " << boost::timer::format(count_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Total time = " << boost::timer::format(total_time.elapsed(), boost::timer::default_places, "%ws wall\n") << std::endl;
|
||||
return total_time.elapsed();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void extensions_time()
|
||||
{
|
||||
cpu_timer sur_timer,sur_opt_timer;
|
||||
sur_timer.stop();sur_opt_timer.stop();
|
||||
|
||||
for(std::size_t i = 0; i != N; ++i){
|
||||
{
|
||||
sur_timer.resume();
|
||||
T t(sorted_unique_range.begin(), sorted_unique_range.end());
|
||||
sur_timer.stop();
|
||||
}
|
||||
{
|
||||
sur_opt_timer.resume();
|
||||
T t(boost::container::ordered_unique_range, sorted_unique_range.begin(), sorted_unique_range.end());
|
||||
sur_opt_timer.stop();
|
||||
}
|
||||
|
||||
}
|
||||
std::cout << " Construct sorted_unique_range " << boost::timer::format(sur_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << " Construct sorted_unique_range (extension) " << boost::timer::format(sur_opt_timer.elapsed(), boost::timer::default_places, "%ws wall\n");
|
||||
std::cout << "Total time (Extension/Standard):\n";
|
||||
compare_times(sur_opt_timer.elapsed(), sur_timer.elapsed());
|
||||
}
|
||||
|
||||
template<class BoostClass, class StdClass>
|
||||
void launch_tests(const char *BoostContName, const char *StdContName)
|
||||
{
|
||||
try {
|
||||
fill_ranges();
|
||||
{
|
||||
std::cout << "Construct benchmark:" << BoostContName << std::endl;
|
||||
cpu_times boost_set_time = construct_time< BoostClass >();
|
||||
|
||||
std::cout << "Construct benchmark:" << StdContName << std::endl;
|
||||
cpu_times std_set_time = construct_time< StdClass >();
|
||||
|
||||
std::cout << "Total time (" << BoostContName << "/" << StdContName << "):\n";
|
||||
compare_times(boost_set_time, std_set_time);
|
||||
}
|
||||
{
|
||||
std::cout << "Insert benchmark:" << BoostContName << std::endl;
|
||||
cpu_times boost_set_time = insert_time< BoostClass >();
|
||||
|
||||
std::cout << "Insert benchmark:" << StdContName << std::endl;
|
||||
cpu_times std_set_time = insert_time< StdClass >();
|
||||
|
||||
std::cout << "Total time (" << BoostContName << "/" << StdContName << "):\n";
|
||||
compare_times(boost_set_time, std_set_time);
|
||||
}
|
||||
{
|
||||
std::cout << "Search benchmark:" << BoostContName << std::endl;
|
||||
cpu_times boost_set_time = search_time< BoostClass >();
|
||||
|
||||
std::cout << "Search benchmark:" << StdContName << std::endl;
|
||||
cpu_times std_set_time = search_time< StdClass >();
|
||||
|
||||
std::cout << "Total time (" << BoostContName << "/" << StdContName << "):\n";
|
||||
compare_times(boost_set_time, std_set_time);
|
||||
}
|
||||
{
|
||||
std::cout << "Extensions benchmark:" << BoostContName << std::endl;
|
||||
extensions_time< BoostClass >();
|
||||
}
|
||||
|
||||
}catch(std::exception e){
|
||||
std::cout << e.what();
|
||||
}
|
||||
}
|
||||
#include "bench_set.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
|
||||
fill_range_ints();
|
||||
fill_range_strings();
|
||||
|
||||
//set vs std::set
|
||||
launch_tests< boost::container::set<int> , std::set<int> >
|
||||
("boost::container::set<int>", "std::set<int>");/*
|
||||
//multiset vs std::set
|
||||
launch_tests< boost::container::multiset<int> , std::multiset<int> >
|
||||
("boost::container::multiset<int>", "std::multiset<int>");*/
|
||||
//flat_set vs set
|
||||
//launch_tests< boost::container::flat_set<int> , boost::container::set<int> >
|
||||
//("boost::container::flat_set<int>", "boost::container::set<int>");
|
||||
//flat_multiset vs multiset
|
||||
//launch_tests< boost::container::flat_multiset<int> , boost::container::multiset<int> >
|
||||
//("boost::container::flat_multiset<int>", "boost::container::multiset<int>");
|
||||
return 1;
|
||||
launch_tests< set<int> , std::set<int> >
|
||||
("set<int>", "std::set<int>");
|
||||
launch_tests< set<string> , std::set<string> >
|
||||
("set<string>", "std::set<string>");
|
||||
|
||||
//set(sizeopt) vs set(!sizeopt)
|
||||
launch_tests< set<int>, set<int, std::less<int>, std::allocator<int>, tree_assoc_options< optimize_size<false> >::type > >
|
||||
("set<int>(sizeopt=true)", "set<int>(sizeopt=false)");
|
||||
launch_tests< set<string>, set<string, std::less<string>, std::allocator<string>, tree_assoc_options< optimize_size<false> >::type > >
|
||||
("set<string>(sizeopt=true)", "set<string>(sizeopt=false)");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
462
bench/bench_set.hpp
Normal file
462
bench/bench_set.hpp
Normal file
@@ -0,0 +1,462 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2014. 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_BENCH_BENCH_SET_HPP
|
||||
#define BOOST_CONTAINER_BENCH_BENCH_SET_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/timer/timer.hpp>
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/container/string.hpp>
|
||||
|
||||
using boost::timer::cpu_timer;
|
||||
using boost::timer::cpu_times;
|
||||
using boost::timer::nanosecond_type;
|
||||
using namespace boost::container;
|
||||
|
||||
#ifdef NDEBUG
|
||||
static const std::size_t NElements = 1000;
|
||||
#else
|
||||
static const std::size_t NElements = 100;
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
static const std::size_t NIter = 500;
|
||||
#else
|
||||
static const std::size_t NIter = 50;
|
||||
#endif
|
||||
|
||||
void compare_times(cpu_times time_numerator, cpu_times time_denominator){
|
||||
std::cout << ((double)time_numerator.wall/(double)time_denominator.wall) << std::endl;
|
||||
std::cout << "----------------------------------------------" << '\n' << std::endl;
|
||||
}
|
||||
|
||||
vector<int> sorted_unique_range_int;
|
||||
vector<int> sorted_range_int;
|
||||
vector<int> random_unique_range_int;
|
||||
vector<int> random_range_int;
|
||||
|
||||
void fill_range_ints()
|
||||
{
|
||||
//sorted_unique_range_int
|
||||
sorted_unique_range_int.resize(NElements);
|
||||
for(std::size_t i = 0, max = sorted_unique_range_int.size(); i != max; ++i){
|
||||
sorted_unique_range_int[i] = static_cast<int>(i);
|
||||
}
|
||||
//sorted_range_int
|
||||
sorted_range_int = sorted_unique_range_int;
|
||||
sorted_range_int.insert(sorted_range_int.end(), sorted_unique_range_int.begin(), sorted_unique_range_int.end());
|
||||
std::sort(sorted_range_int.begin(), sorted_range_int.end());
|
||||
|
||||
//random_range_int
|
||||
std::srand(0);
|
||||
random_range_int.assign(sorted_range_int.begin(), sorted_range_int.end());
|
||||
std::random_shuffle(random_range_int.begin(), random_range_int.end());
|
||||
//random_unique_range_int
|
||||
std::srand(0);
|
||||
random_unique_range_int.assign(sorted_unique_range_int.begin(), sorted_unique_range_int.end());
|
||||
std::random_shuffle(random_unique_range_int.begin(), random_unique_range_int.end());
|
||||
}
|
||||
|
||||
vector<string> sorted_unique_range_string;
|
||||
vector<string> sorted_range_string;
|
||||
vector<string> random_unique_range_string;
|
||||
vector<string> random_range_string;
|
||||
|
||||
void fill_range_strings()
|
||||
{
|
||||
//sorted_unique_range_int
|
||||
sorted_unique_range_string.resize(NElements);
|
||||
for(std::size_t i = 0, max = sorted_unique_range_string.size(); i != max; ++i){
|
||||
std::stringstream sstr;
|
||||
sstr << std::setfill('0') << std::setw(10) << i;
|
||||
sorted_unique_range_string[i] = "really_long_long_prefix_to_ssb_and_increase_comparison_costs_";
|
||||
const std::string &s = sstr.str();
|
||||
sorted_unique_range_string[i].append(s.begin(), s.end());
|
||||
}
|
||||
//sorted_range_string
|
||||
sorted_range_string = sorted_unique_range_string;
|
||||
sorted_range_string.insert(sorted_range_string.end(), sorted_unique_range_string.begin(), sorted_unique_range_string.end());
|
||||
std::sort(sorted_range_string.begin(), sorted_range_string.end());
|
||||
|
||||
//random_range_string
|
||||
std::srand(0);
|
||||
random_range_string.assign(sorted_range_string.begin(), sorted_range_string.end());
|
||||
std::random_shuffle(random_range_string.begin(), random_range_string.end());
|
||||
//random_unique_range_string
|
||||
std::srand(0);
|
||||
random_unique_range_string.assign(sorted_unique_range_string.begin(), sorted_unique_range_string.end());
|
||||
std::random_shuffle(random_unique_range_string.begin(), random_unique_range_string.end());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
struct range_provider;
|
||||
|
||||
template<>
|
||||
struct range_provider<int>
|
||||
{
|
||||
typedef vector<int> type;
|
||||
|
||||
static type &sorted_unique()
|
||||
{ return sorted_unique_range_int; }
|
||||
|
||||
static type &sorted()
|
||||
{ return sorted_range_int; }
|
||||
|
||||
static type &random_unique()
|
||||
{ return random_unique_range_int; }
|
||||
|
||||
static type &random()
|
||||
{ return random_range_int; }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_provider<string>
|
||||
{
|
||||
typedef vector<string> type;
|
||||
|
||||
static type &sorted_unique()
|
||||
{ return sorted_unique_range_string; }
|
||||
|
||||
static type &sorted()
|
||||
{ return sorted_range_string; }
|
||||
|
||||
static type &random_unique()
|
||||
{ return random_unique_range_string; }
|
||||
|
||||
static type &random()
|
||||
{ return random_range_string; }
|
||||
};
|
||||
|
||||
template<typename C>
|
||||
cpu_times copy_destroy_time(vector<typename C::value_type> &unique_range)
|
||||
{
|
||||
cpu_timer copy_timer, assign_timer, destroy_timer;
|
||||
|
||||
cpu_timer total_time;
|
||||
|
||||
for(std::size_t i = 0; i != NIter; ++i){
|
||||
{
|
||||
C c(unique_range.begin(), unique_range.end());
|
||||
total_time.resume();
|
||||
copy_timer.resume();
|
||||
C caux(c);
|
||||
copy_timer.stop();
|
||||
assign_timer.resume();
|
||||
c = caux;
|
||||
assign_timer.stop();
|
||||
destroy_timer.resume();
|
||||
}
|
||||
destroy_timer.stop();
|
||||
total_time.stop();
|
||||
}
|
||||
total_time.stop();
|
||||
|
||||
std::cout << " Copy sorted range " << boost::timer::format(copy_timer.elapsed(), boost::timer::default_places, "%ws\n");
|
||||
std::cout << " Assign sorted range " << boost::timer::format(assign_timer.elapsed(), boost::timer::default_places, "%ws\n");
|
||||
std::cout << " Destroy " << boost::timer::format(destroy_timer.elapsed(), boost::timer::default_places, "%ws\n");
|
||||
std::cout << " Total time = " << boost::timer::format(total_time.elapsed(), boost::timer::default_places, "%ws\n") << std::endl;
|
||||
return total_time.elapsed();
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
cpu_times construct_time(vector<typename C::value_type> &unique_range, vector<typename C::value_type> &range, const char *RangeType)
|
||||
{
|
||||
cpu_timer sur_timer, sr_timer;
|
||||
|
||||
cpu_timer total_time;
|
||||
|
||||
for(std::size_t i = 0; i != NIter; ++i){
|
||||
{
|
||||
sur_timer.resume();
|
||||
total_time.resume();
|
||||
C c(unique_range.begin(), unique_range.end());
|
||||
sur_timer.stop();
|
||||
total_time.stop();
|
||||
}
|
||||
{
|
||||
total_time.resume();
|
||||
sr_timer.resume();
|
||||
C c(range.begin(), range.end());
|
||||
sr_timer.stop();
|
||||
total_time.stop();
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << " Construct " << RangeType << " unique_range " << boost::timer::format(sur_timer.elapsed(), boost::timer::default_places, "%ws\n");
|
||||
std::cout << " Construct " << RangeType << " range " << boost::timer::format(sr_timer.elapsed(), boost::timer::default_places, "%ws\n");
|
||||
std::cout << " Total time = " << boost::timer::format(total_time.elapsed(), boost::timer::default_places, "%ws\n") << std::endl;
|
||||
return total_time.elapsed();
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
cpu_times insert_time(vector<typename C::value_type> &unique_range, vector<typename C::value_type> &range, const char *RangeType)
|
||||
{
|
||||
cpu_timer ur_timer,r_timer;
|
||||
ur_timer.stop();r_timer.stop();
|
||||
|
||||
cpu_timer total_time;
|
||||
total_time.resume();
|
||||
|
||||
for(std::size_t i = 0; i != NIter; ++i){
|
||||
{
|
||||
total_time.resume();
|
||||
ur_timer.resume();
|
||||
C c;
|
||||
c.insert(unique_range.begin(), unique_range.end());
|
||||
ur_timer.stop();
|
||||
total_time.stop();
|
||||
}
|
||||
{
|
||||
total_time.resume();
|
||||
r_timer.resume();
|
||||
C c;
|
||||
c.insert(range.begin(), range.end());
|
||||
r_timer.stop();
|
||||
total_time.stop();
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << " Insert " << RangeType << " unique_range " << boost::timer::format(ur_timer.elapsed(), boost::timer::default_places, "%ws\n");
|
||||
std::cout << " Insert " << RangeType << " range " << boost::timer::format(r_timer.elapsed(), boost::timer::default_places, "%ws\n");
|
||||
std::cout << " Total time = " << boost::timer::format(total_time.elapsed(), boost::timer::default_places, "%ws\n") << std::endl;
|
||||
return total_time.elapsed();
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
bool check_not_end(vector<Iterator> &iterators, Iterator itend, std::size_t number_of_ends = 0)
|
||||
{
|
||||
std::size_t end_count = 0;
|
||||
for(std::size_t i = 0, max = iterators.size(); i != max; ++i){
|
||||
if(iterators[i] == itend && (++end_count > number_of_ends) )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
bool check_all_not_empty(vector< std::pair<Iterator, Iterator > > &iterator_pairs)
|
||||
{
|
||||
for(std::size_t i = 0, max = iterator_pairs.size(); i != max; ++i){
|
||||
if(iterator_pairs[i].first == iterator_pairs[i].second)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
cpu_times search_time(vector<typename C::value_type> &unique_range, const char *RangeType)
|
||||
{
|
||||
cpu_timer find_timer, lower_timer, upper_timer, equal_range_timer, count_timer;
|
||||
|
||||
C c(unique_range.begin(), unique_range.end());
|
||||
|
||||
cpu_timer total_time;
|
||||
total_time.resume();
|
||||
|
||||
vector<typename C::iterator> v_it(NElements);
|
||||
vector< std::pair<typename C::iterator, typename C::iterator> > v_itp(NElements);
|
||||
|
||||
for(std::size_t i = 0; i != NIter; ++i){
|
||||
//Find
|
||||
{
|
||||
find_timer.resume();
|
||||
for(std::size_t rep = 0; rep != 2; ++rep)
|
||||
for(std::size_t i = 0, max = unique_range.size(); i != max; ++i){
|
||||
v_it[i] = c.find(unique_range[i]);
|
||||
}
|
||||
find_timer.stop();
|
||||
if(!check_not_end(v_it, c.end())){
|
||||
std::cout << "ERROR! find all elements not found" << std::endl;
|
||||
}
|
||||
}
|
||||
//Lower
|
||||
{
|
||||
lower_timer.resume();
|
||||
for(std::size_t rep = 0; rep != 2; ++rep)
|
||||
for(std::size_t i = 0, max = unique_range.size(); i != max; ++i){
|
||||
v_it[i] = c.lower_bound(unique_range[i]);
|
||||
}
|
||||
lower_timer.stop();
|
||||
if(!check_not_end(v_it, c.end())){
|
||||
std::cout << "ERROR! lower_bound all elements not found" << std::endl;
|
||||
}
|
||||
}
|
||||
//Upper
|
||||
{
|
||||
upper_timer.resume();
|
||||
for(std::size_t rep = 0; rep != 2; ++rep)
|
||||
for(std::size_t i = 0, max = unique_range.size(); i != max; ++i){
|
||||
v_it[i] = c.upper_bound(unique_range[i]);
|
||||
}
|
||||
upper_timer.stop();
|
||||
if(!check_not_end(v_it, c.end(), 1u)){
|
||||
std::cout << "ERROR! upper_bound all elements not found" << std::endl;
|
||||
}
|
||||
}
|
||||
//Equal
|
||||
{
|
||||
equal_range_timer.resume();
|
||||
for(std::size_t rep = 0; rep != 2; ++rep)
|
||||
for(std::size_t i = 0, max = unique_range.size(); i != max; ++i){
|
||||
v_itp[i] = c.equal_range(unique_range[i]);
|
||||
}
|
||||
equal_range_timer.stop();
|
||||
if(!check_all_not_empty(v_itp)){
|
||||
std::cout << "ERROR! equal_range all elements not found" << std::endl;
|
||||
}
|
||||
}
|
||||
//Count
|
||||
{
|
||||
std::size_t count = 0;
|
||||
count_timer.resume();
|
||||
for(std::size_t rep = 0; rep != 2; ++rep)
|
||||
for(std::size_t i = 0, max = unique_range.size(); i != max; ++i){
|
||||
count += c.count(unique_range[i]);
|
||||
}
|
||||
count_timer.stop();
|
||||
if(count/2 != c.size()){
|
||||
std::cout << "ERROR! count all elements not found" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
total_time.stop();
|
||||
|
||||
std::cout << " Find " << RangeType << " " << boost::timer::format(find_timer.elapsed(), boost::timer::default_places, "%ws\n");
|
||||
std::cout << " Lower Bound " << RangeType << " " << boost::timer::format(lower_timer.elapsed(), boost::timer::default_places, "%ws\n");
|
||||
std::cout << " Upper Bound " << RangeType << " " << boost::timer::format(upper_timer.elapsed(), boost::timer::default_places, "%ws\n");
|
||||
std::cout << " Equal Range " << RangeType << " " << boost::timer::format(equal_range_timer.elapsed(), boost::timer::default_places, "%ws\n");
|
||||
std::cout << " Count " << RangeType << " " << boost::timer::format(count_timer.elapsed(), boost::timer::default_places, "%ws\n");
|
||||
std::cout << " Total time = " << boost::timer::format(total_time.elapsed(), boost::timer::default_places, "%ws\n") << std::endl;
|
||||
return total_time.elapsed();
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
void extensions_time(vector<typename C::value_type> &sorted_unique_range)
|
||||
{
|
||||
cpu_timer sur_timer,sur_opt_timer;
|
||||
sur_timer.stop();sur_opt_timer.stop();
|
||||
|
||||
for(std::size_t i = 0; i != NIter; ++i){
|
||||
{
|
||||
sur_timer.resume();
|
||||
C c(sorted_unique_range.begin(), sorted_unique_range.end());
|
||||
sur_timer.stop();
|
||||
}
|
||||
{
|
||||
sur_opt_timer.resume();
|
||||
C c(boost::container::ordered_unique_range, sorted_unique_range.begin(), sorted_unique_range.end());
|
||||
sur_opt_timer.stop();
|
||||
}
|
||||
|
||||
}
|
||||
std::cout << " Construct sorted_unique_range " << boost::timer::format(sur_timer.elapsed(), boost::timer::default_places, "%ws\n");
|
||||
std::cout << " Construct sorted_unique_range (extension) " << boost::timer::format(sur_opt_timer.elapsed(), boost::timer::default_places, "%ws\n");
|
||||
std::cout << "Extension/Standard: ";
|
||||
compare_times(sur_opt_timer.elapsed(), sur_timer.elapsed());
|
||||
}
|
||||
|
||||
template<class BoostClass, class StdClass>
|
||||
void launch_tests(const char *BoostContName, const char *StdContName)
|
||||
{
|
||||
typedef range_provider<typename BoostClass::value_type> get_range_t;
|
||||
try {
|
||||
std::cout << "**********************************************" << '\n';
|
||||
std::cout << "**********************************************" << '\n';
|
||||
std::cout << '\n';
|
||||
std::cout << BoostContName << " .VS " << StdContName << '\n';
|
||||
std::cout << '\n';
|
||||
std::cout << "**********************************************" << '\n';
|
||||
std::cout << "**********************************************" << '\n' << std::endl;
|
||||
{
|
||||
std::cout << "Copy/Assign/Destroy benchmark:" << BoostContName << std::endl;
|
||||
cpu_times boost_set_time = copy_destroy_time< BoostClass >(get_range_t::sorted_unique());
|
||||
|
||||
std::cout << "Copy/Assign/Destroy benchmark:" << StdContName << std::endl;
|
||||
cpu_times std_set_time = copy_destroy_time< StdClass >(get_range_t::sorted_unique());
|
||||
|
||||
std::cout << BoostContName << "/" << StdContName << ": ";
|
||||
compare_times(boost_set_time, std_set_time);
|
||||
}
|
||||
{
|
||||
std::cout << "Ordered construct benchmark:" << BoostContName << std::endl;
|
||||
cpu_times boost_set_time = construct_time< BoostClass >(get_range_t::sorted_unique(), get_range_t::sorted(), "(ord)");
|
||||
|
||||
std::cout << "Ordered construct benchmark:" << StdContName << std::endl;
|
||||
cpu_times std_set_time = construct_time< StdClass >(get_range_t::sorted_unique(), get_range_t::sorted(), "(ord)");;
|
||||
|
||||
std::cout << BoostContName << "/" << StdContName << ": ";
|
||||
compare_times(boost_set_time, std_set_time);
|
||||
}
|
||||
{
|
||||
std::cout << "Random construct benchmark:" << BoostContName << std::endl;
|
||||
cpu_times boost_set_time = construct_time< BoostClass >(get_range_t::random_unique(), get_range_t::random(), "(rnd)");
|
||||
|
||||
std::cout << "Random construct benchmark:" << StdContName << std::endl;
|
||||
cpu_times std_set_time = construct_time< StdClass >(get_range_t::random_unique(), get_range_t::random(), "(rnd)");;
|
||||
|
||||
std::cout << BoostContName << "/" << StdContName << ": ";
|
||||
compare_times(boost_set_time, std_set_time);
|
||||
}
|
||||
{
|
||||
std::cout << "Ordered Insert benchmark:" << BoostContName << std::endl;
|
||||
cpu_times boost_set_time = insert_time< BoostClass >(get_range_t::sorted_unique(), get_range_t::sorted(), "(ord)");
|
||||
|
||||
std::cout << "Ordered Insert benchmark:" << StdContName << std::endl;
|
||||
cpu_times std_set_time = insert_time< StdClass >(get_range_t::sorted_unique(), get_range_t::sorted(), "(ord)");
|
||||
|
||||
std::cout << BoostContName << "/" << StdContName << ": ";
|
||||
compare_times(boost_set_time, std_set_time);
|
||||
}
|
||||
{
|
||||
std::cout << "Random Insert benchmark:" << BoostContName << std::endl;
|
||||
cpu_times boost_set_time = insert_time< BoostClass >(get_range_t::random_unique(), get_range_t::random(), "(rnd)");
|
||||
|
||||
std::cout << "Random Insert benchmark:" << StdContName << std::endl;
|
||||
cpu_times std_set_time = insert_time< StdClass >(get_range_t::random_unique(), get_range_t::random(), "(rnd)");
|
||||
|
||||
std::cout << BoostContName << "/" << StdContName << ": ";
|
||||
compare_times(boost_set_time, std_set_time);
|
||||
}
|
||||
{
|
||||
std::cout << "Ordered Search benchmark:" << BoostContName << std::endl;
|
||||
cpu_times boost_set_time = search_time< BoostClass >(get_range_t::sorted_unique(), "(ord)");
|
||||
|
||||
std::cout << "Ordered Search benchmark:" << StdContName << std::endl;
|
||||
cpu_times std_set_time = search_time< StdClass >(get_range_t::sorted_unique(), "(ord)");
|
||||
|
||||
std::cout << BoostContName << "/" << StdContName << ": ";
|
||||
compare_times(boost_set_time, std_set_time);
|
||||
}
|
||||
{
|
||||
std::cout << "Random Search benchmark:" << BoostContName << std::endl;
|
||||
cpu_times boost_set_time = search_time< BoostClass >(get_range_t::random_unique(), "(rnd)");
|
||||
|
||||
std::cout << "Random Search benchmark:" << StdContName << std::endl;
|
||||
cpu_times std_set_time = search_time< StdClass >(get_range_t::random_unique(), "(rnd)");
|
||||
|
||||
std::cout << BoostContName << "/" << StdContName << ": ";
|
||||
compare_times(boost_set_time, std_set_time);
|
||||
}
|
||||
{
|
||||
std::cout << "Extensions benchmark:" << BoostContName << std::endl;
|
||||
extensions_time< BoostClass >(get_range_t::sorted_unique());
|
||||
}
|
||||
|
||||
}catch(std::exception e){
|
||||
std::cout << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_BENCH_BENCH_SET_HPP
|
||||
29
bench/bench_set_alloc_v2.cpp
Normal file
29
bench/bench_set_alloc_v2.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "boost/container/set.hpp"
|
||||
#include "boost/container/allocator.hpp"
|
||||
#include "bench_set.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
|
||||
fill_range_ints();
|
||||
fill_range_strings();
|
||||
|
||||
//set<..., allocator_v2> vs. set
|
||||
launch_tests< set<int, std::less<int>, allocator<int> >, set<int> >
|
||||
("set<int, ..., allocator<int>", "set<int>");
|
||||
launch_tests< set<string, std::less<string>, allocator<string> >, set<string> >
|
||||
("set<string, ..., allocator<string>", "set<string>");
|
||||
|
||||
return 0;
|
||||
}
|
||||
38
bench/bench_set_avl.cpp
Normal file
38
bench/bench_set_avl.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "boost/container/set.hpp"
|
||||
#include <set>
|
||||
|
||||
#include "bench_set.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
|
||||
fill_range_ints();
|
||||
fill_range_strings();
|
||||
|
||||
//set(AVL) vs set(RB)
|
||||
launch_tests< set<int, std::less<int>, std::allocator<int>, tree_assoc_options< tree_type<avl_tree> >::type >, set<int> >
|
||||
("set<int>(AVL)", "set<int>(RB)");
|
||||
launch_tests< set<string, std::less<string>, std::allocator<string>, tree_assoc_options< tree_type<avl_tree> >::type >, set<string> >
|
||||
("set<string>(AVL)", "set<string>(RB)");
|
||||
|
||||
//set(AVL,sizeopt) vs set(AVL,!sizeopt)
|
||||
launch_tests< set<int, std::less<int>, std::allocator<int>, tree_assoc_options< tree_type<avl_tree> >::type >
|
||||
, set<int, std::less<int>, std::allocator<int>, tree_assoc_options< tree_type<avl_tree>, optimize_size<false> >::type > >
|
||||
("set<int>(AVL,sizeopt=true)", "set<int>(AVL,sizeopt=false)");
|
||||
launch_tests< set<string, std::less<string>, std::allocator<string>, tree_assoc_options< tree_type<avl_tree> >::type >
|
||||
, set<string, std::less<string>, std::allocator<string>, tree_assoc_options< tree_type<avl_tree>, optimize_size<false> >::type > >
|
||||
("set<string>(AVL,sizeopt=true)", "set<string>(AVL,sizeopt=false)");
|
||||
|
||||
return 0;
|
||||
}
|
||||
30
bench/bench_set_multi.cpp
Normal file
30
bench/bench_set_multi.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "boost/container/set.hpp"
|
||||
#include <set>
|
||||
|
||||
#include "bench_set.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
|
||||
fill_range_ints();
|
||||
fill_range_strings();
|
||||
|
||||
//multiset vs std::multiset
|
||||
launch_tests< multiset<int> , std::multiset<int> >
|
||||
("multiset<int>", "std::multiset<int>");
|
||||
launch_tests< multiset<string> , std::multiset<string> >
|
||||
("multiset<string>", "std::multiset<string>");
|
||||
|
||||
return 0;
|
||||
}
|
||||
28
bench/bench_set_sg.cpp
Normal file
28
bench/bench_set_sg.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "boost/container/set.hpp"
|
||||
#include "bench_set.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
|
||||
fill_range_ints();
|
||||
fill_range_strings();
|
||||
|
||||
//set(RB) vs set(SG)
|
||||
launch_tests< set<int, std::less<int>, std::allocator<int>, tree_assoc_options< tree_type<scapegoat_tree> >::type >, set<int> >
|
||||
("set<int>(SG)", "set<int>(RB)");
|
||||
launch_tests< set<string, std::less<string>, std::allocator<string>, tree_assoc_options< tree_type<scapegoat_tree> >::type >, set<string> >
|
||||
("set<string>(SG)", "set<string>(RB)");
|
||||
|
||||
return 0;
|
||||
}
|
||||
28
bench/bench_set_sp.cpp
Normal file
28
bench/bench_set_sp.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "boost/container/set.hpp"
|
||||
#include "bench_set.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
|
||||
fill_range_ints();
|
||||
fill_range_strings();
|
||||
|
||||
//set(RB) vs set(SP)
|
||||
launch_tests< set<int, std::less<int>, std::allocator<int>, tree_assoc_options< tree_type<splay_tree> >::type >, set<int> >
|
||||
("set<int>(SP)", "set<int>(RB)");
|
||||
launch_tests< set<string, std::less<string>, std::allocator<string>, tree_assoc_options< tree_type<splay_tree> >::type >, set<string> >
|
||||
("set<string>(SP)", "set<string>(RB)");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -4,8 +4,8 @@
|
||||
// @date Aug 14, 2011
|
||||
// @author Andrew Hundt <ATHundt@gmail.com>
|
||||
//
|
||||
// (C) 2011-2012 Andrew Hundt <ATHundt@gmail.com>
|
||||
// (C) 2013 Ion Gaztanaga
|
||||
// (C) 2011-2013 Andrew Hundt <ATHundt@gmail.com>
|
||||
// (C) 2013-2013 Ion Gaztanaga
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -28,7 +28,7 @@ using boost::timer::cpu_times;
|
||||
using boost::timer::nanosecond_type;
|
||||
|
||||
#ifdef NDEBUG
|
||||
static const std::size_t N = 1000;
|
||||
static const std::size_t N = 300;
|
||||
#else
|
||||
static const std::size_t N = 100;
|
||||
#endif
|
||||
@@ -141,5 +141,5 @@ int main()
|
||||
}catch(std::exception e){
|
||||
std::cout << e.what();
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_VARRAY_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_VARRAY_HPP
|
||||
|
||||
#if (defined _MSC_VER)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
#include <boost/container/detail/preprocessor.hpp>
|
||||
|
||||
#include "varray_util.hpp"
|
||||
#include "varray_concept.hpp"
|
||||
#include <boost/iterator/iterator_concepts.hpp>
|
||||
//#include "varray_concept.hpp"
|
||||
//#include <boost/iterator/iterator_concepts.hpp>
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
#include <stdexcept>
|
||||
@@ -229,7 +229,7 @@ class varray
|
||||
(varray)
|
||||
);
|
||||
|
||||
BOOST_CONCEPT_ASSERT((concept::VArrayStrategy<Strategy>));
|
||||
//BOOST_CONCEPT_ASSERT((concept::VArrayStrategy<Strategy>));
|
||||
|
||||
typedef boost::aligned_storage<
|
||||
sizeof(Value[Capacity]),
|
||||
@@ -353,7 +353,7 @@ public:
|
||||
varray(Iterator first, Iterator last)
|
||||
: m_size(0)
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
|
||||
//BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
|
||||
|
||||
this->assign(first, last); // may throw
|
||||
}
|
||||
@@ -890,7 +890,7 @@ public:
|
||||
template <typename Iterator>
|
||||
iterator insert(iterator position, Iterator first, Iterator last)
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
|
||||
//BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
|
||||
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal;
|
||||
this->insert_dispatch(position, first, last, traversal());
|
||||
@@ -975,7 +975,7 @@ public:
|
||||
template <typename Iterator>
|
||||
void assign(Iterator first, Iterator last)
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
|
||||
//BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
|
||||
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal;
|
||||
this->assign_dispatch(first, last, traversal()); // may throw
|
||||
@@ -1728,7 +1728,7 @@ private:
|
||||
template <typename Iterator>
|
||||
void insert_dispatch(iterator position, Iterator first, Iterator last, boost::random_access_traversal_tag const&)
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT((boost_concepts::RandomAccessTraversal<Iterator>)); // Make sure you passed a RandomAccessIterator
|
||||
//BOOST_CONCEPT_ASSERT((boost_concepts::RandomAccessTraversal<Iterator>)); // Make sure you passed a RandomAccessIterator
|
||||
|
||||
errh::check_iterator_end_eq(*this, position);
|
||||
|
||||
@@ -2015,7 +2015,7 @@ public:
|
||||
void insert(iterator, Iterator first, Iterator last)
|
||||
{
|
||||
// TODO - add MPL_ASSERT, check if Iterator is really an iterator
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal;
|
||||
//typedef typename boost::iterator_traversal<Iterator>::type traversal;
|
||||
errh::check_capacity(*this, std::distance(first, last)); // may throw
|
||||
}
|
||||
|
||||
@@ -2039,7 +2039,7 @@ public:
|
||||
void assign(Iterator first, Iterator last)
|
||||
{
|
||||
// TODO - add MPL_ASSERT, check if Iterator is really an iterator
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal;
|
||||
//typedef typename boost::iterator_traversal<Iterator>::type traversal;
|
||||
errh::check_capacity(*this, std::distance(first, last)); // may throw
|
||||
}
|
||||
|
||||
|
||||
@@ -566,13 +566,6 @@ template <typename DisableTrivialInit, typename I, typename P>
|
||||
inline
|
||||
void construct(DisableTrivialInit const&, I pos, BOOST_RV_REF(P) p)
|
||||
{
|
||||
typedef typename
|
||||
::boost::mpl::and_<
|
||||
is_corresponding_value<I, P>,
|
||||
::boost::has_trivial_copy<P>
|
||||
>::type
|
||||
use_memcpy;
|
||||
|
||||
typedef typename boost::iterator_value<I>::type V;
|
||||
new (static_cast<void*>(boost::addressof(*pos))) V(::boost::move(p)); // may throw
|
||||
}
|
||||
|
||||
@@ -10,13 +10,14 @@
|
||||
#ifndef BOOST_CONTAINER_VARRAY_HPP
|
||||
#define BOOST_CONTAINER_VARRAY_HPP
|
||||
|
||||
#if (defined _MSC_VER)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
|
||||
#include "detail/varray.hpp"
|
||||
#include <boost/move/move.hpp>
|
||||
|
||||
namespace boost { namespace container {
|
||||
|
||||
|
||||
23
build/Jamfile.v2
Normal file
23
build/Jamfile.v2
Normal file
@@ -0,0 +1,23 @@
|
||||
# (C) Copyright Vladimir Prus, David Abrahams, Michael Stevens, Hartmut Kaiser,
|
||||
# Ion Gaztanaga 2007-2008
|
||||
# Use, modification and distribution are subject to the
|
||||
# Boost Software License, Version 1.0. (See accompanying file
|
||||
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
project boost/container
|
||||
: source-location ../src
|
||||
: usage-requirements # pass these requirement to dependents (i.e. users)
|
||||
<link>shared:<define>BOOST_CONTAINER_DYN_LINK=1
|
||||
<link>static:<define>BOOST_CONTAINER_STATIC_LINK=1
|
||||
;
|
||||
|
||||
# Base names of the source files for libboost_container
|
||||
CPP_SOURCES = alloc_lib ;
|
||||
|
||||
lib boost_container
|
||||
: $(CPP_SOURCES).c
|
||||
: <link>shared:<define>BOOST_CONTAINER_DYN_LINK=1
|
||||
<link>static:<define>BOOST_CONTAINER_STATIC_LINK=1
|
||||
;
|
||||
|
||||
boost-install boost_container ;
|
||||
@@ -1,6 +1,6 @@
|
||||
# Boost.Container library documentation Jamfile ---------------------------------
|
||||
#
|
||||
# Copyright Ion Gaztanaga 2009-2012. Use, modification and
|
||||
# Copyright Ion Gaztanaga 2009-2013. Use, modification and
|
||||
# distribution is subject to the Boost Software License, Version
|
||||
# 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -35,7 +35,9 @@ doxygen autodoc
|
||||
\"BOOST_RV_REF_BEG=\" \\
|
||||
\"BOOST_RV_REF_END=&&\" \\
|
||||
\"BOOST_COPY_ASSIGN_REF(T)=const T &\" \\
|
||||
\"BOOST_FWD_REF(a)=a &&\""
|
||||
\"BOOST_FWD_REF(a)=a &&\" \\
|
||||
\"BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) = template<TYPE VALUE> struct OPTION_NAME{};\" \\
|
||||
\"BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) = template<class TYPE> struct OPTION_NAME{};\" "
|
||||
<xsl:param>"boost.doxygen.reftitle=Boost.Container Header Reference"
|
||||
;
|
||||
|
||||
|
||||
@@ -49,9 +49,13 @@ In short, what does [*Boost.Container] offer?
|
||||
|
||||
[section:introduction_building_container Building Boost.Container]
|
||||
|
||||
There is no need to compile [*Boost.Container], since it's
|
||||
a header only library. Just include your Boost header directory in your
|
||||
compiler include path.
|
||||
There is no need to compile [*Boost.Container] if you don't use [link container.extended_functionality.extended_allocators Extended Allocators]
|
||||
since in that case it's a header-only library. Just include your Boost header directory in your compiler include path.
|
||||
|
||||
[link container.extended_functionality.extended_allocators Extended Allocators] are
|
||||
implemented as a separately compiled library, so you must install binaries in a location that can be found by your linker
|
||||
when using these classes. If you followed the [@http://www.boost.org/doc/libs/release/more/getting_started/index.html Boost Getting Started] instructions,
|
||||
that's already been done for you.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -148,12 +152,19 @@ today, in fact, implementors would have to go out of their way to prohibit it!]]
|
||||
C++11 standard is also cautious about incomplete types and STL: ["['17.6.4.8 Other functions (...) 2.
|
||||
the effects are undefined in the following cases: (...) In particular - if an incomplete type (3.9)
|
||||
is used as a template argument when instantiating a template component,
|
||||
unless specifically allowed for that component]]. Fortunately [*Boost.Container] containers are designed
|
||||
to support type erasure and recursive types, so let's see some examples:
|
||||
unless specifically allowed for that component]].
|
||||
|
||||
Fortunately all [*Boost.Container] containers except
|
||||
[classref boost::container::static_vector static_vector] and
|
||||
[classref boost::container::basic_string basic_string] are designed to support incomplete types.
|
||||
[classref boost::container::static_vector static_vector] is special because
|
||||
it statically allocates memory for `value_type` and this requires complete types and
|
||||
[classref boost::container::basic_string basic_string] implements Small String Optimization which
|
||||
also requires complete types.
|
||||
|
||||
[section:recursive_containers Recursive containers]
|
||||
|
||||
All containers offered by [*Boost.Container] can be used to define recursive containers:
|
||||
Most [*Boost.Container] containers can be used to define recursive containers:
|
||||
|
||||
[import ../example/doc_recursive_containers.cpp]
|
||||
[doc_recursive_containers]
|
||||
@@ -261,8 +272,8 @@ When dealing with user-defined classes, (e.g. when constructing user-defined cla
|
||||
propagate error situations internally as no error will be propagated through [*Boost.Container].
|
||||
* If `BOOST_NO_EXCEPTIONS` is *not* defined, the library propagates exceptions offering the exception guarantees detailed in the documentation.
|
||||
|
||||
When the library needs to throw an exception (such as `out_of_range` when an incorrect index is used in `vector::at`)], the library calls
|
||||
a throw callback declared in `<boost/container/throw_exception.hpp>`:
|
||||
When the library needs to throw an exception (such as `out_of_range` when an incorrect index is used in `vector::at`), the library calls
|
||||
a throw-callback declared in [headerref boost/container/throw_exception.hpp]:
|
||||
|
||||
* If `BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS` is defined, then the programmer must provide its own definition for all
|
||||
`throw_xxx` functions. Those functions can't return, they must throw an exception or call `std::exit` or `std::abort`.
|
||||
@@ -522,6 +533,168 @@ using [@http://en.cppreference.com/w/cpp/language/default_initialization default
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:ordered_range_insertion Ordered range insertion for associative containers (['ordered_unique_range], ['ordered_range]) ]
|
||||
|
||||
When filling associative containers big performance gains can be achieved if the input range to be inserted
|
||||
is guaranteed by the user to be ordered according to the predicate. This can happen when inserting values from a `set` to
|
||||
a `multiset` or between different associative container families (`[multi]set/map` vs. `flat_[multi]set/map`).
|
||||
|
||||
[*Boost.Container] has some overloads for constructors and insertions taking an `ordered_unique_range_t` or
|
||||
an `ordered_range_t` tag parameters as the first argument. When an `ordered_unique_range_t` overload is used, the
|
||||
user notifies the container that the input range is ordered according to the container predicate and has no
|
||||
duplicates. When an `ordered_range_t` overload is used, the
|
||||
user notifies the container that the input range is ordered according to the container predicate but it might
|
||||
have duplicates. With this information, the container can avoid multiple predicate calls and improve insertion
|
||||
times.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:configurable_tree_based_associative_containers Configurable tree-based associative ordered containers]
|
||||
|
||||
[classref boost::container::set set], [classref boost::container::multiset multiset],
|
||||
[classref boost::container::map map] and [classref boost::container::multimap multimap] associative containers
|
||||
are implemented as binary search trees which offer the needed complexity and stability guarantees required by the
|
||||
C++ standard for associative containers.
|
||||
|
||||
[*Boost.Container] offers the possibility to configure at compile time some parameters of the binary search tree
|
||||
implementation. This configuration is passed as the last template parameter and defined using the utility class
|
||||
[classref boost::container::tree_assoc_options tree_assoc_options].
|
||||
|
||||
The following parameters can be configured:
|
||||
|
||||
* The underlying [*tree implementation] type ([classref boost::container::tree_type tree_type]).
|
||||
By default these containers use a red-black tree but the user can use other tree types:
|
||||
* [@http://en.wikipedia.org/wiki/Red%E2%80%93black_tree Red-Black Tree]
|
||||
* [@http://en.wikipedia.org/wiki/Avl_trees AVL tree]
|
||||
* [@http://en.wikipedia.org/wiki/Scapegoat_tree Scapegoat tree]. In this case Insertion and Deletion
|
||||
are amortized O(log n) instead of O(log n).
|
||||
* [@http://en.wikipedia.org/wiki/Splay_tree Splay tree]. In this case Searches, Insertions and Deletions
|
||||
are amortized O(log n) instead of O(log n).
|
||||
|
||||
* Whether the [*size saving] mechanisms are used to implement the tree nodes
|
||||
([classref boost::container::optimize_size optimize_size]). By default this option is activated and is only
|
||||
meaningful to red-black and avl trees (in other cases, this option will be ignored).
|
||||
This option will try to put rebalancing metadata inside the "parent" pointer of the node if the pointer
|
||||
type has enough alignment. Usually, due to alignment issues, the metadata uses the size of a pointer yielding
|
||||
to four pointer size overhead per node, whereas activating this option usually leads to 3 pointer size overhead.
|
||||
Although some mask operations must be performed to extract
|
||||
data from this special "parent" pointer, in several systems this option also improves performance due to the
|
||||
improved cache usage produced by the node size reduction.
|
||||
|
||||
See the following example to see how [classref boost::container::tree_assoc_options tree_assoc_options] can be
|
||||
used to customize these containers:
|
||||
|
||||
[import ../example/doc_custom_tree.cpp]
|
||||
[doc_custom_tree]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:constant_time_range_splice Constant-time range splice for `(s)list`]
|
||||
|
||||
In the first C++ standard `list::size()` was not required to be constant-time,
|
||||
and that caused some controversy in the C++ community. Quoting Howard Hinnant's
|
||||
[@http://home.roadrunner.com/~hinnant/On_list_size.html ['On List Size]] paper:
|
||||
|
||||
[: ['There is a considerable debate on whether `std::list<T>::size()` should be O(1) or O(N).
|
||||
The usual argument notes that it is a tradeoff with:]
|
||||
|
||||
`splice(iterator position, list& x, iterator first, iterator last);`
|
||||
|
||||
['If size() is O(1) and this != &x, then this method must perform a linear operation so that it
|
||||
can adjust the size member in each list]]
|
||||
|
||||
C++11 definitely required `size()` to be O(1), so range splice became O(N). However,
|
||||
Howard Hinnant's paper proposed a new `splice` overload so that even O(1) `list:size()`
|
||||
implementations could achieve O(1) range splice when the range size was known to the caller:
|
||||
|
||||
[: `void splice(iterator position, list& x, iterator first, iterator last, size_type n);`
|
||||
|
||||
[*Effects]: Inserts elements in the range [first, last) before position and removes the elements from x.
|
||||
|
||||
[*Requires]: [first, last) is a valid range in x. The result is undefined if position is an iterator in the range [first, last). Invalidates only the iterators and references to the spliced elements. n == distance(first, last).
|
||||
|
||||
[*Throws]: Nothing.
|
||||
|
||||
[*Complexity]: Constant time.
|
||||
]
|
||||
|
||||
This new splice signature allows the client to pass the distance of the input range in.
|
||||
This information is often available at the call site. If it is passed in,
|
||||
then the operation is constant time, even with an O(1) size.
|
||||
|
||||
[*Boost.Container] implements this overload for `list` and a modified version of it for `slist`
|
||||
(as `slist::size()` is also `O(1)`).
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:extended_allocators Extended allocators]
|
||||
|
||||
Many C++ programmers have ever wondered where does good old realloc fit in C++. And that's a good question.
|
||||
Could we improve [classref boost::container::vector vector] performance using memory expansion mechanisms
|
||||
to avoid too many copies? But [classref boost::container::vector vector] is not the only container that
|
||||
could benefit from an improved allocator interface: we could take advantage of the insertion of multiple
|
||||
elements in [classref boost::container::list list] using a burst allocation mechanism that could amortize
|
||||
costs (mutex locks, free memory searches...) that can't be amortized when using single node allocation
|
||||
strategies.
|
||||
|
||||
These improvements require extending the STL allocator interface and use make use of a new
|
||||
general purpose allocator since new and delete don't offer expansion and burst capabilities.
|
||||
|
||||
* [*Boost.Container] containers support an extended allocator interface based on an evolution of proposals
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1953.html N1953: Upgrading the Interface of Allocators using API Versioning],
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2045.html N2045: Improving STL allocators]
|
||||
and the article
|
||||
[@http://www.drivehq.com/web/igaztanaga/allocplus/ Applying classic memory allocation strategies to C++ containers].
|
||||
The extended allocator interface is implemented by [classref boost::container::allocator allocator],
|
||||
[classref boost::container::adaptive_pool adaptive_pool] and [classref boost::container::node_allocator node_allocator]
|
||||
classes.
|
||||
|
||||
* Extended allocators use a modified [@http://g.oswego.edu/dl/html/malloc.html Doug Lea Malloc (DLMalloc)] low-level
|
||||
allocator and offers an C API to implement memory expansion and burst allocations. DLmalloc is known to be very size
|
||||
and speed efficient, and this allocator is used as the basis of many malloc implementations, including multithreaded
|
||||
allocators built above DLmalloc (See [@http://www.malloc.de/en/ ptmalloc2, ptmalloc3] or
|
||||
[@http://www.nedprod.com/programs/portable/nedmalloc/ nedmalloc]). This low-level allocator is implemented as
|
||||
a separately compiled library whereas [classref boost::container::allocator allocator],
|
||||
[classref boost::container::adaptive_pool adaptive_pool] and [classref boost::container::node_allocator node_allocator]
|
||||
are header-only classes.
|
||||
|
||||
The following extended allocators are provided:
|
||||
|
||||
* [classref boost::container::allocator allocator]: This extended allocator offers expansion, shrink-in place
|
||||
and burst allocation capabilities implemented as a thin wrapper around the modified DLMalloc.
|
||||
It can be used with all containers and it should be the default choice when the programmer wants to use
|
||||
extended allocator capabilities.
|
||||
|
||||
* [classref boost::container::node_allocator node_allocator]: It's a
|
||||
[@http://www.boost.org/doc/libs/1_55_0/libs/pool/doc/html/boost_pool/pool/pooling.html#boost_pool.pool.pooling.simple Simple Segregated Storage]
|
||||
allocator, similar to [*Boost.Pool] that takes advantage of the modified DLMalloc burst interface. It does not return
|
||||
memory to the DLMalloc allocator (and thus, to the system), unless explicitly requested. It does offer a very small
|
||||
memory overhead so it's suitable for node containers ([boost::container::list list], [boost::container::slist slist]
|
||||
[boost::container::set set]...) that allocate very small `value_type`s and it offers improved node allocation times
|
||||
for single node allocations with respecto to [classref boost::container::allocator allocator].
|
||||
|
||||
* [classref boost::container::adaptive_pool adaptive_pool]: It's a low-overhead node allocator that can return memory
|
||||
to the system. The overhead can be very low (< 5% for small nodes) and it's nearly as fast as [classref boost::container::node_allocator node_allocator].
|
||||
It's also suitable for node containers.
|
||||
|
||||
Use them simply specifying the new allocator in the corresponding template argument of your favourite container:
|
||||
|
||||
[import ../example/doc_extended_allocators.cpp]
|
||||
[doc_extended_allocators]
|
||||
|
||||
[endsect]
|
||||
|
||||
[/
|
||||
/a__section:previous_element_slist Previous element for slist__a
|
||||
/
|
||||
/The C++11 `std::forward_list` class implement a singly linked list, similar to `slist`, and these
|
||||
/containers only offer forward iterators and implement insertions and splice operations that operate with ranges
|
||||
/to be inserted ['after] that position. In those cases, sometimes it's interesting to obtain an iterator pointing
|
||||
/to the previous element of another element. This operation can be implemented
|
||||
/
|
||||
/a__endsect__a
|
||||
]
|
||||
|
||||
[/
|
||||
/a__section:get_stored_allocator Obtain stored allocator__a
|
||||
/
|
||||
@@ -532,18 +705,6 @@ using [@http://en.cppreference.com/w/cpp/language/default_initialization default
|
||||
/http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html
|
||||
/
|
||||
/a__endsect__a
|
||||
/
|
||||
/a__section:ordered_range_insertion Ordered range insertion (a__'ordered_unique_range__a, a__'ordered_range__a) __a
|
||||
/
|
||||
/a__endsect__a
|
||||
/
|
||||
/a__section:constant_time_range_splice Constant-time range splice__a
|
||||
/
|
||||
/a__endsect__a
|
||||
/
|
||||
/a__section:previous_element_slist Slist previous element__a
|
||||
/
|
||||
/a__endsect__a
|
||||
/]
|
||||
|
||||
[endsect]
|
||||
@@ -709,9 +870,10 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
* Default constructors don't allocate memory at all, which improves performance and
|
||||
usually implies a no-throw guarantee (if predicate's or allocator's default constructor doesn't throw).
|
||||
* Small string optimization for [classref boost::container::basic_string basic_string].
|
||||
* New extensions beyond the standard based on user feedback to improve code performance.
|
||||
* [link container.extended_functionality Extended functionality] beyond the standard based
|
||||
on user feedback to improve code performance.
|
||||
* You need a portable implementation that works when compiling without exceptions support or
|
||||
you need to customize the error handling when a container needs to signall an exceptional error.
|
||||
you need to customize the error handling when a container needs to signal an exceptional error.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -759,6 +921,21 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
|
||||
[section:release_notes Release Notes]
|
||||
|
||||
[section:release_notes_boost_1_56_00 Boost 1.56 Release]
|
||||
|
||||
* Added DlMalloc-based [link container.extended_functionality.extended_allocators Extended Allocators].
|
||||
|
||||
* [link container.extended_functionality.configurable_tree_based_associative_containers Improved configurability]
|
||||
of tree-based ordered associative containers. AVL, Scapegoat and Splay trees are now available
|
||||
to implement [classref boost::container::set set], [classref boost::container::multiset multiset],
|
||||
[classref boost::container::map map] and [classref boost::container::multimap multimap].
|
||||
|
||||
* Fixed bugs:
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9338 #9338: ['"VS2005 compiler errors in swap() definition after including container/memory_util.hpp"]].
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9648 #9648: ['"string construction optimization - char_traits::copy could be used ..."]].
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:release_notes_boost_1_55_00 Boost 1.55 Release]
|
||||
|
||||
* Implemented [link container.main_features.scary_iterators SCARY iterators].
|
||||
@@ -769,7 +946,8 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
[@https://svn.boost.org/trac/boost/ticket/9009 #9009],
|
||||
[@https://svn.boost.org/trac/boost/ticket/9064 #9064],
|
||||
[@https://svn.boost.org/trac/boost/ticket/9092 #9092],
|
||||
[@https://svn.boost.org/trac/boost/ticket/9108 #9108].
|
||||
[@https://svn.boost.org/trac/boost/ticket/9108 #9108],
|
||||
[@https://svn.boost.org/trac/boost/ticket/9166 #9166],
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ rule test_all
|
||||
|
||||
for local fileb in [ glob doc_*.cpp ]
|
||||
{
|
||||
all_rules += [ run $(fileb)
|
||||
all_rules += [ run $(fileb) /boost/container//boost_container /boost/timer//boost_timer
|
||||
: # additional args
|
||||
: # test-files
|
||||
: # requirements
|
||||
|
||||
64
example/doc_custom_tree.cpp
Normal file
64
example/doc_custom_tree.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
//[doc_custom_tree
|
||||
#include <boost/container/set.hpp>
|
||||
#include <cassert>
|
||||
|
||||
int main ()
|
||||
{
|
||||
using namespace boost::container;
|
||||
|
||||
//First define several options
|
||||
//
|
||||
|
||||
//This option specifies an AVL tree based associative container
|
||||
typedef tree_assoc_options< tree_type<avl_tree> >::type AVLTree;
|
||||
|
||||
//This option specifies an AVL tree based associative container
|
||||
//disabling node size optimization.
|
||||
typedef tree_assoc_options< tree_type<avl_tree>
|
||||
, optimize_size<false> >::type AVLTreeNoSizeOpt;
|
||||
|
||||
//This option specifies an Splay tree based associative container
|
||||
typedef tree_assoc_options< tree_type<splay_tree> >::type SplayTree;
|
||||
|
||||
//Now define new tree-based associative containers
|
||||
//
|
||||
|
||||
//AVLTree based set container
|
||||
typedef set<int, std::less<int>, std::allocator<int>, AVLTree> AvlSet;
|
||||
|
||||
//AVLTree based set container without size optimization
|
||||
typedef set<int, std::less<int>, std::allocator<int>, AVLTreeNoSizeOpt> AvlSetNoSizeOpt;
|
||||
|
||||
//Splay tree based multiset container
|
||||
typedef multiset<int, std::less<int>, std::allocator<int>, SplayTree> SplayMultiset;
|
||||
|
||||
//Use them
|
||||
//
|
||||
AvlSet avl_set;
|
||||
avl_set.insert(0);
|
||||
assert(avl_set.find(0) != avl_set.end());
|
||||
|
||||
AvlSetNoSizeOpt avl_set_no_szopt;
|
||||
avl_set_no_szopt.insert(1);
|
||||
avl_set_no_szopt.insert(1);
|
||||
assert(avl_set_no_szopt.count(1) == 1);
|
||||
|
||||
SplayMultiset splay_mset;
|
||||
splay_mset.insert(2);
|
||||
splay_mset.insert(2);
|
||||
assert(splay_mset.count(2) == 2);
|
||||
return 0;
|
||||
}
|
||||
//]
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2009-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)
|
||||
//
|
||||
|
||||
54
example/doc_extended_allocators.cpp
Normal file
54
example/doc_extended_allocators.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
//[doc_extended_allocators
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/container/flat_set.hpp>
|
||||
#include <boost/container/list.hpp>
|
||||
#include <boost/container/set.hpp>
|
||||
|
||||
//"allocator" is a general purpose allocator that can reallocate
|
||||
//memory, something useful for vector and flat associative containers
|
||||
#include <boost/container/allocator.hpp>
|
||||
|
||||
//"adaptive_pool" is a node allocator, specially suited for
|
||||
//node-based containers
|
||||
#include <boost/container/adaptive_pool.hpp>
|
||||
|
||||
int main ()
|
||||
{
|
||||
using namespace boost::container;
|
||||
|
||||
//A vector that can reallocate memory to implement faster insertions
|
||||
vector<int, allocator<int> > extended_alloc_vector;
|
||||
|
||||
//A flat set that can reallocate memory to implement faster insertions
|
||||
flat_set<int, std::less<int>, allocator<int> > extended_alloc_flat_set;
|
||||
|
||||
//A list that can manages nodes to implement faster
|
||||
//range insertions and deletions
|
||||
list<int, adaptive_pool<int> > extended_alloc_list;
|
||||
|
||||
//A set that can recycle nodes to implement faster
|
||||
//range insertions and deletions
|
||||
set<int, std::less<int>, adaptive_pool<int> > extended_alloc_set;
|
||||
|
||||
//Now user them as always
|
||||
extended_alloc_vector.push_back(0);
|
||||
extended_alloc_flat_set.insert(0);
|
||||
extended_alloc_list.push_back(0);
|
||||
extended_alloc_set.insert(0);
|
||||
|
||||
//...
|
||||
return 0;
|
||||
}
|
||||
//]
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2009-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2009-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -11,9 +11,10 @@
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
//[doc_recursive_containers
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/container/stable_vector.hpp>
|
||||
#include <boost/container/deque.hpp>
|
||||
#include <boost/container/list.hpp>
|
||||
#include <boost/container/map.hpp>
|
||||
#include <boost/container/stable_vector.hpp>
|
||||
#include <boost/container/string.hpp>
|
||||
|
||||
using namespace boost::container;
|
||||
@@ -23,6 +24,10 @@ struct data
|
||||
int i_;
|
||||
//A vector holding still undefined class 'data'
|
||||
vector<data> v_;
|
||||
//A stable_vector holding still undefined class 'data'
|
||||
stable_vector<data> sv_;
|
||||
//A stable_vector holding still undefined class 'data'
|
||||
deque<data> d_;
|
||||
//A list holding still undefined 'data'
|
||||
list<data> l_;
|
||||
//A map holding still undefined 'data'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2009-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)
|
||||
//
|
||||
|
||||
390
include/boost/container/adaptive_pool.hpp
Normal file
390
include/boost/container/adaptive_pool.hpp
Normal file
@@ -0,0 +1,390 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_ADAPTIVE_POOL_HPP
|
||||
#define BOOST_CONTAINER_ADAPTIVE_POOL_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
#include <boost/container/detail/adaptive_node_pool.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/alloc_lib_auto_link.hpp>
|
||||
#include <boost/container/detail/singleton.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//!An STL node allocator that uses a modified DLMalloc as memory
|
||||
//!source.
|
||||
//!
|
||||
//!This node allocator shares a segregated storage between all instances
|
||||
//!of adaptive_pool with equal sizeof(T).
|
||||
//!
|
||||
//!NodesPerBlock is the number of nodes allocated at once when the allocator
|
||||
//!needs runs out of nodes. MaxFreeBlocks is the maximum number of totally free blocks
|
||||
//!that the adaptive node pool will hold. The rest of the totally free blocks will be
|
||||
//!deallocated to the memory manager.
|
||||
//!
|
||||
//!OverheadPercent is the (approximated) maximum size overhead (1-20%) of the allocator:
|
||||
//!(memory usable for nodes / total memory allocated from the memory allocator)
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template < class T
|
||||
, std::size_t NodesPerBlock = ADP_nodes_per_block
|
||||
, std::size_t MaxFreeBlocks = ADP_max_free_blocks
|
||||
, std::size_t OverheadPercent = ADP_overhead_percent
|
||||
>
|
||||
#else
|
||||
template < class T
|
||||
, std::size_t NodesPerBlock
|
||||
, std::size_t MaxFreeBlocks
|
||||
, std::size_t OverheadPercent
|
||||
, unsigned Version
|
||||
>
|
||||
#endif
|
||||
class adaptive_pool
|
||||
{
|
||||
//!If Version is 1, the allocator is a STL conforming allocator. If Version is 2,
|
||||
//!the allocator offers advanced expand in place and burst allocation capabilities.
|
||||
public:
|
||||
typedef unsigned int allocation_type;
|
||||
typedef adaptive_pool
|
||||
<T, NodesPerBlock, MaxFreeBlocks, OverheadPercent
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
, Version
|
||||
#endif
|
||||
> self_t;
|
||||
|
||||
static const std::size_t nodes_per_block = NodesPerBlock;
|
||||
static const std::size_t max_free_blocks = MaxFreeBlocks;
|
||||
static const std::size_t overhead_percent = OverheadPercent;
|
||||
static const std::size_t real_nodes_per_block = NodesPerBlock;
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
BOOST_STATIC_ASSERT((Version <=2));
|
||||
#endif
|
||||
|
||||
public:
|
||||
//-------
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
typedef const T * const_pointer;
|
||||
typedef typename ::boost::container::
|
||||
container_detail::unvoid<T>::type & reference;
|
||||
typedef const typename ::boost::container::
|
||||
container_detail::unvoid<T>::type & const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
typedef boost::container::container_detail::
|
||||
version_type<self_t, Version> version;
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef boost::container::container_detail::
|
||||
basic_multiallocation_chain<void*> multiallocation_chain_void;
|
||||
typedef boost::container::container_detail::
|
||||
transform_multiallocation_chain
|
||||
<multiallocation_chain_void, T> multiallocation_chain;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//!Obtains adaptive_pool from
|
||||
//!adaptive_pool
|
||||
template<class T2>
|
||||
struct rebind
|
||||
{
|
||||
typedef adaptive_pool
|
||||
< T2
|
||||
, NodesPerBlock
|
||||
, MaxFreeBlocks
|
||||
, OverheadPercent
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
, Version
|
||||
#endif
|
||||
> other;
|
||||
};
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
//!Not assignable from related adaptive_pool
|
||||
template<class T2, unsigned Version2, std::size_t N2, std::size_t F2>
|
||||
adaptive_pool& operator=
|
||||
(const adaptive_pool<T2, Version2, N2, F2>&);
|
||||
|
||||
//!Not assignable from other adaptive_pool
|
||||
adaptive_pool& operator=(const adaptive_pool&);
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//!Default constructor
|
||||
adaptive_pool() BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Copy constructor from other adaptive_pool.
|
||||
adaptive_pool(const adaptive_pool &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Copy constructor from related adaptive_pool.
|
||||
template<class T2>
|
||||
adaptive_pool
|
||||
(const adaptive_pool<T2, NodesPerBlock, MaxFreeBlocks, OverheadPercent
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
, Version
|
||||
#endif
|
||||
> &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Destructor
|
||||
~adaptive_pool() BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Returns the number of elements that could be allocated.
|
||||
//!Never throws
|
||||
size_type max_size() const BOOST_CONTAINER_NOEXCEPT
|
||||
{ return size_type(-1)/sizeof(T); }
|
||||
|
||||
//!Allocate memory for an array of count elements.
|
||||
//!Throws std::bad_alloc if there is no enough memory
|
||||
pointer allocate(size_type count, const void * = 0)
|
||||
{
|
||||
if(count > this->max_size())
|
||||
boost::container::throw_bad_alloc();
|
||||
|
||||
if(Version == 1 && count == 1){
|
||||
typedef typename container_detail::shared_adaptive_node_pool
|
||||
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
return pointer(static_cast<T*>(singleton_t::instance().allocate_node()));
|
||||
}
|
||||
else{
|
||||
return static_cast<pointer>(boost_cont_malloc(count*sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
//!Deallocate allocated memory.
|
||||
//!Never throws
|
||||
void deallocate(const pointer &ptr, size_type count) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
(void)count;
|
||||
if(Version == 1 && count == 1){
|
||||
typedef container_detail::shared_adaptive_node_pool
|
||||
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
singleton_t::instance().deallocate_node(ptr);
|
||||
}
|
||||
else{
|
||||
boost_cont_free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<pointer, bool>
|
||||
allocation_command(allocation_type command,
|
||||
size_type limit_size,
|
||||
size_type preferred_size,
|
||||
size_type &received_size, pointer reuse = pointer())
|
||||
{
|
||||
std::pair<pointer, bool> ret =
|
||||
this->priv_allocation_command(command, limit_size, preferred_size, received_size, reuse);
|
||||
if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
|
||||
boost::container::throw_bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//!Returns maximum the number of objects the previously allocated memory
|
||||
//!pointed by p can hold.
|
||||
size_type size(pointer p) const BOOST_CONTAINER_NOEXCEPT
|
||||
{ return boost_cont_size(p); }
|
||||
|
||||
//!Allocates just one object. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
//!Throws bad_alloc if there is no enough memory
|
||||
pointer allocate_one()
|
||||
{
|
||||
typedef container_detail::shared_adaptive_node_pool
|
||||
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
return (pointer)singleton_t::instance().allocate_node();
|
||||
}
|
||||
|
||||
//!Allocates many elements of size == 1.
|
||||
//!Elements must be individually deallocated with deallocate_one()
|
||||
void allocate_individual(std::size_t num_elements, multiallocation_chain &chain)
|
||||
{
|
||||
typedef container_detail::shared_adaptive_node_pool
|
||||
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
singleton_t::instance().allocate_nodes(num_elements, static_cast<typename shared_pool_t::multiallocation_chain&>(chain));
|
||||
//typename shared_pool_t::multiallocation_chain ch;
|
||||
//singleton_t::instance().allocate_nodes(num_elements, ch);
|
||||
//chain.incorporate_after
|
||||
//(chain.before_begin(), (T*)&*ch.begin(), (T*)&*ch.last(), ch.size());
|
||||
}
|
||||
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
||||
//!with other functions different from allocate_one(). Never throws
|
||||
void deallocate_one(pointer p) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
typedef container_detail::shared_adaptive_node_pool
|
||||
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
singleton_t::instance().deallocate_node(p);
|
||||
}
|
||||
|
||||
void deallocate_individual(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
typedef container_detail::shared_adaptive_node_pool
|
||||
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
//typename shared_pool_t::multiallocation_chain ch(&*chain.begin(), &*chain.last(), chain.size());
|
||||
//singleton_t::instance().deallocate_nodes(ch);
|
||||
singleton_t::instance().deallocate_nodes(chain);
|
||||
}
|
||||
|
||||
//!Allocates many elements of size elem_size.
|
||||
//!Elements must be individually deallocated with deallocate()
|
||||
void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));/*
|
||||
boost_cont_memchain ch;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
|
||||
if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
chain.incorporate_after(chain.before_begin()
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
|
||||
if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain))){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
//!Allocates n_elements elements, each one of size elem_sizes[i]
|
||||
//!Elements must be individually deallocated with deallocate()
|
||||
void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));/*
|
||||
boost_cont_memchain ch;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
|
||||
if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
chain.incorporate_after(chain.before_begin()
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
|
||||
if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain))){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
void deallocate_many(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
|
||||
{/*
|
||||
boost_cont_memchain ch;
|
||||
void *beg(&*chain.begin()), *last(&*chain.last());
|
||||
size_t size(chain.size());
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&ch, beg, last, size);
|
||||
boost_cont_multidealloc(&ch);*/
|
||||
boost_cont_multidealloc(reinterpret_cast<boost_cont_memchain *>(&chain));
|
||||
}
|
||||
|
||||
//!Deallocates all free blocks of the pool
|
||||
static void deallocate_free_blocks() BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
typedef container_detail::shared_adaptive_node_pool
|
||||
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
singleton_t::instance().deallocate_free_blocks();
|
||||
}
|
||||
|
||||
//!Swaps allocators. Does not throw. If each allocator is placed in a
|
||||
//!different memory segment, the result is undefined.
|
||||
friend void swap(adaptive_pool &, adaptive_pool &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!An allocator always compares to true, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator==(const adaptive_pool &, const adaptive_pool &) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return true; }
|
||||
|
||||
//!An allocator always compares to false, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator!=(const adaptive_pool &, const adaptive_pool &) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return false; }
|
||||
/*
|
||||
//!Returns address of mutable object.
|
||||
//!Never throws
|
||||
pointer address(reference value) const
|
||||
{ return pointer(boost::addressof(value)); }
|
||||
|
||||
//!Returns address of non mutable object.
|
||||
//!Never throws
|
||||
const_pointer address(const_reference value) const
|
||||
{ return const_pointer(boost::addressof(value)); }
|
||||
|
||||
//!Default construct an object.
|
||||
//!Throws if T's default constructor throws
|
||||
void construct(const pointer &ptr)
|
||||
{ new(ptr) value_type; }
|
||||
|
||||
//!Construct a copy of the passed object.
|
||||
//!Throws if T's copy constructor throws
|
||||
void construct(pointer ptr, const_reference t)
|
||||
{ new(ptr) value_type(t); }
|
||||
|
||||
//!Destroys object. Throws if object's
|
||||
//!destructor throws
|
||||
void destroy(const pointer &ptr)
|
||||
{ (void)ptr; BOOST_ASSERT(ptr); (*ptr).~value_type(); }
|
||||
*/
|
||||
private:
|
||||
std::pair<pointer, bool> priv_allocation_command
|
||||
(allocation_type command, std::size_t limit_size
|
||||
,std::size_t preferred_size,std::size_t &received_size, void *reuse_ptr)
|
||||
{
|
||||
boost_cont_command_ret_t ret = {0 , 0};
|
||||
if(limit_size > this->max_size() || preferred_size > this->max_size()){
|
||||
// ret.first = 0;
|
||||
return std::pair<pointer, bool>(pointer(), false);
|
||||
}
|
||||
std::size_t l_size = limit_size*sizeof(T);
|
||||
std::size_t p_size = preferred_size*sizeof(T);
|
||||
std::size_t r_size;
|
||||
{
|
||||
ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr);
|
||||
}
|
||||
received_size = r_size/sizeof(T);
|
||||
return std::pair<pointer, bool>(static_cast<pointer>(ret.first), !!ret.second);
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_ADAPTIVE_POOL_HPP
|
||||
368
include/boost/container/allocator.hpp
Normal file
368
include/boost/container/allocator.hpp
Normal file
@@ -0,0 +1,368 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_ALLOCATOR_HPP
|
||||
#define BOOST_CONTAINER_ALLOCATOR_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
#include <boost/container/detail/alloc_lib_auto_link.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <cassert>
|
||||
#include <new>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template<unsigned Version, unsigned int AllocationDisableMask>
|
||||
class allocator<void, Version, AllocationDisableMask>
|
||||
{
|
||||
typedef allocator<void, Version, AllocationDisableMask> self_t;
|
||||
public:
|
||||
typedef void value_type;
|
||||
typedef void * pointer;
|
||||
typedef const void* const_pointer;
|
||||
typedef int & reference;
|
||||
typedef const int & const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef boost::container::container_detail::
|
||||
version_type<self_t, Version> version;
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef boost::container::container_detail::
|
||||
basic_multiallocation_chain<void*> multiallocation_chain;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//!Obtains an allocator that allocates
|
||||
//!objects of type T2
|
||||
template<class T2>
|
||||
struct rebind
|
||||
{
|
||||
typedef allocator< T2
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
, Version, AllocationDisableMask
|
||||
#endif
|
||||
> other;
|
||||
};
|
||||
|
||||
//!Default constructor
|
||||
//!Never throws
|
||||
allocator()
|
||||
{}
|
||||
|
||||
//!Constructor from other allocator.
|
||||
//!Never throws
|
||||
allocator(const allocator &)
|
||||
{}
|
||||
|
||||
//!Constructor from related allocator.
|
||||
//!Never throws
|
||||
template<class T2>
|
||||
allocator(const allocator<T2, Version, AllocationDisableMask> &)
|
||||
{}
|
||||
};
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//!\file
|
||||
//! This class is an extended STL-compatible that offers advanced allocation mechanism
|
||||
//!(in-place expansion, shrinking, burst-allocation...)
|
||||
//!
|
||||
//! This allocator is a wrapper around a modified DLmalloc.
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template<class T>
|
||||
#else
|
||||
//! If Version is 1, the allocator is a STL conforming allocator. If Version is 2,
|
||||
//! the allocator offers advanced expand in place and burst allocation capabilities.
|
||||
//
|
||||
//! AllocationDisableMask works only if Version is 2 and it can be an inclusive OR
|
||||
//! of allocation types the user wants to disable.
|
||||
template<class T, unsigned Version, unsigned int AllocationDisableMask>
|
||||
#endif //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
class allocator
|
||||
{
|
||||
typedef unsigned int allocation_type;
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
|
||||
//Self type
|
||||
typedef allocator<T, Version, AllocationDisableMask> self_t;
|
||||
|
||||
//Not assignable from related allocator
|
||||
template<class T2, unsigned int Version2, unsigned int AllocationDisableMask2>
|
||||
allocator& operator=(const allocator<T2, Version2, AllocationDisableMask2>&);
|
||||
|
||||
//Not assignable from other allocator
|
||||
allocator& operator=(const allocator&);
|
||||
|
||||
static const unsigned int ForbiddenMask =
|
||||
BOOST_CONTAINER_ALLOCATE_NEW | BOOST_CONTAINER_EXPAND_BWD | BOOST_CONTAINER_EXPAND_FWD ;
|
||||
|
||||
//The mask can't disable all the allocation types
|
||||
BOOST_STATIC_ASSERT(( (AllocationDisableMask & ForbiddenMask) != ForbiddenMask ));
|
||||
|
||||
//The mask is only valid for version 2 allocators
|
||||
BOOST_STATIC_ASSERT(( Version != 1 || (AllocationDisableMask == 0) ));
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
typedef const T * const_pointer;
|
||||
typedef T & reference;
|
||||
typedef const T & const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
typedef boost::container::container_detail::
|
||||
version_type<self_t, Version> version;
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef boost::container::container_detail::
|
||||
basic_multiallocation_chain<void*> void_multiallocation_chain;
|
||||
|
||||
typedef boost::container::container_detail::
|
||||
transform_multiallocation_chain
|
||||
<void_multiallocation_chain, T> multiallocation_chain;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//!Obtains an allocator that allocates
|
||||
//!objects of type T2
|
||||
template<class T2>
|
||||
struct rebind
|
||||
{
|
||||
typedef allocator<T2, Version, AllocationDisableMask> other;
|
||||
};
|
||||
|
||||
//!Default constructor
|
||||
//!Never throws
|
||||
allocator() BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Constructor from other allocator.
|
||||
//!Never throws
|
||||
allocator(const allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Constructor from related allocator.
|
||||
//!Never throws
|
||||
template<class T2>
|
||||
allocator(const allocator<T2
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
, Version, AllocationDisableMask
|
||||
#endif
|
||||
> &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Allocates memory for an array of count elements.
|
||||
//!Throws std::bad_alloc if there is no enough memory
|
||||
//!If Version is 2, this allocated memory can only be deallocated
|
||||
//!with deallocate() or (for Version == 2) deallocate_many()
|
||||
pointer allocate(size_type count, const void * hint= 0)
|
||||
{
|
||||
(void)hint;
|
||||
if(count > this->max_size())
|
||||
boost::container::throw_bad_alloc();
|
||||
void *ret = boost_cont_malloc(count*sizeof(T));
|
||||
if(!ret)
|
||||
boost::container::throw_bad_alloc();
|
||||
return static_cast<pointer>(ret);
|
||||
}
|
||||
|
||||
//!Deallocates previously allocated memory.
|
||||
//!Never throws
|
||||
void deallocate(pointer ptr, size_type) BOOST_CONTAINER_NOEXCEPT
|
||||
{ boost_cont_free(ptr); }
|
||||
|
||||
//!Returns the maximum number of elements that could be allocated.
|
||||
//!Never throws
|
||||
size_type max_size() const BOOST_CONTAINER_NOEXCEPT
|
||||
{ return size_type(-1)/sizeof(T); }
|
||||
|
||||
//!Swaps two allocators, does nothing
|
||||
//!because this allocator is stateless
|
||||
friend void swap(self_t &, self_t &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!An allocator always compares to true, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator==(const allocator &, const allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return true; }
|
||||
|
||||
//!An allocator always compares to false, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator!=(const allocator &, const allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return false; }
|
||||
|
||||
//!An advanced function that offers in-place expansion shrink to fit and new allocation
|
||||
//!capabilities. Memory allocated with this function can only be deallocated with deallocate()
|
||||
//!or deallocate_many().
|
||||
//!This function is available only with Version == 2
|
||||
std::pair<pointer, bool>
|
||||
allocation_command(allocation_type command,
|
||||
size_type limit_size,
|
||||
size_type preferred_size,
|
||||
size_type &received_size, pointer reuse = pointer())
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
const allocation_type mask(AllocationDisableMask);
|
||||
command &= ~mask;
|
||||
std::pair<pointer, bool> ret =
|
||||
priv_allocation_command(command, limit_size, preferred_size, received_size, reuse);
|
||||
if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
|
||||
boost::container::throw_bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//!Returns maximum the number of objects the previously allocated memory
|
||||
//!pointed by p can hold.
|
||||
//!Memory must not have been allocated with
|
||||
//!allocate_one or allocate_individual.
|
||||
//!This function is available only with Version == 2
|
||||
size_type size(pointer p) const BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
return boost_cont_size(p);
|
||||
}
|
||||
|
||||
//!Allocates just one object. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
//!Throws bad_alloc if there is no enough memory
|
||||
//!This function is available only with Version == 2
|
||||
pointer allocate_one()
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
return this->allocate(1);
|
||||
}
|
||||
|
||||
//!Allocates many elements of size == 1.
|
||||
//!Elements must be individually deallocated with deallocate_one()
|
||||
//!This function is available only with Version == 2
|
||||
void allocate_individual(std::size_t num_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
this->allocate_many(1, num_elements, chain);
|
||||
}
|
||||
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
||||
//!with other functions different from allocate_one() or allocate_individual.
|
||||
//Never throws
|
||||
void deallocate_one(pointer p) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
return this->deallocate(p, 1);
|
||||
}
|
||||
|
||||
//!Deallocates memory allocated with allocate_one() or allocate_individual().
|
||||
//!This function is available only with Version == 2
|
||||
void deallocate_individual(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
return this->deallocate_many(chain);
|
||||
}
|
||||
|
||||
//!Allocates many elements of size elem_size.
|
||||
//!Elements must be individually deallocated with deallocate()
|
||||
//!This function is available only with Version == 2
|
||||
void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));/*
|
||||
boost_cont_memchain ch;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
|
||||
if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
chain.incorporate_after(chain.before_begin()
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
|
||||
if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain))){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
//!Allocates n_elements elements, each one of size elem_sizes[i]
|
||||
//!Elements must be individually deallocated with deallocate()
|
||||
//!This function is available only with Version == 2
|
||||
void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
boost_cont_memchain ch;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
|
||||
if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
chain.incorporate_after(chain.before_begin()
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );
|
||||
/*
|
||||
if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain))){
|
||||
boost::container::throw_bad_alloc();
|
||||
}*/
|
||||
}
|
||||
|
||||
//!Deallocates several elements allocated by
|
||||
//!allocate_many(), allocate(), or allocation_command().
|
||||
//!This function is available only with Version == 2
|
||||
void deallocate_many(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
boost_cont_memchain ch;
|
||||
void *beg(&*chain.begin()), *last(&*chain.last());
|
||||
size_t size(chain.size());
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&ch, beg, last, size);
|
||||
boost_cont_multidealloc(&ch);
|
||||
//boost_cont_multidealloc(reinterpret_cast<boost_cont_memchain *>(&chain));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::pair<pointer, bool> priv_allocation_command
|
||||
(allocation_type command, std::size_t limit_size
|
||||
,std::size_t preferred_size,std::size_t &received_size, void *reuse_ptr)
|
||||
{
|
||||
boost_cont_command_ret_t ret = {0 , 0};
|
||||
if((limit_size > this->max_size()) | (preferred_size > this->max_size())){
|
||||
return std::pair<pointer, bool>(pointer(), false);
|
||||
}
|
||||
std::size_t l_size = limit_size*sizeof(T);
|
||||
std::size_t p_size = preferred_size*sizeof(T);
|
||||
std::size_t r_size;
|
||||
{
|
||||
ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr);
|
||||
}
|
||||
received_size = r_size/sizeof(T);
|
||||
return std::pair<pointer, bool>(static_cast<pointer>(ret.first), !!ret.second);
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_ALLOCATOR_HPP
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -38,7 +38,7 @@
|
||||
#include <boost/container/detail/preprocessor.hpp>
|
||||
#endif
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
@@ -56,7 +56,7 @@ struct is_std_allocator< std::allocator<T> >
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! The class template allocator_traits supplies a uniform interface to all allocator types.
|
||||
//! This class is a C++03-compatible implementation of std::allocator_traits
|
||||
@@ -94,29 +94,29 @@ struct allocator_traits
|
||||
//!
|
||||
typedef see_documentation size_type;
|
||||
//! Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant
|
||||
//! type with internal constant static member `value` == false.
|
||||
//! type with internal constant static member <code>value</code> == false.
|
||||
typedef see_documentation propagate_on_container_copy_assignment;
|
||||
//! Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant
|
||||
//! type with internal constant static member `value` == false.
|
||||
//! type with internal constant static member <code>value</code> == false.
|
||||
typedef see_documentation propagate_on_container_move_assignment;
|
||||
//! Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant
|
||||
//! type with internal constant static member `value` == false.
|
||||
//! type with internal constant static member <code>value</code> == false.
|
||||
typedef see_documentation propagate_on_container_swap;
|
||||
//! Defines an allocator: Alloc::rebind<T>::other if such a type exists; otherwise, Alloc<T, Args>
|
||||
//! if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or
|
||||
//! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed.
|
||||
//!
|
||||
//! In C++03 compilers `rebind_alloc` is a struct derived from an allocator
|
||||
//! In C++03 compilers <code>rebind_alloc</code> is a struct derived from an allocator
|
||||
//! deduced by previously detailed rules.
|
||||
template <class T> using rebind_alloc = see_documentation;
|
||||
|
||||
//! In C++03 compilers `rebind_traits` is a struct derived from
|
||||
//! `allocator_traits<OtherAlloc>`, where `OtherAlloc` is
|
||||
//! the allocator deduced by rules explained in `rebind_alloc`.
|
||||
//! In C++03 compilers <code>rebind_traits</code> is a struct derived from
|
||||
//! <code>allocator_traits<OtherAlloc></code>, where <code>OtherAlloc</code> is
|
||||
//! the allocator deduced by rules explained in <code>rebind_alloc</code>.
|
||||
template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >;
|
||||
|
||||
//! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers.
|
||||
//! `type` is an allocator related to Alloc deduced deduced by rules explained in `rebind_alloc`.
|
||||
//! <code>type</code> is an allocator related to Alloc deduced deduced by rules explained in <code>rebind_alloc</code>.
|
||||
template <class T>
|
||||
struct portable_rebind_alloc
|
||||
{ typedef see_documentation type; };
|
||||
@@ -206,19 +206,19 @@ struct allocator_traits
|
||||
{ typedef typename boost::intrusive::detail::type_rebinder<Alloc, T>::type type; };
|
||||
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Returns</b>: `a.allocate(n)`
|
||||
//! <b>Returns</b>: <code>a.allocate(n)</code>
|
||||
//!
|
||||
static pointer allocate(Alloc &a, size_type n)
|
||||
{ return a.allocate(n); }
|
||||
|
||||
//! <b>Returns</b>: `a.deallocate(p, n)`
|
||||
//! <b>Returns</b>: <code>a.deallocate(p, n)</code>
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing
|
||||
static void deallocate(Alloc &a, pointer p, size_type n)
|
||||
{ a.deallocate(p, n); }
|
||||
|
||||
//! <b>Effects</b>: calls `a.allocate(n, p)` if that call is well-formed;
|
||||
//! otherwise, invokes `a.allocate(n)`
|
||||
//! <b>Effects</b>: calls <code>a.allocate(n, p)</code> if that call is well-formed;
|
||||
//! otherwise, invokes <code>a.allocate(n)</code>
|
||||
static pointer allocate(Alloc &a, size_type n, const_void_pointer p)
|
||||
{
|
||||
const bool value = boost::container::container_detail::
|
||||
@@ -228,10 +228,10 @@ struct allocator_traits
|
||||
return allocator_traits::priv_allocate(flag, a, n, p);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: calls `a.destroy(p)` if that call is well-formed;
|
||||
//! otherwise, invokes `p->~T()`.
|
||||
//! <b>Effects</b>: calls <code>a.destroy(p)</code> if that call is well-formed;
|
||||
//! otherwise, invokes <code>p->~T()</code>.
|
||||
template<class T>
|
||||
static void destroy(Alloc &a, T*p)
|
||||
static void destroy(Alloc &a, T*p) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
typedef T* destroy_pointer;
|
||||
const bool value = boost::container::container_detail::
|
||||
@@ -241,9 +241,9 @@ struct allocator_traits
|
||||
allocator_traits::priv_destroy(flag, a, p);
|
||||
}
|
||||
|
||||
//! <b>Returns</b>: `a.max_size()` if that expression is well-formed; otherwise,
|
||||
//! `numeric_limits<size_type>::max()`.
|
||||
static size_type max_size(const Alloc &a)
|
||||
//! <b>Returns</b>: <code>a.max_size()</code> if that expression is well-formed; otherwise,
|
||||
//! <code>numeric_limits<size_type>::max()</code>.
|
||||
static size_type max_size(const Alloc &a) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_max_size
|
||||
@@ -252,7 +252,7 @@ struct allocator_traits
|
||||
return allocator_traits::priv_max_size(flag, a);
|
||||
}
|
||||
|
||||
//! <b>Returns</b>: `a.select_on_container_copy_construction()` if that expression is well-formed;
|
||||
//! <b>Returns</b>: <code>a.select_on_container_copy_construction()</code> if that expression is well-formed;
|
||||
//! otherwise, a.
|
||||
static
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
@@ -276,8 +276,8 @@ struct allocator_traits
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
//! <b>Effects</b>: calls `a.construct(p, std::forward<Args>(args)...)` if that call is well-formed;
|
||||
//! otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`
|
||||
//! <b>Effects</b>: calls <code>a.construct(p, std::forward<Args>(args)...)</code> if that call is well-formed;
|
||||
//! otherwise, invokes <code>::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)</code>
|
||||
template <class T, class ...Args>
|
||||
static void construct(Alloc & a, T* p, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
@@ -285,7 +285,7 @@ struct allocator_traits
|
||||
allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
private:
|
||||
static pointer priv_allocate(boost::true_type, Alloc &a, size_type n, const_void_pointer p)
|
||||
@@ -295,23 +295,23 @@ struct allocator_traits
|
||||
{ return allocator_traits::allocate(a, n); }
|
||||
|
||||
template<class T>
|
||||
static void priv_destroy(boost::true_type, Alloc &a, T* p)
|
||||
static void priv_destroy(boost::true_type, Alloc &a, T* p) BOOST_CONTAINER_NOEXCEPT
|
||||
{ a.destroy(p); }
|
||||
|
||||
template<class T>
|
||||
static void priv_destroy(boost::false_type, Alloc &, T* p)
|
||||
static void priv_destroy(boost::false_type, Alloc &, T* p) BOOST_CONTAINER_NOEXCEPT
|
||||
{ p->~T(); (void)p; }
|
||||
|
||||
static size_type priv_max_size(boost::true_type, const Alloc &a)
|
||||
static size_type priv_max_size(boost::true_type, const Alloc &a) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return a.max_size(); }
|
||||
|
||||
static size_type priv_max_size(boost::false_type, const Alloc &)
|
||||
static size_type priv_max_size(boost::false_type, const Alloc &) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return (std::numeric_limits<size_type>::max)(); }
|
||||
|
||||
static Alloc priv_select_on_container_copy_construction(boost::true_type, const Alloc &a)
|
||||
{ return a.select_on_container_copy_construction(); }
|
||||
|
||||
static const Alloc &priv_select_on_container_copy_construction(boost::false_type, const Alloc &a)
|
||||
static const Alloc &priv_select_on_container_copy_construction(boost::false_type, const Alloc &a) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return a; }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
@@ -394,7 +394,7 @@ struct allocator_traits
|
||||
{ ::new((void*)p) T; }
|
||||
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -15,11 +15,37 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//! \file
|
||||
//! This header file forward declares the following containers:
|
||||
//! - boost::container::vector
|
||||
//! - boost::container::stable_vector
|
||||
//! - boost::container::static_vector
|
||||
//! - boost::container::slist
|
||||
//! - boost::container::list
|
||||
//! - boost::container::set
|
||||
//! - boost::container::multiset
|
||||
//! - boost::container::map
|
||||
//! - boost::container::multimap
|
||||
//! - boost::container::flat_set
|
||||
//! - boost::container::flat_multiset
|
||||
//! - boost::container::flat_map
|
||||
//! - boost::container::flat_multimap
|
||||
//! - boost::container::basic_string
|
||||
//! - boost::container::string
|
||||
//! - boost::container::wstring
|
||||
//!
|
||||
//! It forward declares the following allocators:
|
||||
//! - boost::container::allocator
|
||||
//! - boost::container::node_allocator
|
||||
//! - boost::container::adaptive_pool
|
||||
//!
|
||||
//! And finally it defines the following types
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Standard predeclarations
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost{
|
||||
namespace intrusive{
|
||||
@@ -32,13 +58,14 @@ namespace bi = boost::intrusive;
|
||||
|
||||
}}}
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Containers
|
||||
@@ -47,89 +74,146 @@ namespace bi = boost::intrusive;
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//vector class
|
||||
//! Enumeration used to configure ordered associative containers
|
||||
//! with a concrete tree implementation.
|
||||
enum tree_type_enum
|
||||
{
|
||||
red_black_tree,
|
||||
avl_tree,
|
||||
scapegoat_tree,
|
||||
splay_tree
|
||||
};
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template <class T
|
||||
,class Allocator = std::allocator<T> >
|
||||
class vector;
|
||||
|
||||
//vector class
|
||||
template <class T
|
||||
,class Allocator = std::allocator<T> >
|
||||
class stable_vector;
|
||||
|
||||
//vector class
|
||||
template <class T, std::size_t Capacity>
|
||||
class static_vector;
|
||||
|
||||
template <class T
|
||||
,class Allocator = std::allocator<T> >
|
||||
class deque;
|
||||
|
||||
//list class
|
||||
template <class T
|
||||
,class Allocator = std::allocator<T> >
|
||||
class list;
|
||||
|
||||
//slist class
|
||||
template <class T
|
||||
,class Allocator = std::allocator<T> >
|
||||
class slist;
|
||||
|
||||
//set class
|
||||
template<tree_type_enum TreeType, bool OptimizeSize>
|
||||
struct tree_opt;
|
||||
|
||||
typedef tree_opt<red_black_tree, true> tree_assoc_defaults;
|
||||
|
||||
template <class Key
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<Key> >
|
||||
,class Allocator = std::allocator<Key>
|
||||
,class Options = tree_assoc_defaults >
|
||||
class set;
|
||||
|
||||
//multiset class
|
||||
template <class Key
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<Key> >
|
||||
,class Allocator = std::allocator<Key>
|
||||
,class Options = tree_assoc_defaults >
|
||||
class multiset;
|
||||
|
||||
//map class
|
||||
template <class Key
|
||||
,class T
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<std::pair<const Key, T> > >
|
||||
,class Allocator = std::allocator<std::pair<const Key, T> >
|
||||
,class Options = tree_assoc_defaults >
|
||||
class map;
|
||||
|
||||
//multimap class
|
||||
template <class Key
|
||||
,class T
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<std::pair<const Key, T> > >
|
||||
,class Allocator = std::allocator<std::pair<const Key, T> >
|
||||
,class Options = tree_assoc_defaults >
|
||||
class multimap;
|
||||
|
||||
//flat_set class
|
||||
template <class Key
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<Key> >
|
||||
class flat_set;
|
||||
|
||||
//flat_multiset class
|
||||
template <class Key
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<Key> >
|
||||
class flat_multiset;
|
||||
|
||||
//flat_map class
|
||||
template <class Key
|
||||
,class T
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<std::pair<Key, T> > >
|
||||
class flat_map;
|
||||
|
||||
//flat_multimap class
|
||||
template <class Key
|
||||
,class T
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<std::pair<Key, T> > >
|
||||
class flat_multimap;
|
||||
|
||||
//basic_string class
|
||||
template <class CharT
|
||||
,class Traits = std::char_traits<CharT>
|
||||
,class Allocator = std::allocator<CharT> >
|
||||
class basic_string;
|
||||
|
||||
typedef basic_string
|
||||
<char
|
||||
,std::char_traits<char>
|
||||
,std::allocator<char> >
|
||||
string;
|
||||
|
||||
typedef basic_string
|
||||
<wchar_t
|
||||
,std::char_traits<wchar_t>
|
||||
,std::allocator<wchar_t> >
|
||||
wstring;
|
||||
|
||||
static const std::size_t ADP_nodes_per_block = 256u;
|
||||
static const std::size_t ADP_max_free_blocks = 2u;
|
||||
static const std::size_t ADP_overhead_percent = 1u;
|
||||
static const std::size_t ADP_only_alignment = 0u;
|
||||
|
||||
template < class T
|
||||
, std::size_t NodesPerBlock = ADP_nodes_per_block
|
||||
, std::size_t MaxFreeBlocks = ADP_max_free_blocks
|
||||
, std::size_t OverheadPercent = ADP_overhead_percent
|
||||
, unsigned Version = 2
|
||||
>
|
||||
class adaptive_pool;
|
||||
|
||||
template < class T
|
||||
, unsigned Version = 2
|
||||
, unsigned int AllocationDisableMask = 0>
|
||||
class allocator;
|
||||
|
||||
static const std::size_t NodeAlloc_nodes_per_block = 256u;
|
||||
|
||||
template
|
||||
< class T
|
||||
, std::size_t NodesPerBlock = NodeAlloc_nodes_per_block
|
||||
, std::size_t Version = 2>
|
||||
class node_allocator;
|
||||
|
||||
#else
|
||||
|
||||
//! Default options for tree-based associative containers
|
||||
//! - tree_type<red_black_tree>
|
||||
//! - optimize_size<true>
|
||||
typedef implementation_defined tree_assoc_defaults;
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! Type used to tag that the input range is
|
||||
//! guaranteed to be ordered
|
||||
struct ordered_range_t
|
||||
@@ -149,17 +233,26 @@ struct ordered_unique_range_t
|
||||
//! guaranteed to be ordered and unique
|
||||
static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t();
|
||||
|
||||
//! Type used to tag that the input range is
|
||||
//! guaranteed to be ordered and unique
|
||||
//! Type used to tag that the inserted values
|
||||
//! should be default initialized
|
||||
struct default_init_t
|
||||
{};
|
||||
|
||||
//! Value used to tag that the input range is
|
||||
//! guaranteed to be ordered and unique
|
||||
//! Value used to tag that the inserted values
|
||||
//! should be default initialized
|
||||
static const default_init_t default_init = default_init_t();
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace detail_really_deep_namespace {
|
||||
//! Type used to tag that the inserted values
|
||||
//! should be value initialized
|
||||
struct value_init_t
|
||||
{};
|
||||
|
||||
//! Value used to tag that the inserted values
|
||||
//! should be value initialized
|
||||
static const value_init_t value_init = value_init_t();
|
||||
|
||||
namespace container_detail_really_deep_namespace {
|
||||
|
||||
//Otherwise, gcc issues a warning of previously defined
|
||||
//anonymous_instance and unique_instance
|
||||
@@ -175,7 +268,7 @@ struct dummy
|
||||
|
||||
} //detail_really_deep_namespace {
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
}} //namespace boost { namespace container {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -45,12 +45,8 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
/// @cond
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class T, class Allocator = std::allocator<T> >
|
||||
#else
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class T, class Allocator>
|
||||
#endif
|
||||
class deque;
|
||||
|
||||
template <class T>
|
||||
@@ -465,21 +461,24 @@ class deque_base
|
||||
const allocator_type &alloc() const BOOST_CONTAINER_NOEXCEPT
|
||||
{ return members_; }
|
||||
};
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! Deque class
|
||||
//!
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
//! A double-ended queue is a sequence that supports random access to elements, constant time insertion
|
||||
//! and removal of elements at the end of the sequence, and linear time insertion and removal of elements in the middle.
|
||||
//!
|
||||
//! \tparam T The type of object that is stored in the deque
|
||||
//! \tparam Allocator The allocator used for all internal memory management
|
||||
template <class T, class Allocator = std::allocator<T> >
|
||||
#else
|
||||
template <class T, class Allocator>
|
||||
#endif
|
||||
class deque : protected deque_base<Allocator>
|
||||
{
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
typedef deque_base<Allocator> Base;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
|
||||
@@ -503,7 +502,7 @@ class deque : protected deque_base<Allocator>
|
||||
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
|
||||
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
private: // Internal typedefs
|
||||
BOOST_COPYABLE_AND_MOVABLE(deque)
|
||||
@@ -512,7 +511,7 @@ class deque : protected deque_base<Allocator>
|
||||
{ return Base::s_buffer_size(); }
|
||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////
|
||||
@@ -549,8 +548,8 @@ class deque : protected deque_base<Allocator>
|
||||
explicit deque(size_type n)
|
||||
: Base(n, allocator_type())
|
||||
{
|
||||
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
|
||||
proxy.uninitialized_copy_n_and_update(this->begin(), n);
|
||||
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy;
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
|
||||
//deque_base will deallocate in case of exception...
|
||||
}
|
||||
|
||||
@@ -566,8 +565,8 @@ class deque : protected deque_base<Allocator>
|
||||
deque(size_type n, default_init_t)
|
||||
: Base(n, allocator_type())
|
||||
{
|
||||
container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
|
||||
proxy.uninitialized_copy_n_and_update(this->begin(), n);
|
||||
container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy;
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
|
||||
//deque_base will deallocate in case of exception...
|
||||
}
|
||||
|
||||
@@ -978,7 +977,7 @@ class deque : protected deque_base<Allocator>
|
||||
this->priv_erase_last_n(len - new_size);
|
||||
else{
|
||||
const size_type n = new_size - this->size();
|
||||
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
|
||||
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy;
|
||||
priv_insert_back_aux_impl(n, proxy);
|
||||
}
|
||||
}
|
||||
@@ -998,7 +997,7 @@ class deque : protected deque_base<Allocator>
|
||||
this->priv_erase_last_n(len - new_size);
|
||||
else{
|
||||
const size_type n = new_size - this->size();
|
||||
container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
|
||||
container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy;
|
||||
priv_insert_back_aux_impl(n, proxy);
|
||||
}
|
||||
}
|
||||
@@ -1155,7 +1154,7 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
else{
|
||||
typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
|
||||
this->priv_insert_front_aux_impl(1, type(this->alloc(), boost::forward<Args>(args)...));
|
||||
this->priv_insert_front_aux_impl(1, type(boost::forward<Args>(args)...));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1177,7 +1176,7 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
else{
|
||||
typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
|
||||
this->priv_insert_back_aux_impl(1, type(this->alloc(), boost::forward<Args>(args)...));
|
||||
this->priv_insert_back_aux_impl(1, type(boost::forward<Args>(args)...));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1203,7 +1202,7 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
else{
|
||||
typedef container_detail::insert_emplace_proxy<Allocator, iterator, Args...> type;
|
||||
return this->priv_insert_aux_impl(p, 1, type(this->alloc(), boost::forward<Args>(args)...));
|
||||
return this->priv_insert_aux_impl(p, 1, type(boost::forward<Args>(args)...));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1222,10 +1221,10 @@ class deque : protected deque_base<Allocator>
|
||||
priv_push_front_simple_commit(); \
|
||||
} \
|
||||
else{ \
|
||||
container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
|
||||
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
|
||||
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
|
||||
priv_insert_front_aux_impl(1, proxy); \
|
||||
typedef container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
|
||||
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
|
||||
priv_insert_front_aux_impl \
|
||||
(1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
@@ -1240,10 +1239,10 @@ class deque : protected deque_base<Allocator>
|
||||
priv_push_back_simple_commit(); \
|
||||
} \
|
||||
else{ \
|
||||
container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
|
||||
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
|
||||
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
|
||||
priv_insert_back_aux_impl(1, proxy); \
|
||||
typedef container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
|
||||
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
|
||||
priv_insert_back_aux_impl \
|
||||
(1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
@@ -1260,10 +1259,10 @@ class deque : protected deque_base<Allocator>
|
||||
return (this->end()-1); \
|
||||
} \
|
||||
else{ \
|
||||
container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
|
||||
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
|
||||
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
|
||||
return this->priv_insert_aux_impl(p, 1, proxy); \
|
||||
typedef container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
|
||||
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
|
||||
return this->priv_insert_aux_impl \
|
||||
(p, 1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
|
||||
} \
|
||||
} \
|
||||
//!
|
||||
@@ -1397,7 +1396,7 @@ class deque : protected deque_base<Allocator>
|
||||
#endif
|
||||
)
|
||||
{
|
||||
container_detail::insert_range_proxy<Allocator, FwdIt, iterator> proxy(this->alloc(), first);
|
||||
container_detail::insert_range_proxy<Allocator, FwdIt, iterator> proxy(first);
|
||||
return priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
|
||||
}
|
||||
#endif
|
||||
@@ -1537,7 +1536,49 @@ class deque : protected deque_base<Allocator>
|
||||
this->members_.m_finish = this->members_.m_start;
|
||||
}
|
||||
|
||||
/// @cond
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const deque& x, const deque& y)
|
||||
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const deque& x, const deque& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const deque& x, const deque& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const deque& x, const deque& y)
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const deque& x, const deque& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const deque& x, const deque& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(deque& x, deque& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
|
||||
void priv_erase_last_n(size_type n)
|
||||
@@ -1570,7 +1611,8 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
else {
|
||||
return priv_insert_aux_impl
|
||||
(position, (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
|
||||
( position, (size_type)1
|
||||
, container_detail::get_insert_value_proxy<iterator, Allocator>(::boost::forward<U>(x)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1584,7 +1626,8 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
else{
|
||||
priv_insert_aux_impl
|
||||
(this->cbegin(), (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
|
||||
( this->cbegin(), (size_type)1
|
||||
, container_detail::get_insert_value_proxy<iterator, Allocator>(::boost::forward<U>(x)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1598,8 +1641,8 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
else{
|
||||
priv_insert_aux_impl
|
||||
(this->cend(), (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
|
||||
container_detail::insert_copy_proxy<Allocator, iterator> proxy(this->alloc(), x);
|
||||
( this->cend(), (size_type)1
|
||||
, container_detail::get_insert_value_proxy<iterator, Allocator>(::boost::forward<U>(x)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1652,7 +1695,7 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
|
||||
template<class InsertProxy>
|
||||
iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy interf)
|
||||
iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy proxy)
|
||||
{
|
||||
iterator pos(p.unconst());
|
||||
const size_type pos_n = p - this->cbegin();
|
||||
@@ -1667,7 +1710,7 @@ class deque : protected deque_base<Allocator>
|
||||
const iterator new_start = this->priv_reserve_elements_at_front(n);
|
||||
const iterator old_start = this->members_.m_start;
|
||||
if(!elemsbefore){
|
||||
interf.uninitialized_copy_n_and_update(new_start, n);
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
|
||||
this->members_.m_start = new_start;
|
||||
}
|
||||
else{
|
||||
@@ -1678,17 +1721,17 @@ class deque : protected deque_base<Allocator>
|
||||
(this->alloc(), this->members_.m_start, start_n, new_start);
|
||||
this->members_.m_start = new_start;
|
||||
boost::move(start_n, pos, old_start);
|
||||
interf.copy_n_and_update(pos - n, n);
|
||||
proxy.copy_n_and_update(this->alloc(), pos - n, n);
|
||||
}
|
||||
else {
|
||||
const size_type mid_count = n - elemsbefore;
|
||||
const iterator mid_start = old_start - mid_count;
|
||||
interf.uninitialized_copy_n_and_update(mid_start, mid_count);
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), mid_start, mid_count);
|
||||
this->members_.m_start = mid_start;
|
||||
::boost::container::uninitialized_move_alloc
|
||||
(this->alloc(), old_start, pos, new_start);
|
||||
this->members_.m_start = new_start;
|
||||
interf.copy_n_and_update(old_start, elemsbefore);
|
||||
proxy.copy_n_and_update(this->alloc(), old_start, elemsbefore);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1697,7 +1740,7 @@ class deque : protected deque_base<Allocator>
|
||||
const iterator old_finish = this->members_.m_finish;
|
||||
const size_type elemsafter = length - elemsbefore;
|
||||
if(!elemsafter){
|
||||
interf.uninitialized_copy_n_and_update(old_finish, n);
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n);
|
||||
this->members_.m_finish = new_finish;
|
||||
}
|
||||
else{
|
||||
@@ -1708,15 +1751,15 @@ class deque : protected deque_base<Allocator>
|
||||
(this->alloc(), finish_n, old_finish, old_finish);
|
||||
this->members_.m_finish = new_finish;
|
||||
boost::move_backward(pos, finish_n, old_finish);
|
||||
interf.copy_n_and_update(pos, n);
|
||||
proxy.copy_n_and_update(this->alloc(), pos, n);
|
||||
}
|
||||
else {
|
||||
const size_type raw_gap = n - elemsafter;
|
||||
::boost::container::uninitialized_move_alloc
|
||||
(this->alloc(), pos, old_finish, old_finish + raw_gap);
|
||||
BOOST_TRY{
|
||||
interf.copy_n_and_update(pos, elemsafter);
|
||||
interf.uninitialized_copy_n_and_update(old_finish, raw_gap);
|
||||
proxy.copy_n_and_update(this->alloc(), pos, elemsafter);
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, raw_gap);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
this->priv_destroy_range(old_finish, old_finish + elemsafter);
|
||||
@@ -1731,7 +1774,7 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
|
||||
template <class InsertProxy>
|
||||
iterator priv_insert_back_aux_impl(size_type n, InsertProxy interf)
|
||||
iterator priv_insert_back_aux_impl(size_type n, InsertProxy proxy)
|
||||
{
|
||||
if(!this->members_.m_map){
|
||||
this->priv_initialize_map(0);
|
||||
@@ -1739,20 +1782,20 @@ class deque : protected deque_base<Allocator>
|
||||
|
||||
iterator new_finish = this->priv_reserve_elements_at_back(n);
|
||||
iterator old_finish = this->members_.m_finish;
|
||||
interf.uninitialized_copy_n_and_update(old_finish, n);
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n);
|
||||
this->members_.m_finish = new_finish;
|
||||
return iterator(this->members_.m_finish - n);
|
||||
}
|
||||
|
||||
template <class InsertProxy>
|
||||
iterator priv_insert_front_aux_impl(size_type n, InsertProxy interf)
|
||||
iterator priv_insert_front_aux_impl(size_type n, InsertProxy proxy)
|
||||
{
|
||||
if(!this->members_.m_map){
|
||||
this->priv_initialize_map(0);
|
||||
}
|
||||
|
||||
iterator new_start = this->priv_reserve_elements_at_front(n);
|
||||
interf.uninitialized_copy_n_and_update(new_start, n);
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
|
||||
this->members_.m_start = new_start;
|
||||
return new_start;
|
||||
}
|
||||
@@ -1934,45 +1977,12 @@ class deque : protected deque_base<Allocator>
|
||||
this->members_.m_start.priv_set_node(new_nstart);
|
||||
this->members_.m_finish.priv_set_node(new_nstart + old_num_nodes - 1);
|
||||
}
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
// Nonmember functions.
|
||||
template <class T, class Allocator>
|
||||
inline bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator<(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator!=(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return !(x == y); }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator>(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return y < x; }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator>=(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return !(x < y); }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator<=(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return !(y < x); }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
}}
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1985,7 +1995,7 @@ struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator> >
|
||||
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
|
||||
162
include/boost/container/detail/adaptive_node_pool.hpp
Normal file
162
include/boost/container/detail/adaptive_node_pool.hpp
Normal file
@@ -0,0 +1,162 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/intrusive/set.hpp>
|
||||
#include <boost/aligned_storage.hpp>
|
||||
#include <boost/container/detail/alloc_lib_auto_link.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/container/detail/pool_common_alloc.hpp>
|
||||
#include <boost/container/detail/mutex.hpp>
|
||||
#include <boost/container/detail/adaptive_node_pool_impl.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <cstddef>
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <new>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template<bool AlignOnly>
|
||||
struct select_private_adaptive_node_pool_impl
|
||||
{
|
||||
typedef boost::container::container_detail::
|
||||
private_adaptive_node_pool_impl
|
||||
< fake_segment_manager
|
||||
, unsigned(AlignOnly)*::boost::container::adaptive_pool_flag::align_only
|
||||
| ::boost::container::adaptive_pool_flag::size_ordered | ::boost::container::adaptive_pool_flag::address_ordered
|
||||
> type;
|
||||
};
|
||||
|
||||
//!Pooled memory allocator using an smart adaptive pool. Includes
|
||||
//!a reference count but the class does not delete itself, this is
|
||||
//!responsibility of user classes. Node size (NodeSize) and the number of
|
||||
//!nodes allocated per block (NodesPerBlock) are known at compile time.
|
||||
template< std::size_t NodeSize
|
||||
, std::size_t NodesPerBlock
|
||||
, std::size_t MaxFreeBlocks
|
||||
, std::size_t OverheadPercent
|
||||
>
|
||||
class private_adaptive_node_pool
|
||||
: public select_private_adaptive_node_pool_impl<(OverheadPercent == 0)>::type
|
||||
{
|
||||
typedef typename select_private_adaptive_node_pool_impl<OverheadPercent == 0>::type base_t;
|
||||
//Non-copyable
|
||||
private_adaptive_node_pool(const private_adaptive_node_pool &);
|
||||
private_adaptive_node_pool &operator=(const private_adaptive_node_pool &);
|
||||
|
||||
public:
|
||||
typedef typename base_t::multiallocation_chain multiallocation_chain;
|
||||
static const std::size_t nodes_per_block = NodesPerBlock;
|
||||
|
||||
//!Constructor. Never throws
|
||||
private_adaptive_node_pool()
|
||||
: base_t(0
|
||||
, NodeSize
|
||||
, NodesPerBlock
|
||||
, MaxFreeBlocks
|
||||
, (unsigned char)OverheadPercent)
|
||||
{}
|
||||
};
|
||||
|
||||
//!Pooled memory allocator using adaptive pool. Includes
|
||||
//!a reference count but the class does not delete itself, this is
|
||||
//!responsibility of user classes. Node size (NodeSize) and the number of
|
||||
//!nodes allocated per block (NodesPerBlock) are known at compile time
|
||||
template< std::size_t NodeSize
|
||||
, std::size_t NodesPerBlock
|
||||
, std::size_t MaxFreeBlocks
|
||||
, std::size_t OverheadPercent
|
||||
>
|
||||
class shared_adaptive_node_pool
|
||||
: public private_adaptive_node_pool
|
||||
<NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent>
|
||||
{
|
||||
private:
|
||||
typedef private_adaptive_node_pool
|
||||
<NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent> private_node_allocator_t;
|
||||
public:
|
||||
typedef typename private_node_allocator_t::multiallocation_chain multiallocation_chain;
|
||||
|
||||
//!Constructor. Never throws
|
||||
shared_adaptive_node_pool()
|
||||
: private_node_allocator_t(){}
|
||||
|
||||
//!Destructor. Deallocates all allocated blocks. Never throws
|
||||
~shared_adaptive_node_pool()
|
||||
{}
|
||||
|
||||
//!Allocates array of count elements. Can throw std::bad_alloc
|
||||
void *allocate_node()
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
return private_node_allocator_t::allocate_node();
|
||||
}
|
||||
|
||||
//!Deallocates an array pointed by ptr. Never throws
|
||||
void deallocate_node(void *ptr)
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
private_node_allocator_t::deallocate_node(ptr);
|
||||
}
|
||||
|
||||
//!Allocates a singly linked list of n nodes ending in null pointer.
|
||||
//!can throw std::bad_alloc
|
||||
void allocate_nodes(const std::size_t n, multiallocation_chain &chain)
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
return private_node_allocator_t::allocate_nodes(n, chain);
|
||||
}
|
||||
|
||||
void deallocate_nodes(multiallocation_chain &chain)
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
private_node_allocator_t::deallocate_nodes(chain);
|
||||
}
|
||||
|
||||
//!Deallocates all the free blocks of memory. Never throws
|
||||
void deallocate_free_blocks()
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
private_node_allocator_t::deallocate_free_blocks();
|
||||
}
|
||||
|
||||
private:
|
||||
default_mutex mutex_;
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -15,9 +15,10 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/detail/utilities.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/intrusive/set.hpp>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -15,8 +15,373 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/aligned_storage.hpp>
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <iterator> //std::iterator_traits
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
|
||||
namespace boost { namespace container { namespace container_detail {
|
||||
|
||||
template<class A, class FwdIt, class Iterator>
|
||||
struct move_insert_range_proxy
|
||||
{
|
||||
typedef typename allocator_traits<A>::size_type size_type;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
|
||||
explicit move_insert_range_proxy(FwdIt first)
|
||||
: first_(first)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n)
|
||||
{
|
||||
this->first_ = ::boost::container::uninitialized_move_alloc_n_source
|
||||
(a, this->first_, n, p);
|
||||
}
|
||||
|
||||
void copy_n_and_update(A &, Iterator p, size_type n)
|
||||
{
|
||||
this->first_ = ::boost::container::move_n_source(this->first_, n, p);
|
||||
}
|
||||
|
||||
FwdIt first_;
|
||||
};
|
||||
|
||||
|
||||
template<class A, class FwdIt, class Iterator>
|
||||
struct insert_range_proxy
|
||||
{
|
||||
typedef typename allocator_traits<A>::size_type size_type;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
|
||||
explicit insert_range_proxy(FwdIt first)
|
||||
: first_(first)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n)
|
||||
{
|
||||
this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p);
|
||||
}
|
||||
|
||||
void copy_n_and_update(A &, Iterator p, size_type n)
|
||||
{
|
||||
this->first_ = ::boost::container::copy_n_source(this->first_, n, p);
|
||||
}
|
||||
|
||||
FwdIt first_;
|
||||
};
|
||||
|
||||
|
||||
template<class A, class Iterator>
|
||||
struct insert_n_copies_proxy
|
||||
{
|
||||
typedef typename allocator_traits<A>::size_type size_type;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
|
||||
explicit insert_n_copies_proxy(const value_type &v)
|
||||
: v_(v)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
|
||||
{ boost::container::uninitialized_fill_alloc_n(a, v_, n, p); }
|
||||
|
||||
void copy_n_and_update(A &, Iterator p, size_type n) const
|
||||
{ std::fill_n(p, n, v_); }
|
||||
|
||||
const value_type &v_;
|
||||
};
|
||||
|
||||
template<class A, class Iterator>
|
||||
struct insert_value_initialized_n_proxy
|
||||
{
|
||||
typedef ::boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef typename allocator_traits<A>::size_type size_type;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
|
||||
{ boost::container::uninitialized_value_init_alloc_n(a, n, p); }
|
||||
|
||||
void copy_n_and_update(A &, Iterator, size_type) const
|
||||
{ BOOST_ASSERT(false); }
|
||||
};
|
||||
|
||||
template<class A, class Iterator>
|
||||
struct insert_default_initialized_n_proxy
|
||||
{
|
||||
typedef ::boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef typename allocator_traits<A>::size_type size_type;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
|
||||
{ boost::container::uninitialized_default_init_alloc_n(a, n, p); }
|
||||
|
||||
void copy_n_and_update(A &, Iterator, size_type) const
|
||||
{ BOOST_ASSERT(false); }
|
||||
};
|
||||
|
||||
template<class A, class Iterator>
|
||||
struct insert_copy_proxy
|
||||
{
|
||||
typedef boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef typename alloc_traits::size_type size_type;
|
||||
typedef typename alloc_traits::value_type value_type;
|
||||
|
||||
explicit insert_copy_proxy(const value_type &v)
|
||||
: v_(v)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
alloc_traits::construct( a, container_detail::to_raw_pointer(&*p), v_);
|
||||
}
|
||||
|
||||
void copy_n_and_update(A &, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
*p =v_;
|
||||
}
|
||||
|
||||
const value_type &v_;
|
||||
};
|
||||
|
||||
|
||||
template<class A, class Iterator>
|
||||
struct insert_move_proxy
|
||||
{
|
||||
typedef boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef typename alloc_traits::size_type size_type;
|
||||
typedef typename alloc_traits::value_type value_type;
|
||||
|
||||
explicit insert_move_proxy(value_type &v)
|
||||
: v_(v)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
alloc_traits::construct( a
|
||||
, container_detail::to_raw_pointer(&*p)
|
||||
, ::boost::move(v_)
|
||||
);
|
||||
}
|
||||
|
||||
void copy_n_and_update(A &, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
*p = ::boost::move(v_);
|
||||
}
|
||||
|
||||
value_type &v_;
|
||||
};
|
||||
|
||||
template<class It, class A>
|
||||
insert_move_proxy<A, It> get_insert_value_proxy(BOOST_RV_REF(typename std::iterator_traits<It>::value_type) v)
|
||||
{
|
||||
return insert_move_proxy<A, It>(v);
|
||||
}
|
||||
|
||||
template<class It, class A>
|
||||
insert_copy_proxy<A, It> get_insert_value_proxy(const typename std::iterator_traits<It>::value_type &v)
|
||||
{
|
||||
return insert_copy_proxy<A, It>(v);
|
||||
}
|
||||
|
||||
}}} //namespace boost { namespace container { namespace container_detail {
|
||||
|
||||
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
|
||||
#include <boost/container/detail/variadic_templates_tools.hpp>
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <typeinfo>
|
||||
//#include <iostream> //For debugging purposes
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template<class A, class Iterator, class ...Args>
|
||||
struct insert_non_movable_emplace_proxy
|
||||
{
|
||||
typedef boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef typename alloc_traits::size_type size_type;
|
||||
typedef typename alloc_traits::value_type value_type;
|
||||
|
||||
typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
|
||||
|
||||
explicit insert_non_movable_emplace_proxy(Args&&... args)
|
||||
: args_(args...)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n)
|
||||
{ this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); }
|
||||
|
||||
private:
|
||||
template<int ...IdxPack>
|
||||
void priv_uninitialized_copy_some_and_update(A &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
alloc_traits::construct( a
|
||||
, container_detail::to_raw_pointer(&*p)
|
||||
, ::boost::forward<Args>(get<IdxPack>(this->args_))...
|
||||
);
|
||||
}
|
||||
|
||||
protected:
|
||||
tuple<Args&...> args_;
|
||||
};
|
||||
|
||||
template<class A, class Iterator, class ...Args>
|
||||
struct insert_emplace_proxy
|
||||
: public insert_non_movable_emplace_proxy<A, Iterator, Args...>
|
||||
{
|
||||
typedef insert_non_movable_emplace_proxy<A, Iterator, Args...> base_t;
|
||||
typedef boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef typename base_t::value_type value_type;
|
||||
typedef typename base_t::size_type size_type;
|
||||
typedef typename base_t::index_tuple_t index_tuple_t;
|
||||
|
||||
explicit insert_emplace_proxy(Args&&... args)
|
||||
: base_t(::boost::forward<Args>(args)...)
|
||||
{}
|
||||
|
||||
void copy_n_and_update(A &a, Iterator p, size_type n)
|
||||
{ this->priv_copy_some_and_update(a, index_tuple_t(), p, n); }
|
||||
|
||||
private:
|
||||
|
||||
template<int ...IdxPack>
|
||||
void priv_copy_some_and_update(A &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
|
||||
{
|
||||
BOOST_ASSERT(n ==1); (void)n;
|
||||
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
|
||||
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
|
||||
alloc_traits::construct(a, vp,
|
||||
::boost::forward<Args>(get<IdxPack>(this->args_))...);
|
||||
BOOST_TRY{
|
||||
*p = ::boost::move(*vp);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
alloc_traits::destroy(a, vp);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
alloc_traits::destroy(a, vp);
|
||||
}
|
||||
};
|
||||
|
||||
}}} //namespace boost { namespace container { namespace container_detail {
|
||||
|
||||
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
|
||||
#include <boost/container/detail/preprocessor.hpp>
|
||||
#include <boost/container/detail/value_init.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(N) \
|
||||
template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \
|
||||
struct BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
|
||||
{ \
|
||||
typedef boost::container::allocator_traits<A> alloc_traits; \
|
||||
typedef typename alloc_traits::size_type size_type; \
|
||||
typedef typename alloc_traits::value_type value_type; \
|
||||
\
|
||||
explicit BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
|
||||
( BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
|
||||
BOOST_PP_EXPR_IF(N, :) BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_INIT, _) \
|
||||
{} \
|
||||
\
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) \
|
||||
{ \
|
||||
BOOST_ASSERT(n == 1); (void)n; \
|
||||
alloc_traits::construct \
|
||||
( a \
|
||||
, container_detail::to_raw_pointer(&*p) \
|
||||
BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
|
||||
); \
|
||||
} \
|
||||
\
|
||||
void copy_n_and_update(A &, Iterator, size_type) \
|
||||
{ BOOST_ASSERT(false); } \
|
||||
\
|
||||
protected: \
|
||||
BOOST_PP_REPEAT(N, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
|
||||
}; \
|
||||
\
|
||||
template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \
|
||||
struct BOOST_PP_CAT(insert_emplace_proxy_arg, N) \
|
||||
: BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
|
||||
< A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > \
|
||||
{ \
|
||||
typedef BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
|
||||
<A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > base_t; \
|
||||
typedef typename base_t::value_type value_type; \
|
||||
typedef typename base_t::size_type size_type; \
|
||||
typedef boost::container::allocator_traits<A> alloc_traits; \
|
||||
\
|
||||
explicit BOOST_PP_CAT(insert_emplace_proxy_arg, N) \
|
||||
( BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
|
||||
: base_t(BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ) \
|
||||
{} \
|
||||
\
|
||||
void copy_n_and_update(A &a, Iterator p, size_type n) \
|
||||
{ \
|
||||
BOOST_ASSERT(n == 1); (void)n; \
|
||||
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
|
||||
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
|
||||
alloc_traits::construct(a, vp \
|
||||
BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
|
||||
BOOST_TRY{ \
|
||||
*p = ::boost::move(*vp); \
|
||||
} \
|
||||
BOOST_CATCH(...){ \
|
||||
alloc_traits::destroy(a, vp); \
|
||||
BOOST_RETHROW \
|
||||
} \
|
||||
BOOST_CATCH_END \
|
||||
alloc_traits::destroy(a, vp); \
|
||||
} \
|
||||
}; \
|
||||
//!
|
||||
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
}}} //namespace boost { namespace container { namespace container_detail {
|
||||
|
||||
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
|
||||
/*
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
|
||||
#define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/aligned_storage.hpp>
|
||||
@@ -391,3 +756,4 @@ struct BOOST_PP_CAT(insert_emplace_proxy_arg, N)
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
|
||||
*/
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -17,7 +17,7 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/type_traits/has_trivial_copy.hpp>
|
||||
|
||||
326
include/boost/container/detail/alloc_lib.h
Normal file
326
include/boost/container/detail/alloc_lib.h
Normal file
@@ -0,0 +1,326 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_CONTAINER_ALLOC_LIB_EXT_H
|
||||
#define BOOST_CONTAINER_ALLOC_LIB_EXT_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable : 4127)
|
||||
|
||||
/*
|
||||
we need to import/export our code only if the user has specifically
|
||||
asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
|
||||
libraries to be dynamically linked, or BOOST_CONTAINER_DYN_LINK
|
||||
if they want just this one to be dynamically liked:
|
||||
*/
|
||||
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTAINER_DYN_LINK)
|
||||
|
||||
/* export if this is our own source, otherwise import: */
|
||||
#ifdef BOOST_CONTAINER_SOURCE
|
||||
# define BOOST_CONTAINER_DECL __declspec(dllexport)
|
||||
#else
|
||||
# define BOOST_CONTAINER_DECL __declspec(dllimport)
|
||||
#endif /* BOOST_CONTAINER_SOURCE */
|
||||
#endif /* DYN_LINK */
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
/* if BOOST_CONTAINER_DECL isn't defined yet define it now: */
|
||||
#ifndef BOOST_CONTAINER_DECL
|
||||
#define BOOST_CONTAINER_DECL
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!An forward iterator to traverse the elements of a memory chain container.*/
|
||||
typedef struct multialloc_node_impl
|
||||
{
|
||||
struct multialloc_node_impl *next_node_ptr;
|
||||
} boost_cont_memchain_node;
|
||||
|
||||
|
||||
/*!An forward iterator to traverse the elements of a memory chain container.*/
|
||||
typedef struct multialloc_it_impl
|
||||
{
|
||||
boost_cont_memchain_node *node_ptr;
|
||||
} boost_cont_memchain_it;
|
||||
|
||||
/*!Memory chain: A container holding memory portions allocated by boost_cont_multialloc_nodes
|
||||
and boost_cont_multialloc_arrays functions.*/
|
||||
typedef struct boost_cont_memchain_impl
|
||||
{
|
||||
size_t num_mem;
|
||||
boost_cont_memchain_node root_node;
|
||||
boost_cont_memchain_node *last_node_ptr;
|
||||
} boost_cont_memchain;
|
||||
|
||||
/*!Advances the iterator one position so that it points to the next element in the memory chain*/
|
||||
#define BOOST_CONTAINER_MEMIT_NEXT(IT) (IT.node_ptr = IT.node_ptr->next_node_ptr)
|
||||
|
||||
/*!Returns the address of the memory chain currently pointed by the iterator*/
|
||||
#define BOOST_CONTAINER_MEMIT_ADDR(IT) ((void*)IT.node_ptr)
|
||||
|
||||
/*!Initializer for an iterator pointing to the position before the first element*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_BEFORE_BEGIN_IT(PMEMCHAIN) { &((PMEMCHAIN)->root_node) }
|
||||
|
||||
/*!Initializer for an iterator pointing to the first element*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(PMEMCHAIN) {(PMEMCHAIN)->root_node.next_node_ptr }
|
||||
|
||||
/*!Initializer for an iterator pointing to the last element*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_LAST_IT(PMEMCHAIN) {(PMEMCHAIN)->last_node_ptr }
|
||||
|
||||
/*!Initializer for an iterator pointing to one past the last element (end iterator)*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_END_IT(PMEMCHAIN) {(boost_cont_memchain_node *)0 }
|
||||
|
||||
/*!True if IT is the end iterator, false otherwise*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_IS_END_IT(PMEMCHAIN, IT) (!(IT).node_ptr)
|
||||
|
||||
/*!The address of the first memory portion hold by the memory chain*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(PMEMCHAIN)((void*)((PMEMCHAIN)->root_node.next_node_ptr))
|
||||
|
||||
/*!The address of the last memory portion hold by the memory chain*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_LASTMEM(PMEMCHAIN) ((void*)((PMEMCHAIN)->last_node_ptr))
|
||||
|
||||
/*!The number of memory portions hold by the memory chain*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_SIZE(PMEMCHAIN) ((PMEMCHAIN)->num_mem)
|
||||
|
||||
/*!Initializes the memory chain from the first memory portion, the last memory
|
||||
portion and number of portions obtained from another memory chain*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_INIT_FROM(PMEMCHAIN, FIRST, LAST, NUM)\
|
||||
(PMEMCHAIN)->last_node_ptr = (boost_cont_memchain_node *)(LAST), \
|
||||
(PMEMCHAIN)->root_node.next_node_ptr = (boost_cont_memchain_node *)(FIRST), \
|
||||
(PMEMCHAIN)->num_mem = (NUM);\
|
||||
/**/
|
||||
|
||||
/*!Default initializes a memory chain. Postconditions: begin iterator is end iterator,
|
||||
the number of portions is zero.*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_INIT(PMEMCHAIN)\
|
||||
((PMEMCHAIN)->root_node.next_node_ptr = 0, (PMEMCHAIN)->last_node_ptr = &((PMEMCHAIN)->root_node), (PMEMCHAIN)->num_mem = 0)\
|
||||
/**/
|
||||
|
||||
/*!True if the memory chain is empty (holds no memory portions*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_EMPTY(PMEMCHAIN)\
|
||||
((PMEMCHAIN)->num_mem == 0)\
|
||||
/**/
|
||||
|
||||
/*!Inserts a new memory portions in the front of the chain*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_PUSH_BACK(PMEMCHAIN, MEM)\
|
||||
do{\
|
||||
boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
||||
boost_cont_memchain_node *____tmp_mem____ = (boost_cont_memchain_node *)(MEM);\
|
||||
____chain____->last_node_ptr->next_node_ptr = ____tmp_mem____;\
|
||||
____tmp_mem____->next_node_ptr = 0;\
|
||||
____chain____->last_node_ptr = ____tmp_mem____;\
|
||||
++____chain____->num_mem;\
|
||||
}while(0)\
|
||||
/**/
|
||||
|
||||
/*!Inserts a new memory portions in the back of the chain*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_PUSH_FRONT(PMEMCHAIN, MEM)\
|
||||
do{\
|
||||
boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
||||
boost_cont_memchain_node *____tmp_mem____ = (boost_cont_memchain_node *)(MEM);\
|
||||
boost_cont_memchain *____root____ = &((PMEMCHAIN)->root_node);\
|
||||
if(!____chain____->root_node.next_node_ptr){\
|
||||
____chain____->last_node_ptr = ____tmp_mem____;\
|
||||
}\
|
||||
boost_cont_memchain_node *____old_first____ = ____root____->next_node_ptr;\
|
||||
____tmp_mem____->next_node_ptr = ____old_first____;\
|
||||
____root____->next_node_ptr = ____tmp_mem____;\
|
||||
++____chain____->num_mem;\
|
||||
}while(0)\
|
||||
/**/
|
||||
|
||||
/*!Erases the memory portion after the portion pointed by BEFORE_IT from the memory chain*/
|
||||
/*!Precondition: BEFORE_IT must be a valid iterator of the memory chain and it can't be the end iterator*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_ERASE_AFTER(PMEMCHAIN, BEFORE_IT)\
|
||||
do{\
|
||||
boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
||||
boost_cont_memchain_node *____prev_node____ = (BEFORE_IT).node_ptr;\
|
||||
boost_cont_memchain_node *____erase_node____ = ____prev_node____->next_node_ptr;\
|
||||
if(____chain____->last_node_ptr == ____erase_node____){\
|
||||
____chain____->last_node_ptr = &____chain____->root_node;\
|
||||
}\
|
||||
____prev_node____->next_node_ptr = ____erase_node____->next_node_ptr;\
|
||||
--____chain____->num_mem;\
|
||||
}while(0)\
|
||||
/**/
|
||||
|
||||
/*!Erases the first portion from the memory chain.
|
||||
Precondition: the memory chain must not be empty*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_POP_FRONT(PMEMCHAIN)\
|
||||
do{\
|
||||
boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
||||
boost_cont_memchain_node *____prev_node____ = &____chain____->root_node;\
|
||||
boost_cont_memchain_node *____erase_node____ = ____prev_node____->next_node_ptr;\
|
||||
if(____chain____->last_node_ptr == ____erase_node____){\
|
||||
____chain____->last_node_ptr = &____chain____->root_node;\
|
||||
}\
|
||||
____prev_node____->next_node_ptr = ____erase_node____->next_node_ptr;\
|
||||
--____chain____->num_mem;\
|
||||
}while(0)\
|
||||
/**/
|
||||
|
||||
/*!Joins two memory chains inserting the portions of the second chain at the back of the first chain*/
|
||||
/*
|
||||
#define BOOST_CONTAINER_MEMCHAIN_SPLICE_BACK(PMEMCHAIN, PMEMCHAIN2)\
|
||||
do{\
|
||||
boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
||||
boost_cont_memchain *____chain2____ = (PMEMCHAIN2);\
|
||||
if(!____chain2____->root_node.next_node_ptr){\
|
||||
break;\
|
||||
}\
|
||||
else if(!____chain____->first_mem){\
|
||||
____chain____->first_mem = ____chain2____->first_mem;\
|
||||
____chain____->last_node_ptr = ____chain2____->last_node_ptr;\
|
||||
____chain____->num_mem = ____chain2____->num_mem;\
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(*____chain2____);\
|
||||
}\
|
||||
else{\
|
||||
____chain____->last_node_ptr->next_node_ptr = ____chain2____->first_mem;\
|
||||
____chain____->last_node_ptr = ____chain2____->last_node_ptr;\
|
||||
____chain____->num_mem += ____chain2____->num_mem;\
|
||||
}\
|
||||
}while(0)\*/
|
||||
/**/
|
||||
|
||||
/*!Joins two memory chains inserting the portions of the second chain at the back of the first chain*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_INCORPORATE_AFTER(PMEMCHAIN, BEFORE_IT, FIRST, BEFORELAST, NUM)\
|
||||
do{\
|
||||
boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
||||
boost_cont_memchain_node *____pnode____ = (BEFORE_IT).node_ptr;\
|
||||
boost_cont_memchain_node *____next____ = ____pnode____->next_node_ptr;\
|
||||
boost_cont_memchain_node *____first____ = (boost_cont_memchain_node *)(FIRST);\
|
||||
boost_cont_memchain_node *____blast____ = (boost_cont_memchain_node *)(BEFORELAST);\
|
||||
size_t ____num____ = (NUM);\
|
||||
if(!____num____){\
|
||||
break;\
|
||||
}\
|
||||
if(____pnode____ == ____chain____->last_node_ptr){\
|
||||
____chain____->last_node_ptr = ____blast____;\
|
||||
}\
|
||||
____pnode____->next_node_ptr = ____first____;\
|
||||
____blast____->next_node_ptr = ____next____;\
|
||||
____chain____->num_mem += ____num____;\
|
||||
}while(0)\
|
||||
/**/
|
||||
|
||||
BOOST_CONTAINER_DECL size_t boost_cont_size(const void *p);
|
||||
|
||||
BOOST_CONTAINER_DECL void* boost_cont_malloc(size_t bytes);
|
||||
|
||||
BOOST_CONTAINER_DECL void boost_cont_free(void* mem);
|
||||
|
||||
BOOST_CONTAINER_DECL void* boost_cont_memalign(size_t bytes, size_t alignment);
|
||||
|
||||
/*!Indicates the all elements allocated by boost_cont_multialloc_nodes or boost_cont_multialloc_arrays
|
||||
must be contiguous.*/
|
||||
#define DL_MULTIALLOC_ALL_CONTIGUOUS ((size_t)(-1))
|
||||
|
||||
/*!Indicates the number of contiguous elements allocated by boost_cont_multialloc_nodes or boost_cont_multialloc_arrays
|
||||
should be selected by those functions.*/
|
||||
#define DL_MULTIALLOC_DEFAULT_CONTIGUOUS ((size_t)(0))
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_multialloc_nodes
|
||||
(size_t n_elements, size_t elem_size, size_t contiguous_elements, boost_cont_memchain *pchain);
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_multialloc_arrays
|
||||
(size_t n_elements, const size_t *sizes, size_t sizeof_element, size_t contiguous_elements, boost_cont_memchain *pchain);
|
||||
|
||||
BOOST_CONTAINER_DECL void boost_cont_multidealloc(boost_cont_memchain *pchain);
|
||||
|
||||
BOOST_CONTAINER_DECL size_t boost_cont_footprint();
|
||||
|
||||
BOOST_CONTAINER_DECL size_t boost_cont_allocated_memory();
|
||||
|
||||
BOOST_CONTAINER_DECL size_t boost_cont_chunksize(const void *p);
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_all_deallocated();
|
||||
|
||||
typedef struct boost_cont_malloc_stats_impl
|
||||
{
|
||||
size_t max_system_bytes;
|
||||
size_t system_bytes;
|
||||
size_t in_use_bytes;
|
||||
} boost_cont_malloc_stats_t;
|
||||
|
||||
BOOST_CONTAINER_DECL boost_cont_malloc_stats_t boost_cont_malloc_stats();
|
||||
|
||||
BOOST_CONTAINER_DECL size_t boost_cont_in_use_memory();
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_trim(size_t pad);
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_mallopt
|
||||
(int parameter_number, int parameter_value);
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_grow
|
||||
(void* oldmem, size_t minbytes, size_t maxbytes, size_t *received);
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_shrink
|
||||
(void* oldmem, size_t minbytes, size_t maxbytes, size_t *received, int do_commit);
|
||||
|
||||
BOOST_CONTAINER_DECL void* boost_cont_alloc
|
||||
(size_t minbytes, size_t preferred_bytes, size_t *received_bytes);
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_malloc_check();
|
||||
|
||||
typedef unsigned int allocation_type;
|
||||
|
||||
enum
|
||||
{
|
||||
// constants for allocation commands
|
||||
BOOST_CONTAINER_ALLOCATE_NEW = 0X01,
|
||||
BOOST_CONTAINER_EXPAND_FWD = 0X02,
|
||||
BOOST_CONTAINER_EXPAND_BWD = 0X04,
|
||||
BOOST_CONTAINER_SHRINK_IN_PLACE = 0X08,
|
||||
BOOST_CONTAINER_NOTHROW_ALLOCATION = 0X10,
|
||||
// BOOST_CONTAINER_ZERO_MEMORY = 0X20,
|
||||
BOOST_CONTAINER_TRY_SHRINK_IN_PLACE = 0X40,
|
||||
BOOST_CONTAINER_EXPAND_BOTH = BOOST_CONTAINER_EXPAND_FWD | BOOST_CONTAINER_EXPAND_BWD,
|
||||
BOOST_CONTAINER_EXPAND_OR_NEW = BOOST_CONTAINER_ALLOCATE_NEW | BOOST_CONTAINER_EXPAND_BOTH
|
||||
};
|
||||
|
||||
//#define BOOST_CONTAINERDLMALLOC__FOOTERS
|
||||
#ifndef BOOST_CONTAINERDLMALLOC__FOOTERS
|
||||
enum { BOOST_CONTAINER_ALLOCATION_PAYLOAD = sizeof(size_t) };
|
||||
#else
|
||||
enum { BOOST_CONTAINER_ALLOCATION_PAYLOAD = sizeof(size_t)*2 };
|
||||
#endif
|
||||
|
||||
typedef struct boost_cont_command_ret_impl
|
||||
{
|
||||
void *first;
|
||||
int second;
|
||||
}boost_cont_command_ret_t;
|
||||
|
||||
BOOST_CONTAINER_DECL boost_cont_command_ret_t boost_cont_allocation_command
|
||||
( allocation_type command
|
||||
, size_t sizeof_object
|
||||
, size_t limit_objects
|
||||
, size_t preferred_objects
|
||||
, size_t *received_objects
|
||||
, void *reuse_ptr
|
||||
);
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_mallopt(int param_number, int value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} //extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
|
||||
#endif //#define BOOST_CONTAINERDLMALLOC__EXT_H
|
||||
16
include/boost/container/detail/alloc_lib_auto_link.hpp
Normal file
16
include/boost/container/detail/alloc_lib_auto_link.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_CONTAINER_DETAIL_BOOST_CONT_EXT_AUTO_LINK_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_BOOST_CONT_EXT_AUTO_LINK_HPP
|
||||
|
||||
#include <boost/container/detail/auto_link.hpp>
|
||||
#include <boost/container/detail/alloc_lib.h>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_BOOST_CONT_EXT_AUTO_LINK_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -15,13 +15,13 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
enum allocation_type_v
|
||||
{
|
||||
// constants for allocation commands
|
||||
@@ -37,7 +37,7 @@ enum allocation_type_v
|
||||
};
|
||||
|
||||
typedef int allocation_type;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
static const allocation_type allocate_new = (allocation_type)allocate_new_v;
|
||||
static const allocation_type expand_fwd = (allocation_type)expand_fwd_v;
|
||||
static const allocation_type expand_bwd = (allocation_type)expand_bwd_v;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2012-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2012-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/allocator_traits.hpp> //allocator_traits
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp> //multiallocation_chain
|
||||
|
||||
38
include/boost/container/detail/auto_link.hpp
Normal file
38
include/boost/container/detail/auto_link.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_CONTAINER_DETAIL_AUTO_LINK_HPP_INCLUDED
|
||||
#define BOOST_CONTAINER_DETAIL_AUTO_LINK_HPP_INCLUDED
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Automatically link to the correct build variant where possible.
|
||||
//
|
||||
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_CONTAINER_NO_LIB) && !defined(BOOST_CONTAINER_SOURCE)
|
||||
//
|
||||
// Set the name of our library, this will get undef'ed by auto_link.hpp
|
||||
// once it's done with it:
|
||||
//
|
||||
#define BOOST_LIB_NAME boost_container
|
||||
//
|
||||
// If we're importing code from a dll, then tell auto_link.hpp about it:
|
||||
//
|
||||
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTAINER_DYN_LINK)
|
||||
# define BOOST_DYN_LINK
|
||||
#endif
|
||||
//
|
||||
// And include the header that does the work:
|
||||
//
|
||||
#include <boost/config/auto_link.hpp>
|
||||
#endif // auto-linking disabled
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_AUTO_LINK_HPP_INCLUDED
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -18,6 +18,10 @@
|
||||
#define BOOST_CONTAINER_DETAIL_CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
#ifndef _SCL_SECURE_NO_WARNINGS
|
||||
#define BOOST_CONTAINER_DETAIL_SCL_SECURE_NO_WARNINGS
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable : 4702) // unreachable code
|
||||
#pragma warning (disable : 4706) // assignment within conditional expression
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -13,5 +13,9 @@
|
||||
#undef BOOST_CONTAINER_DETAIL_CRT_SECURE_NO_DEPRECATE
|
||||
#undef _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
#ifdef BOOST_CONTAINER_DETAIL_SCL_SECURE_NO_WARNINGS
|
||||
#undef BOOST_CONTAINER_DETAIL_SCL_SECURE_NO_WARNINGS
|
||||
#undef _SCL_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -17,8 +17,9 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
#include <boost/container/detail/utilities.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
@@ -231,6 +232,9 @@ struct null_scoped_destructor_n
|
||||
void increment_size_backwards(size_type)
|
||||
{}
|
||||
|
||||
void shrink_forward(size_type)
|
||||
{}
|
||||
|
||||
void release()
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -15,7 +15,7 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
@@ -270,6 +270,9 @@ class flat_tree
|
||||
Compare key_comp() const
|
||||
{ return this->m_data.get_comp(); }
|
||||
|
||||
value_compare value_comp() const
|
||||
{ return this->m_data; }
|
||||
|
||||
allocator_type get_allocator() const
|
||||
{ return this->m_data.m_vect.get_allocator(); }
|
||||
|
||||
@@ -526,7 +529,7 @@ class flat_tree
|
||||
this->reserve(this->size()+len);
|
||||
const const_iterator b(this->cbegin());
|
||||
const_iterator pos(b);
|
||||
const value_compare &value_comp = this->m_data;
|
||||
const value_compare &val_cmp = this->m_data;
|
||||
skips[0u] = 0u;
|
||||
//Loop in burst sizes
|
||||
while(len){
|
||||
@@ -539,7 +542,7 @@ class flat_tree
|
||||
--len;
|
||||
pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, ce, KeyOfValue()(val));
|
||||
//Check if already present
|
||||
if(pos != ce && !value_comp(val, *pos)){
|
||||
if(pos != ce && !val_cmp(val, *pos)){
|
||||
if(unique_burst > 0){
|
||||
++skips[unique_burst-1];
|
||||
}
|
||||
@@ -714,6 +717,7 @@ class flat_tree
|
||||
return i;
|
||||
}
|
||||
|
||||
// set operations:
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
std::pair<const_iterator, const_iterator> p = this->equal_range(k);
|
||||
@@ -739,12 +743,44 @@ class flat_tree
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
|
||||
{ return this->priv_equal_range(this->cbegin(), this->cend(), k); }
|
||||
|
||||
std::pair<iterator, iterator> lower_bound_range(const key_type& k)
|
||||
{ return this->priv_lower_bound_range(this->begin(), this->end(), k); }
|
||||
|
||||
std::pair<const_iterator, const_iterator> lower_bound_range(const key_type& k) const
|
||||
{ return this->priv_lower_bound_range(this->cbegin(), this->cend(), k); }
|
||||
|
||||
size_type capacity() const
|
||||
{ return this->m_data.m_vect.capacity(); }
|
||||
|
||||
void reserve(size_type cnt)
|
||||
{ this->m_data.m_vect.reserve(cnt); }
|
||||
|
||||
friend bool operator==(const flat_tree& x, const flat_tree& y)
|
||||
{
|
||||
return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin());
|
||||
}
|
||||
|
||||
friend bool operator<(const flat_tree& x, const flat_tree& y)
|
||||
{
|
||||
return std::lexicographical_compare(x.begin(), x.end(),
|
||||
y.begin(), y.end());
|
||||
}
|
||||
|
||||
friend bool operator!=(const flat_tree& x, const flat_tree& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
friend bool operator>(const flat_tree& x, const flat_tree& y)
|
||||
{ return y < x; }
|
||||
|
||||
friend bool operator<=(const flat_tree& x, const flat_tree& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
friend bool operator>=(const flat_tree& x, const flat_tree& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
friend void swap(flat_tree& x, flat_tree& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
private:
|
||||
struct insert_commit_data
|
||||
{
|
||||
@@ -764,10 +800,10 @@ class flat_tree
|
||||
// insert val before upper_bound(val)
|
||||
// else
|
||||
// insert val before lower_bound(val)
|
||||
const value_compare &value_comp = this->m_data;
|
||||
const value_compare &val_cmp = this->m_data;
|
||||
|
||||
if(pos == this->cend() || !value_comp(*pos, val)){
|
||||
if (pos == this->cbegin() || !value_comp(val, pos[-1])){
|
||||
if(pos == this->cend() || !val_cmp(*pos, val)){
|
||||
if (pos == this->cbegin() || !val_cmp(val, pos[-1])){
|
||||
data.position = pos;
|
||||
}
|
||||
else{
|
||||
@@ -784,9 +820,9 @@ class flat_tree
|
||||
bool priv_insert_unique_prepare
|
||||
(const_iterator b, const_iterator e, const value_type& val, insert_commit_data &commit_data)
|
||||
{
|
||||
const value_compare &value_comp = this->m_data;
|
||||
const value_compare &val_cmp = this->m_data;
|
||||
commit_data.position = this->priv_lower_bound(b, e, KeyOfValue()(val));
|
||||
return commit_data.position == e || value_comp(val, *commit_data.position);
|
||||
return commit_data.position == e || val_cmp(val, *commit_data.position);
|
||||
}
|
||||
|
||||
bool priv_insert_unique_prepare
|
||||
@@ -807,9 +843,9 @@ class flat_tree
|
||||
// insert val after pos
|
||||
//else
|
||||
// insert val before lower_bound(val)
|
||||
const value_compare &value_comp = this->m_data;
|
||||
const value_compare &val_cmp = this->m_data;
|
||||
const const_iterator cend_it = this->cend();
|
||||
if(pos == cend_it || value_comp(val, *pos)){ //Check if val should go before end
|
||||
if(pos == cend_it || val_cmp(val, *pos)){ //Check if val should go before end
|
||||
const const_iterator cbeg = this->cbegin();
|
||||
commit_data.position = pos;
|
||||
if(pos == cbeg){ //If container is empty then insert it in the beginning
|
||||
@@ -817,10 +853,10 @@ class flat_tree
|
||||
}
|
||||
const_iterator prev(pos);
|
||||
--prev;
|
||||
if(value_comp(*prev, val)){ //If previous element was less, then it should go between prev and pos
|
||||
if(val_cmp(*prev, val)){ //If previous element was less, then it should go between prev and pos
|
||||
return true;
|
||||
}
|
||||
else if(!value_comp(val, *prev)){ //If previous was equal then insertion should fail
|
||||
else if(!val_cmp(val, *prev)){ //If previous was equal then insertion should fail
|
||||
commit_data.position = prev;
|
||||
return false;
|
||||
}
|
||||
@@ -846,7 +882,7 @@ class flat_tree
|
||||
}
|
||||
|
||||
template <class RanIt>
|
||||
RanIt priv_lower_bound(RanIt first, RanIt last,
|
||||
RanIt priv_lower_bound(RanIt first, const RanIt last,
|
||||
const key_type & key) const
|
||||
{
|
||||
const Compare &key_cmp = this->m_data.get_comp();
|
||||
@@ -855,24 +891,23 @@ class flat_tree
|
||||
RanIt middle;
|
||||
|
||||
while (len) {
|
||||
size_type half = len >> 1;
|
||||
size_type step = len >> 1;
|
||||
middle = first;
|
||||
middle += half;
|
||||
middle += step;
|
||||
|
||||
if (key_cmp(key_extract(*middle), key)) {
|
||||
++middle;
|
||||
first = middle;
|
||||
len = len - half - 1;
|
||||
first = ++middle;
|
||||
len -= step + 1;
|
||||
}
|
||||
else{
|
||||
len = step;
|
||||
}
|
||||
else
|
||||
len = half;
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
|
||||
template <class RanIt>
|
||||
RanIt priv_upper_bound(RanIt first, RanIt last,
|
||||
RanIt priv_upper_bound(RanIt first, const RanIt last,
|
||||
const key_type & key) const
|
||||
{
|
||||
const Compare &key_cmp = this->m_data.get_comp();
|
||||
@@ -881,16 +916,16 @@ class flat_tree
|
||||
RanIt middle;
|
||||
|
||||
while (len) {
|
||||
size_type half = len >> 1;
|
||||
size_type step = len >> 1;
|
||||
middle = first;
|
||||
middle += half;
|
||||
middle += step;
|
||||
|
||||
if (key_cmp(key, key_extract(*middle))) {
|
||||
len = half;
|
||||
len = step;
|
||||
}
|
||||
else{
|
||||
first = ++middle;
|
||||
len = len - half - 1;
|
||||
len -= step + 1;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
@@ -906,29 +941,41 @@ class flat_tree
|
||||
RanIt middle;
|
||||
|
||||
while (len) {
|
||||
size_type half = len >> 1;
|
||||
size_type step = len >> 1;
|
||||
middle = first;
|
||||
middle += half;
|
||||
middle += step;
|
||||
|
||||
if (key_cmp(key_extract(*middle), key)){
|
||||
first = middle;
|
||||
++first;
|
||||
len = len - half - 1;
|
||||
first = ++middle;
|
||||
len -= step + 1;
|
||||
}
|
||||
else if (key_cmp(key, key_extract(*middle))){
|
||||
len = half;
|
||||
len = step;
|
||||
}
|
||||
else {
|
||||
//Middle is equal to key
|
||||
last = first;
|
||||
last += len;
|
||||
first = this->priv_lower_bound(first, middle, key);
|
||||
return std::pair<RanIt, RanIt> (first, this->priv_upper_bound(++middle, last, key));
|
||||
return std::pair<RanIt, RanIt>
|
||||
( this->priv_lower_bound(first, middle, key)
|
||||
, this->priv_upper_bound(++middle, last, key));
|
||||
}
|
||||
}
|
||||
return std::pair<RanIt, RanIt>(first, first);
|
||||
}
|
||||
|
||||
template<class RanIt>
|
||||
std::pair<RanIt, RanIt> priv_lower_bound_range(RanIt first, RanIt last, const key_type& k) const
|
||||
{
|
||||
const Compare &key_cmp = this->m_data.get_comp();
|
||||
KeyOfValue key_extract;
|
||||
RanIt lb(this->priv_lower_bound(first, last, k)), ub(lb);
|
||||
if(lb != last && static_cast<difference_type>(!key_cmp(k, key_extract(*lb)))){
|
||||
++ub;
|
||||
}
|
||||
return std::pair<RanIt, RanIt>(lb, ub);
|
||||
}
|
||||
|
||||
template<class InIt>
|
||||
void priv_insert_equal_loop(InIt first, InIt last)
|
||||
{
|
||||
@@ -950,62 +997,6 @@ class flat_tree
|
||||
}
|
||||
};
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class A>
|
||||
inline bool
|
||||
operator==(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
|
||||
{
|
||||
return x.size() == y.size() &&
|
||||
std::equal(x.begin(), x.end(), y.begin());
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class A>
|
||||
inline bool
|
||||
operator<(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
|
||||
{
|
||||
return std::lexicographical_compare(x.begin(), x.end(),
|
||||
y.begin(), y.end());
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class A>
|
||||
inline bool
|
||||
operator!=(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class A>
|
||||
inline bool
|
||||
operator>(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
|
||||
{ return y < x; }
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class A>
|
||||
inline bool
|
||||
operator<=(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class A>
|
||||
inline bool
|
||||
operator>=(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class A>
|
||||
inline void
|
||||
swap(flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
|
||||
flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
} //namespace container {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2009-2013.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
383
include/boost/container/detail/hash_table.hpp
Normal file
383
include/boost/container/detail/hash_table.hpp
Normal file
@@ -0,0 +1,383 @@
|
||||
/*
|
||||
template <class Value, unsigned int Options = 0, class Hash = hash<Value>, class Pred = equal_to<Value>,
|
||||
class Alloc = allocator<Value> >
|
||||
class hash_set
|
||||
{
|
||||
public:
|
||||
// types
|
||||
typedef Value key_type;
|
||||
typedef key_type value_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
typedef Alloc allocator_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename allocator_traits<allocator_type>::pointer pointer;
|
||||
typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
|
||||
typedef typename allocator_traits<allocator_type>::size_type size_type;
|
||||
typedef typename allocator_traits<allocator_type>::difference_type difference_type;
|
||||
|
||||
typedef /unspecified/ iterator;
|
||||
typedef /unspecified/ const_iterator;
|
||||
typedef /unspecified/ local_iterator;
|
||||
typedef /unspecified/ const_local_iterator;
|
||||
|
||||
hash_set()
|
||||
noexcept(
|
||||
is_nothrow_default_constructible<hasher>::value &&
|
||||
is_nothrow_default_constructible<key_equal>::value &&
|
||||
is_nothrow_default_constructible<allocator_type>::value);
|
||||
explicit hash_set(size_type n, const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
template <class InputIterator>
|
||||
hash_set(InputIterator f, InputIterator l,
|
||||
size_type n = 0, const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
explicit hash_set(const allocator_type&);
|
||||
hash_set(const hash_set&);
|
||||
hash_set(const hash_set&, const Allocator&);
|
||||
hash_set(hash_set&&)
|
||||
noexcept(
|
||||
is_nothrow_move_constructible<hasher>::value &&
|
||||
is_nothrow_move_constructible<key_equal>::value &&
|
||||
is_nothrow_move_constructible<allocator_type>::value);
|
||||
hash_set(hash_set&&, const Allocator&);
|
||||
hash_set(initializer_list<value_type>, size_type n = 0,
|
||||
const hasher& hf = hasher(), const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
~hash_set();
|
||||
hash_set& operator=(const hash_set&);
|
||||
hash_set& operator=(hash_set&&)
|
||||
noexcept(
|
||||
allocator_type::propagate_on_container_move_assignment::value &&
|
||||
is_nothrow_move_assignable<allocator_type>::value &&
|
||||
is_nothrow_move_assignable<hasher>::value &&
|
||||
is_nothrow_move_assignable<key_equal>::value);
|
||||
hash_set& operator=(initializer_list<value_type>);
|
||||
|
||||
allocator_type get_allocator() const noexcept;
|
||||
|
||||
bool empty() const noexcept;
|
||||
size_type size() const noexcept;
|
||||
size_type max_size() const noexcept;
|
||||
|
||||
iterator begin() noexcept;
|
||||
iterator end() noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
const_iterator cbegin() const noexcept;
|
||||
const_iterator cend() const noexcept;
|
||||
|
||||
template <class... Args>
|
||||
pair<iterator, bool> emplace(Args&&... args);
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator position, Args&&... args);
|
||||
pair<iterator, bool> insert(const value_type& obj);
|
||||
pair<iterator, bool> insert(value_type&& obj);
|
||||
iterator insert(const_iterator hint, const value_type& obj);
|
||||
iterator insert(const_iterator hint, value_type&& obj);
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator first, InputIterator last);
|
||||
void insert(initializer_list<value_type>);
|
||||
|
||||
iterator erase(const_iterator position);
|
||||
size_type erase(const key_type& k);
|
||||
iterator erase(const_iterator first, const_iterator last);
|
||||
void clear() noexcept;
|
||||
|
||||
void swap(hash_set&)
|
||||
noexcept(
|
||||
(!allocator_type::propagate_on_container_swap::value ||
|
||||
__is_nothrow_swappable<allocator_type>::value) &&
|
||||
__is_nothrow_swappable<hasher>::value &&
|
||||
__is_nothrow_swappable<key_equal>::value);
|
||||
|
||||
hasher hash_function() const;
|
||||
key_equal key_eq() const;
|
||||
|
||||
iterator find(const key_type& k);
|
||||
const_iterator find(const key_type& k) const;
|
||||
size_type count(const key_type& k) const;
|
||||
pair<iterator, iterator> equal_range(const key_type& k);
|
||||
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
|
||||
|
||||
size_type bucket_count() const noexcept;
|
||||
size_type max_bucket_count() const noexcept;
|
||||
|
||||
size_type bucket_size(size_type n) const;
|
||||
size_type bucket(const key_type& k) const;
|
||||
|
||||
local_iterator begin(size_type n);
|
||||
local_iterator end(size_type n);
|
||||
const_local_iterator begin(size_type n) const;
|
||||
const_local_iterator end(size_type n) const;
|
||||
const_local_iterator cbegin(size_type n) const;
|
||||
const_local_iterator cend(size_type n) const;
|
||||
|
||||
float load_factor() const noexcept;
|
||||
float max_load_factor() const noexcept;
|
||||
void max_load_factor(float z);
|
||||
void rehash(size_type n);
|
||||
void reserve(size_type n);
|
||||
};
|
||||
|
||||
template <class Key, class T, unsigned int Options = 0, class Hash = hash<Key>, class Pred = equal_to<Key>,
|
||||
class Alloc = allocator<pair<const Key, T> > >
|
||||
class hash_map
|
||||
{
|
||||
public:
|
||||
// types
|
||||
typedef Key key_type;
|
||||
typedef T mapped_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
typedef Alloc allocator_type;
|
||||
typedef pair<const key_type, mapped_type> value_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename allocator_traits<allocator_type>::pointer pointer;
|
||||
typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
|
||||
typedef typename allocator_traits<allocator_type>::size_type size_type;
|
||||
typedef typename allocator_traits<allocator_type>::difference_type difference_type;
|
||||
|
||||
typedef /unspecified/ iterator;
|
||||
typedef /unspecified/ const_iterator;
|
||||
typedef /unspecified/ local_iterator;
|
||||
typedef /unspecified/ const_local_iterator;
|
||||
|
||||
hash_map()
|
||||
noexcept(
|
||||
is_nothrow_default_constructible<hasher>::value &&
|
||||
is_nothrow_default_constructible<key_equal>::value &&
|
||||
is_nothrow_default_constructible<allocator_type>::value);
|
||||
explicit hash_map(size_type n, const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
template <class InputIterator>
|
||||
hash_map(InputIterator f, InputIterator l,
|
||||
size_type n = 0, const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
explicit hash_map(const allocator_type&);
|
||||
hash_map(const hash_map&);
|
||||
hash_map(const hash_map&, const Allocator&);
|
||||
hash_map(hash_map&&)
|
||||
noexcept(
|
||||
is_nothrow_move_constructible<hasher>::value &&
|
||||
is_nothrow_move_constructible<key_equal>::value &&
|
||||
is_nothrow_move_constructible<allocator_type>::value);
|
||||
hash_map(hash_map&&, const Allocator&);
|
||||
hash_map(initializer_list<value_type>, size_type n = 0,
|
||||
const hasher& hf = hasher(), const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
~hash_map();
|
||||
hash_map& operator=(const hash_map&);
|
||||
hash_map& operator=(hash_map&&)
|
||||
noexcept(
|
||||
allocator_type::propagate_on_container_move_assignment::value &&
|
||||
is_nothrow_move_assignable<allocator_type>::value &&
|
||||
is_nothrow_move_assignable<hasher>::value &&
|
||||
is_nothrow_move_assignable<key_equal>::value);
|
||||
hash_map& operator=(initializer_list<value_type>);
|
||||
|
||||
allocator_type get_allocator() const noexcept;
|
||||
|
||||
bool empty() const noexcept;
|
||||
size_type size() const noexcept;
|
||||
size_type max_size() const noexcept;
|
||||
|
||||
iterator begin() noexcept;
|
||||
iterator end() noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
const_iterator cbegin() const noexcept;
|
||||
const_iterator cend() const noexcept;
|
||||
|
||||
template <class... Args>
|
||||
pair<iterator, bool> emplace(Args&&... args);
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator position, Args&&... args);
|
||||
pair<iterator, bool> insert(const value_type& obj);
|
||||
template <class P>
|
||||
pair<iterator, bool> insert(P&& obj);
|
||||
iterator insert(const_iterator hint, const value_type& obj);
|
||||
template <class P>
|
||||
iterator insert(const_iterator hint, P&& obj);
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator first, InputIterator last);
|
||||
void insert(initializer_list<value_type>);
|
||||
|
||||
iterator erase(const_iterator position);
|
||||
size_type erase(const key_type& k);
|
||||
iterator erase(const_iterator first, const_iterator last);
|
||||
void clear() noexcept;
|
||||
|
||||
void swap(hash_map&)
|
||||
noexcept(
|
||||
(!allocator_type::propagate_on_container_swap::value ||
|
||||
__is_nothrow_swappable<allocator_type>::value) &&
|
||||
__is_nothrow_swappable<hasher>::value &&
|
||||
__is_nothrow_swappable<key_equal>::value);
|
||||
|
||||
hasher hash_function() const;
|
||||
key_equal key_eq() const;
|
||||
|
||||
iterator find(const key_type& k);
|
||||
const_iterator find(const key_type& k) const;
|
||||
size_type count(const key_type& k) const;
|
||||
pair<iterator, iterator> equal_range(const key_type& k);
|
||||
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
|
||||
|
||||
mapped_type& operator[](const key_type& k);
|
||||
mapped_type& operator[](key_type&& k);
|
||||
|
||||
mapped_type& at(const key_type& k);
|
||||
const mapped_type& at(const key_type& k) const;
|
||||
|
||||
size_type bucket_count() const noexcept;
|
||||
size_type max_bucket_count() const noexcept;
|
||||
|
||||
size_type bucket_size(size_type n) const;
|
||||
size_type bucket(const key_type& k) const;
|
||||
|
||||
local_iterator begin(size_type n);
|
||||
local_iterator end(size_type n);
|
||||
const_local_iterator begin(size_type n) const;
|
||||
const_local_iterator end(size_type n) const;
|
||||
const_local_iterator cbegin(size_type n) const;
|
||||
const_local_iterator cend(size_type n) const;
|
||||
|
||||
float load_factor() const noexcept;
|
||||
float max_load_factor() const noexcept;
|
||||
void max_load_factor(float z);
|
||||
void rehash(size_type n);
|
||||
void reserve(size_type n);
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
template <class Key, class Value, class KeyOfValue, unsigned int Options = 0, class Hash = hash<Key>, class Pred = equal_to<Key>,
|
||||
class Alloc = allocator<Value> >
|
||||
class hash_table
|
||||
{
|
||||
public:
|
||||
// types
|
||||
typedef Value key_type;
|
||||
typedef key_type value_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
typedef Alloc allocator_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename allocator_traits<allocator_type>::pointer pointer;
|
||||
typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
|
||||
typedef typename allocator_traits<allocator_type>::size_type size_type;
|
||||
typedef typename allocator_traits<allocator_type>::difference_type difference_type;
|
||||
|
||||
typedef /unspecified/ iterator;
|
||||
typedef /unspecified/ const_iterator;
|
||||
typedef /unspecified/ local_iterator;
|
||||
typedef /unspecified/ const_local_iterator;
|
||||
|
||||
hash_set()
|
||||
noexcept(
|
||||
is_nothrow_default_constructible<hasher>::value &&
|
||||
is_nothrow_default_constructible<key_equal>::value &&
|
||||
is_nothrow_default_constructible<allocator_type>::value);
|
||||
explicit hash_set(size_type n, const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
template <class InputIterator>
|
||||
hash_set(InputIterator f, InputIterator l,
|
||||
size_type n = 0, const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
explicit hash_set(const allocator_type&);
|
||||
hash_set(const hash_set&);
|
||||
hash_set(const hash_set&, const Allocator&);
|
||||
hash_set(hash_set&&)
|
||||
noexcept(
|
||||
is_nothrow_move_constructible<hasher>::value &&
|
||||
is_nothrow_move_constructible<key_equal>::value &&
|
||||
is_nothrow_move_constructible<allocator_type>::value);
|
||||
hash_set(hash_set&&, const Allocator&);
|
||||
hash_set(initializer_list<value_type>, size_type n = 0,
|
||||
const hasher& hf = hasher(), const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
~hash_set();
|
||||
hash_set& operator=(const hash_set&);
|
||||
hash_set& operator=(hash_set&&)
|
||||
noexcept(
|
||||
allocator_type::propagate_on_container_move_assignment::value &&
|
||||
is_nothrow_move_assignable<allocator_type>::value &&
|
||||
is_nothrow_move_assignable<hasher>::value &&
|
||||
is_nothrow_move_assignable<key_equal>::value);
|
||||
hash_set& operator=(initializer_list<value_type>);
|
||||
|
||||
allocator_type get_allocator() const noexcept;
|
||||
|
||||
bool empty() const noexcept;
|
||||
size_type size() const noexcept;
|
||||
size_type max_size() const noexcept;
|
||||
|
||||
iterator begin() noexcept;
|
||||
iterator end() noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
const_iterator cbegin() const noexcept;
|
||||
const_iterator cend() const noexcept;
|
||||
|
||||
template <class... Args>
|
||||
pair<iterator, bool> emplace(Args&&... args);
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator position, Args&&... args);
|
||||
pair<iterator, bool> insert(const value_type& obj);
|
||||
pair<iterator, bool> insert(value_type&& obj);
|
||||
iterator insert(const_iterator hint, const value_type& obj);
|
||||
iterator insert(const_iterator hint, value_type&& obj);
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator first, InputIterator last);
|
||||
void insert(initializer_list<value_type>);
|
||||
|
||||
iterator erase(const_iterator position);
|
||||
size_type erase(const key_type& k);
|
||||
iterator erase(const_iterator first, const_iterator last);
|
||||
void clear() noexcept;
|
||||
|
||||
void swap(hash_set&)
|
||||
noexcept(
|
||||
(!allocator_type::propagate_on_container_swap::value ||
|
||||
__is_nothrow_swappable<allocator_type>::value) &&
|
||||
__is_nothrow_swappable<hasher>::value &&
|
||||
__is_nothrow_swappable<key_equal>::value);
|
||||
|
||||
hasher hash_function() const;
|
||||
key_equal key_eq() const;
|
||||
|
||||
iterator find(const key_type& k);
|
||||
const_iterator find(const key_type& k) const;
|
||||
size_type count(const key_type& k) const;
|
||||
pair<iterator, iterator> equal_range(const key_type& k);
|
||||
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
|
||||
|
||||
size_type bucket_count() const noexcept;
|
||||
size_type max_bucket_count() const noexcept;
|
||||
|
||||
size_type bucket_size(size_type n) const;
|
||||
size_type bucket(const key_type& k) const;
|
||||
|
||||
local_iterator begin(size_type n);
|
||||
local_iterator end(size_type n);
|
||||
const_local_iterator begin(size_type n) const;
|
||||
const_local_iterator end(size_type n) const;
|
||||
const_local_iterator cbegin(size_type n) const;
|
||||
const_local_iterator cend(size_type n) const;
|
||||
|
||||
float load_factor() const noexcept;
|
||||
float max_load_factor() const noexcept;
|
||||
void max_load_factor(float z);
|
||||
void rehash(size_type n);
|
||||
void reserve(size_type n);
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
@@ -18,7 +18,7 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Stephen Cleary 2000.
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -16,7 +16,9 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <climits>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -17,20 +17,22 @@
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/detail/preprocessor.hpp>
|
||||
#include <boost/intrusive/detail/memory_util.hpp>
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 2, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (2, 2, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME destroy
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 3, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME max_size
|
||||
@@ -48,20 +50,19 @@
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME construct
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS+1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS+1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME swap
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_pointer)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference)
|
||||
@@ -73,6 +74,8 @@ BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assig
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_swap)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(wrapped_value_compare)
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -17,6 +17,9 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
@@ -110,8 +113,10 @@ struct if_
|
||||
|
||||
template <class Pair>
|
||||
struct select1st
|
||||
// : public std::unary_function<Pair, typename Pair::first_type>
|
||||
{
|
||||
typedef Pair argument_type;
|
||||
typedef typename Pair::first_type result_type;
|
||||
|
||||
template<class OtherPair>
|
||||
const typename Pair::first_type& operator()(const OtherPair& x) const
|
||||
{ return x.first; }
|
||||
@@ -123,8 +128,10 @@ struct select1st
|
||||
// identity is an extension: it is not part of the standard.
|
||||
template <class T>
|
||||
struct identity
|
||||
// : public std::unary_function<T,T>
|
||||
{
|
||||
typedef T argument_type;
|
||||
typedef T result_type;
|
||||
|
||||
typedef T type;
|
||||
const T& operator()(const T& x) const
|
||||
{ return x; }
|
||||
@@ -156,5 +163,7 @@ template <> struct unvoid<const void> { struct type { }; };
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -11,7 +11,9 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/detail/utilities.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
278
include/boost/container/detail/mutex.hpp
Normal file
278
include/boost/container/detail/mutex.hpp
Normal file
@@ -0,0 +1,278 @@
|
||||
// Copyright (C) 2000 Stephen Cleary
|
||||
//
|
||||
// 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 for updates, documentation, and revision history.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_MUTEX_HPP
|
||||
#define BOOST_CONTAINER_MUTEX_HPP
|
||||
|
||||
//#define BOOST_CONTAINER_NO_MT
|
||||
//#define BOOST_CONTAINER_NO_SPINLOCKS
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
// Extremely Light-Weight wrapper classes for OS thread synchronization
|
||||
|
||||
#define BOOST_MUTEX_HELPER_NONE 0
|
||||
#define BOOST_MUTEX_HELPER_WIN32 1
|
||||
#define BOOST_MUTEX_HELPER_PTHREAD 2
|
||||
#define BOOST_MUTEX_HELPER_SPINLOCKS 3
|
||||
|
||||
#if !defined(BOOST_HAS_THREADS) && !defined(BOOST_NO_MT)
|
||||
# define BOOST_NO_MT
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_MT) || defined(BOOST_CONTAINER_NO_MT)
|
||||
// No multithreading -> make locks into no-ops
|
||||
#define BOOST_MUTEX_HELPER BOOST_MUTEX_HELPER_NONE
|
||||
#else
|
||||
//Taken from dlmalloc
|
||||
#if !defined(BOOST_CONTAINER_NO_SPINLOCKS) && \
|
||||
((defined(__GNUC__) && \
|
||||
((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) || \
|
||||
defined(__i386__) || defined(__x86_64__))) || \
|
||||
(defined(_MSC_VER) && _MSC_VER>=1310))
|
||||
#define BOOST_MUTEX_HELPER BOOST_MUTEX_HELPER_SPINLOCKS
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
#include <windows.h>
|
||||
#ifndef BOOST_MUTEX_HELPER
|
||||
#define BOOST_MUTEX_HELPER BOOST_MUTEX_HELPER_WIN32
|
||||
#endif
|
||||
#elif defined(BOOST_HAS_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
#if !defined(BOOST_MUTEX_HELPER) && (defined(_POSIX_THREADS) || defined(BOOST_HAS_PTHREADS))
|
||||
#define BOOST_MUTEX_HELPER BOOST_MUTEX_HELPER_PTHREAD
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_MUTEX_HELPER
|
||||
#error Unable to determine platform mutex type; #define BOOST_NO_MT to assume single-threaded
|
||||
#endif
|
||||
|
||||
#if BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_NONE
|
||||
//...
|
||||
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_SPINLOCKS
|
||||
#if defined(_MSC_VER)
|
||||
#ifndef _M_AMD64
|
||||
/* These are already defined on AMD64 builds */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
long __cdecl _InterlockedCompareExchange(long volatile *Dest, long Exchange, long Comp);
|
||||
long __cdecl _InterlockedExchange(long volatile *Target, long Value);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* _M_AMD64 */
|
||||
#pragma intrinsic (_InterlockedCompareExchange)
|
||||
#pragma intrinsic (_InterlockedExchange)
|
||||
#define interlockedcompareexchange _InterlockedCompareExchange
|
||||
#define interlockedexchange _InterlockedExchange
|
||||
#elif defined(WIN32) && defined(__GNUC__)
|
||||
#define interlockedcompareexchange(a, b, c) __sync_val_compare_and_swap(a, c, b)
|
||||
#define interlockedexchange __sync_lock_test_and_set
|
||||
#endif /* Win32 */
|
||||
|
||||
/* First, define CAS_LOCK and CLEAR_LOCK on ints */
|
||||
/* Note CAS_LOCK defined to return 0 on success */
|
||||
|
||||
#if defined(__GNUC__)&& (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
|
||||
#define BOOST_CONTAINER_CAS_LOCK(sl) __sync_lock_test_and_set(sl, 1)
|
||||
#define BOOST_CONTAINER_CLEAR_LOCK(sl) __sync_lock_release(sl)
|
||||
|
||||
#elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
|
||||
/* Custom spin locks for older gcc on x86 */
|
||||
static FORCEINLINE int boost_container_x86_cas_lock(int *sl) {
|
||||
int ret;
|
||||
int val = 1;
|
||||
int cmp = 0;
|
||||
__asm__ __volatile__ ("lock; cmpxchgl %1, %2"
|
||||
: "=a" (ret)
|
||||
: "r" (val), "m" (*(sl)), "0"(cmp)
|
||||
: "memory", "cc");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static FORCEINLINE void boost_container_x86_clear_lock(int* sl) {
|
||||
assert(*sl != 0);
|
||||
int prev = 0;
|
||||
int ret;
|
||||
__asm__ __volatile__ ("lock; xchgl %0, %1"
|
||||
: "=r" (ret)
|
||||
: "m" (*(sl)), "0"(prev)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#define BOOST_CONTAINER_CAS_LOCK(sl) boost_container_x86_cas_lock(sl)
|
||||
#define BOOST_CONTAINER_CLEAR_LOCK(sl) boost_container_x86_clear_lock(sl)
|
||||
|
||||
#else /* Win32 MSC */
|
||||
#define BOOST_CONTAINER_CAS_LOCK(sl) interlockedexchange((long volatile*)sl, (long)1)
|
||||
#define BOOST_CONTAINER_CLEAR_LOCK(sl) interlockedexchange((long volatile*)sl, (long)0)
|
||||
#endif
|
||||
|
||||
/* How to yield for a spin lock */
|
||||
#define SPINS_PER_YIELD 63
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||
#define SLEEP_EX_DURATION 50 /* delay for yield/sleep */
|
||||
#define SPIN_LOCK_YIELD SleepEx(SLEEP_EX_DURATION, FALSE)
|
||||
#elif defined (__SVR4) && defined (__sun) /* solaris */
|
||||
#define SPIN_LOCK_YIELD thr_yield();
|
||||
#elif !defined(LACKS_SCHED_H)
|
||||
#define SPIN_LOCK_YIELD sched_yield();
|
||||
#else
|
||||
#define SPIN_LOCK_YIELD
|
||||
#endif /* ... yield ... */
|
||||
|
||||
#define BOOST_CONTAINER_SPINS_PER_YIELD 63
|
||||
inline int boost_interprocess_spin_acquire_lock(int *sl) {
|
||||
int spins = 0;
|
||||
while (*(volatile int *)sl != 0 ||
|
||||
BOOST_CONTAINER_CAS_LOCK(sl)) {
|
||||
if ((++spins & BOOST_CONTAINER_SPINS_PER_YIELD) == 0) {
|
||||
SPIN_LOCK_YIELD;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#define BOOST_CONTAINER_MLOCK_T int
|
||||
#define BOOST_CONTAINER_TRY_LOCK(sl) !BOOST_CONTAINER_CAS_LOCK(sl)
|
||||
#define BOOST_CONTAINER_RELEASE_LOCK(sl) BOOST_CONTAINER_CLEAR_LOCK(sl)
|
||||
#define BOOST_CONTAINER_ACQUIRE_LOCK(sl) (BOOST_CONTAINER_CAS_LOCK(sl)? boost_interprocess_spin_acquire_lock(sl) : 0)
|
||||
#define BOOST_CONTAINER_INITIAL_LOCK(sl) (*sl = 0)
|
||||
#define BOOST_CONTAINER_DESTROY_LOCK(sl) (0)
|
||||
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_WIN32
|
||||
//
|
||||
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_PTHREAD
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
#if BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_NONE
|
||||
class null_mutex
|
||||
{
|
||||
private:
|
||||
null_mutex(const null_mutex &);
|
||||
void operator=(const null_mutex &);
|
||||
|
||||
public:
|
||||
null_mutex() { }
|
||||
|
||||
static void lock() { }
|
||||
static void unlock() { }
|
||||
};
|
||||
|
||||
typedef null_mutex default_mutex;
|
||||
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_SPINLOCKS
|
||||
|
||||
class spin_mutex
|
||||
{
|
||||
private:
|
||||
BOOST_CONTAINER_MLOCK_T sl;
|
||||
spin_mutex(const spin_mutex &);
|
||||
void operator=(const spin_mutex &);
|
||||
|
||||
public:
|
||||
spin_mutex() { BOOST_CONTAINER_INITIAL_LOCK(&sl); }
|
||||
|
||||
void lock() { BOOST_CONTAINER_ACQUIRE_LOCK(&sl); }
|
||||
void unlock() { BOOST_CONTAINER_RELEASE_LOCK(&sl); }
|
||||
};
|
||||
typedef spin_mutex default_mutex;
|
||||
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_WIN32
|
||||
class mutex
|
||||
{
|
||||
private:
|
||||
CRITICAL_SECTION mtx;
|
||||
|
||||
mutex(const mutex &);
|
||||
void operator=(const mutex &);
|
||||
|
||||
public:
|
||||
mutex()
|
||||
{ InitializeCriticalSection(&mtx); }
|
||||
|
||||
~mutex()
|
||||
{ DeleteCriticalSection(&mtx); }
|
||||
|
||||
void lock()
|
||||
{ EnterCriticalSection(&mtx); }
|
||||
|
||||
void unlock()
|
||||
{ LeaveCriticalSection(&mtx); }
|
||||
};
|
||||
|
||||
typedef mutex default_mutex;
|
||||
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_PTHREAD
|
||||
class mutex
|
||||
{
|
||||
private:
|
||||
pthread_mutex_t mtx;
|
||||
|
||||
mutex(const mutex &);
|
||||
void operator=(const mutex &);
|
||||
|
||||
public:
|
||||
mutex()
|
||||
{ pthread_mutex_init(&mtx, 0); }
|
||||
|
||||
~mutex()
|
||||
{ pthread_mutex_destroy(&mtx); }
|
||||
|
||||
void lock()
|
||||
{ pthread_mutex_lock(&mtx); }
|
||||
|
||||
void unlock()
|
||||
{ pthread_mutex_unlock(&mtx); }
|
||||
};
|
||||
|
||||
typedef mutex default_mutex;
|
||||
#endif
|
||||
|
||||
template<class Mutex>
|
||||
class scoped_lock
|
||||
{
|
||||
public:
|
||||
scoped_lock(Mutex &m)
|
||||
: m_(m)
|
||||
{ m_.lock(); }
|
||||
~scoped_lock()
|
||||
{ m_.unlock(); }
|
||||
|
||||
private:
|
||||
Mutex &m_;
|
||||
};
|
||||
|
||||
} // namespace container_detail
|
||||
} // namespace container
|
||||
} // namespace boost
|
||||
|
||||
#undef BOOST_MUTEX_HELPER_WIN32
|
||||
#undef BOOST_MUTEX_HELPER_PTHREAD
|
||||
#undef BOOST_MUTEX_HELPER_NONE
|
||||
#undef BOOST_MUTEX_HELPER
|
||||
#undef BOOST_MUTEX_HELPER_SPINLOCKS
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -15,7 +15,7 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <utility>
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <boost/container/detail/allocator_version_traits.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/container/detail/memory_util.hpp>
|
||||
#include <boost/container/detail/allocator_version_traits.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
|
||||
@@ -50,33 +51,44 @@ template<class ValueCompare, class Node>
|
||||
struct node_compare
|
||||
: private ValueCompare
|
||||
{
|
||||
typedef typename ValueCompare::key_type key_type;
|
||||
typedef typename ValueCompare::value_type value_type;
|
||||
typedef typename ValueCompare::key_of_value key_of_value;
|
||||
typedef ValueCompare wrapped_value_compare;
|
||||
typedef typename wrapped_value_compare::key_type key_type;
|
||||
typedef typename wrapped_value_compare::value_type value_type;
|
||||
typedef typename wrapped_value_compare::key_of_value key_of_value;
|
||||
|
||||
explicit node_compare(const ValueCompare &pred)
|
||||
: ValueCompare(pred)
|
||||
explicit node_compare(const wrapped_value_compare &pred)
|
||||
: wrapped_value_compare(pred)
|
||||
{}
|
||||
|
||||
node_compare()
|
||||
: ValueCompare()
|
||||
: wrapped_value_compare()
|
||||
{}
|
||||
|
||||
ValueCompare &value_comp()
|
||||
{ return static_cast<ValueCompare &>(*this); }
|
||||
wrapped_value_compare &value_comp()
|
||||
{ return static_cast<wrapped_value_compare &>(*this); }
|
||||
|
||||
ValueCompare &value_comp() const
|
||||
{ return static_cast<const ValueCompare &>(*this); }
|
||||
wrapped_value_compare &value_comp() const
|
||||
{ return static_cast<const wrapped_value_compare &>(*this); }
|
||||
|
||||
bool operator()(const Node &a, const Node &b) const
|
||||
{ return ValueCompare::operator()(a.get_data(), b.get_data()); }
|
||||
{ return wrapped_value_compare::operator()(a.get_data(), b.get_data()); }
|
||||
};
|
||||
|
||||
template<class A, class ICont, class ValPred = container_detail::nat>
|
||||
template<class A, class ICont>
|
||||
struct node_alloc_holder
|
||||
{
|
||||
//If the intrusive container is an associative container, obtain the predicate, which will
|
||||
//be of type node_compare<>. If not an associative container value_compare will be a "nat" type.
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, ICont,
|
||||
value_compare, container_detail::nat) intrusive_value_compare;
|
||||
//In that case obtain the value predicate from the node predicate via wrapped_value_compare
|
||||
//if intrusive_value_compare is node_compare<>, nat otherwise
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, ICont,
|
||||
wrapped_value_compare, container_detail::nat) value_compare;
|
||||
|
||||
typedef allocator_traits<A> allocator_traits_type;
|
||||
typedef typename allocator_traits_type::value_type value_type;
|
||||
typedef ICont intrusive_container;
|
||||
typedef typename ICont::value_type Node;
|
||||
typedef typename allocator_traits_type::template
|
||||
portable_rebind_alloc<Node>::type NodeAlloc;
|
||||
@@ -121,20 +133,20 @@ struct node_alloc_holder
|
||||
{ this->icont().swap(x.icont()); }
|
||||
|
||||
//Constructors for associative containers
|
||||
explicit node_alloc_holder(const ValAlloc &a, const ValPred &c)
|
||||
explicit node_alloc_holder(const ValAlloc &a, const value_compare &c)
|
||||
: members_(a, c)
|
||||
{}
|
||||
|
||||
explicit node_alloc_holder(const node_alloc_holder &x, const ValPred &c)
|
||||
explicit node_alloc_holder(const node_alloc_holder &x, const value_compare &c)
|
||||
: members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c)
|
||||
{}
|
||||
|
||||
explicit node_alloc_holder(const ValPred &c)
|
||||
explicit node_alloc_holder(const value_compare &c)
|
||||
: members_(c)
|
||||
{}
|
||||
|
||||
//helpers for move assignments
|
||||
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const ValPred &c)
|
||||
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const value_compare &c)
|
||||
: members_(boost::move(x.node_alloc()), c)
|
||||
{ this->icont().swap(x.icont()); }
|
||||
|
||||
@@ -346,12 +358,12 @@ struct node_alloc_holder
|
||||
{}
|
||||
|
||||
template<class ConvertibleToAlloc>
|
||||
members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const ValPred &c)
|
||||
members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const value_compare &c)
|
||||
: NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
|
||||
, m_icont(typename ICont::value_compare(c))
|
||||
{}
|
||||
|
||||
explicit members_holder(const ValPred &c)
|
||||
explicit members_holder(const value_compare &c)
|
||||
: NodeAlloc()
|
||||
, m_icont(typename ICont::value_compare(c))
|
||||
{}
|
||||
|
||||
157
include/boost/container/detail/node_pool.hpp
Normal file
157
include/boost/container/detail/node_pool.hpp
Normal file
@@ -0,0 +1,157 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_NODE_POOL_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/detail/mutex.hpp>
|
||||
#include <boost/container/detail/pool_common_alloc.hpp>
|
||||
#include <boost/container/detail/node_pool_impl.hpp>
|
||||
#include <boost/container/detail/mutex.hpp>
|
||||
#include <boost/intrusive/slist.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
#include <functional> //std::unary_function
|
||||
#include <algorithm> //std::swap
|
||||
#include <cassert>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
//!Pooled memory allocator using single segregated storage. Includes
|
||||
//!a reference count but the class does not delete itself, this is
|
||||
//!responsibility of user classes. Node size (NodeSize) and the number of
|
||||
//!nodes allocated per block (NodesPerBlock) are known at compile time
|
||||
template< std::size_t NodeSize, std::size_t NodesPerBlock >
|
||||
class private_node_pool
|
||||
//Inherit from the implementation to avoid template bloat
|
||||
: public boost::container::container_detail::
|
||||
private_node_pool_impl<fake_segment_manager>
|
||||
{
|
||||
typedef boost::container::container_detail::
|
||||
private_node_pool_impl<fake_segment_manager> base_t;
|
||||
//Non-copyable
|
||||
private_node_pool(const private_node_pool &);
|
||||
private_node_pool &operator=(const private_node_pool &);
|
||||
|
||||
public:
|
||||
typedef typename base_t::multiallocation_chain multiallocation_chain;
|
||||
static const std::size_t nodes_per_block = NodesPerBlock;
|
||||
|
||||
//!Constructor from a segment manager. Never throws
|
||||
private_node_pool()
|
||||
: base_t(0, NodeSize, NodesPerBlock)
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
template< std::size_t NodeSize
|
||||
, std::size_t NodesPerBlock
|
||||
>
|
||||
class shared_node_pool
|
||||
: public private_node_pool<NodeSize, NodesPerBlock>
|
||||
{
|
||||
private:
|
||||
typedef private_node_pool<NodeSize, NodesPerBlock> private_node_allocator_t;
|
||||
|
||||
public:
|
||||
typedef typename private_node_allocator_t::free_nodes_t free_nodes_t;
|
||||
typedef typename private_node_allocator_t::multiallocation_chain multiallocation_chain;
|
||||
|
||||
//!Constructor from a segment manager. Never throws
|
||||
shared_node_pool()
|
||||
: private_node_allocator_t(){}
|
||||
|
||||
//!Destructor. Deallocates all allocated blocks. Never throws
|
||||
~shared_node_pool()
|
||||
{}
|
||||
|
||||
//!Allocates array of count elements. Can throw std::bad_alloc
|
||||
void *allocate_node()
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
return private_node_allocator_t::allocate_node();
|
||||
}
|
||||
|
||||
//!Deallocates an array pointed by ptr. Never throws
|
||||
void deallocate_node(void *ptr)
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
private_node_allocator_t::deallocate_node(ptr);
|
||||
}
|
||||
|
||||
//!Allocates a singly linked list of n nodes ending in null pointer.
|
||||
//!can throw std::bad_alloc
|
||||
void allocate_nodes(const std::size_t n, multiallocation_chain &chain)
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
return private_node_allocator_t::allocate_nodes(n, chain);
|
||||
}
|
||||
|
||||
void deallocate_nodes(multiallocation_chain &chain)
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
private_node_allocator_t::deallocate_nodes(chain);
|
||||
}
|
||||
|
||||
//!Deallocates all the free blocks of memory. Never throws
|
||||
void deallocate_free_blocks()
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
private_node_allocator_t::deallocate_free_blocks();
|
||||
}
|
||||
|
||||
//!Deallocates all blocks. Never throws
|
||||
void purge_blocks()
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
private_node_allocator_t::purge_blocks();
|
||||
}
|
||||
|
||||
std::size_t num_free_nodes()
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
return private_node_allocator_t::num_free_nodes();
|
||||
}
|
||||
|
||||
private:
|
||||
default_mutex mutex_;
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -15,9 +15,10 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/detail/utilities.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/intrusive/set.hpp>
|
||||
@@ -29,8 +30,6 @@
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <functional> //std::unary_function
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
@@ -251,8 +250,10 @@ class private_node_pool_impl
|
||||
};
|
||||
|
||||
struct is_between
|
||||
: std::unary_function<typename free_nodes_t::value_type, bool>
|
||||
{
|
||||
typedef typename free_nodes_t::value_type argument_type;
|
||||
typedef bool result_type;
|
||||
|
||||
is_between(const void *addr, std::size_t size)
|
||||
: beg_(static_cast<const char *>(addr)), end_(beg_+size)
|
||||
{}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -17,7 +17,7 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -8,14 +8,16 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
|
||||
#ifndef BOOST_CONTAINER_DETAIL_POOL_COMMON_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_POOL_COMMON_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/intrusive/slist.hpp>
|
||||
#include <new>
|
||||
|
||||
|
||||
94
include/boost/container/detail/pool_common_alloc.hpp
Normal file
94
include/boost/container/detail/pool_common_alloc.hpp
Normal file
@@ -0,0 +1,94 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_POOL_COMMON_ALLOC_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_POOL_COMMON_ALLOC_HPP
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
|
||||
#include <boost/intrusive/slist.hpp>
|
||||
#include <boost/container/detail/pool_common.hpp>
|
||||
#include <boost/container/detail/alloc_lib.h>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost{
|
||||
namespace container{
|
||||
namespace container_detail{
|
||||
|
||||
struct node_slist_helper
|
||||
: public boost::container::container_detail::node_slist<void*>
|
||||
{};
|
||||
|
||||
struct fake_segment_manager
|
||||
{
|
||||
typedef void * void_pointer;
|
||||
static const std::size_t PayloadPerAllocation = BOOST_CONTAINER_ALLOCATION_PAYLOAD;
|
||||
|
||||
typedef boost::container::container_detail::
|
||||
basic_multiallocation_chain<void*> multiallocation_chain;
|
||||
static void deallocate(void_pointer p)
|
||||
{ boost_cont_free(p); }
|
||||
|
||||
static void deallocate_many(multiallocation_chain &chain)
|
||||
{
|
||||
std::size_t size = chain.size();
|
||||
std::pair<void*, void*> ptrs = chain.extract_data();
|
||||
boost_cont_memchain dlchain;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&dlchain, ptrs.first, ptrs.second, size);
|
||||
boost_cont_multidealloc(&dlchain);
|
||||
}
|
||||
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::size_t size_type;
|
||||
|
||||
static void *allocate_aligned(std::size_t nbytes, std::size_t alignment)
|
||||
{
|
||||
void *ret = boost_cont_memalign(nbytes, alignment);
|
||||
if(!ret)
|
||||
boost::container::throw_bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *allocate(std::size_t nbytes)
|
||||
{
|
||||
void *ret = boost_cont_malloc(nbytes);
|
||||
if(!ret)
|
||||
boost::container::throw_bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace boost{
|
||||
} //namespace container{
|
||||
} //namespace container_detail{
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template<class T>
|
||||
struct is_stateless_segment_manager;
|
||||
|
||||
template<>
|
||||
struct is_stateless_segment_manager
|
||||
<boost::container::container_detail::fake_segment_manager>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_POOL_COMMON_ALLOC_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-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)
|
||||
//
|
||||
|
||||
113
include/boost/container/detail/singleton.hpp
Normal file
113
include/boost/container/detail/singleton.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright (C) 2000 Stephen Cleary
|
||||
// Copyright (C) 2008 Ion Gaztanaga
|
||||
//
|
||||
// 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 for updates, documentation, and revision history.
|
||||
//
|
||||
// This file is a modified file from Boost.Pool
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
//
|
||||
// The following helper classes are placeholders for a generic "singleton"
|
||||
// class. The classes below support usage of singletons, including use in
|
||||
// program startup/shutdown code, AS LONG AS there is only one thread
|
||||
// running before main() begins, and only one thread running after main()
|
||||
// exits.
|
||||
//
|
||||
// This class is also limited in that it can only provide singleton usage for
|
||||
// classes with default constructors.
|
||||
//
|
||||
|
||||
// The design of this class is somewhat twisted, but can be followed by the
|
||||
// calling inheritance. Let us assume that there is some user code that
|
||||
// calls "singleton_default<T>::instance()". The following (convoluted)
|
||||
// sequence ensures that the same function will be called before main():
|
||||
// instance() contains a call to create_object.do_nothing()
|
||||
// Thus, object_creator is implicitly instantiated, and create_object
|
||||
// must exist.
|
||||
// Since create_object is a static member, its constructor must be
|
||||
// called before main().
|
||||
// The constructor contains a call to instance(), thus ensuring that
|
||||
// instance() will be called before main().
|
||||
// The first time instance() is called (i.e., before main()) is the
|
||||
// latest point in program execution where the object of type T
|
||||
// can be created.
|
||||
// Thus, any call to instance() will auto-magically result in a call to
|
||||
// instance() before main(), unless already present.
|
||||
// Furthermore, since the instance() function contains the object, instead
|
||||
// of the singleton_default class containing a static instance of the
|
||||
// object, that object is guaranteed to be constructed (at the latest) in
|
||||
// the first call to instance(). This permits calls to instance() from
|
||||
// static code, even if that code is called before the file-scope objects
|
||||
// in this file have been initialized.
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
// T must be: no-throw default constructible and no-throw destructible
|
||||
template <typename T>
|
||||
struct singleton_default
|
||||
{
|
||||
private:
|
||||
struct object_creator
|
||||
{
|
||||
// This constructor does nothing more than ensure that instance()
|
||||
// is called before main() begins, thus creating the static
|
||||
// T object before multithreading race issues can come up.
|
||||
object_creator() { singleton_default<T>::instance(); }
|
||||
inline void do_nothing() const { }
|
||||
};
|
||||
static object_creator create_object;
|
||||
|
||||
singleton_default();
|
||||
|
||||
public:
|
||||
typedef T object_type;
|
||||
|
||||
// If, at any point (in user code), singleton_default<T>::instance()
|
||||
// is called, then the following function is instantiated.
|
||||
static object_type & instance()
|
||||
{
|
||||
// This is the object that we return a reference to.
|
||||
// It is guaranteed to be created before main() begins because of
|
||||
// the next line.
|
||||
static object_type obj;
|
||||
|
||||
// The following line does nothing else than force the instantiation
|
||||
// of singleton_default<T>::create_object, whose constructor is
|
||||
// called before main() begins.
|
||||
create_object.do_nothing();
|
||||
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
typename singleton_default<T>::object_creator
|
||||
singleton_default<T>::create_object;
|
||||
|
||||
} // namespace container_detail
|
||||
} // namespace container
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
@@ -18,8 +18,9 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <iterator>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -11,15 +11,10 @@
|
||||
#ifndef BOOST_CONTAINER_TREE_HPP
|
||||
#define BOOST_CONTAINER_TREE_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/intrusive/rbtree.hpp>
|
||||
#include <boost/container/detail/utilities.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/algorithms.hpp>
|
||||
@@ -28,7 +23,19 @@
|
||||
#include <boost/container/detail/pair.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/options.hpp>
|
||||
|
||||
//
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/intrusive/rbtree.hpp>
|
||||
#include <boost/intrusive/avltree.hpp>
|
||||
#include <boost/intrusive/splaytree.hpp>
|
||||
#include <boost/intrusive/sgtree.hpp>
|
||||
//
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
//
|
||||
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
#include <boost/container/detail/preprocessor.hpp>
|
||||
#endif
|
||||
@@ -85,47 +92,78 @@ struct tree_value_compare
|
||||
{ return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
|
||||
};
|
||||
|
||||
template<class VoidPointer>
|
||||
struct rbtree_hook
|
||||
template<class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
|
||||
struct intrusive_tree_hook;
|
||||
|
||||
template<class VoidPointer, bool OptimizeSize>
|
||||
struct intrusive_tree_hook<VoidPointer, boost::container::red_black_tree, OptimizeSize>
|
||||
{
|
||||
typedef typename container_detail::bi::make_set_base_hook
|
||||
< container_detail::bi::void_pointer<VoidPointer>
|
||||
, container_detail::bi::link_mode<container_detail::bi::normal_link>
|
||||
, container_detail::bi::optimize_size<true>
|
||||
, container_detail::bi::optimize_size<OptimizeSize>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class VoidPointer, bool OptimizeSize>
|
||||
struct intrusive_tree_hook<VoidPointer, boost::container::avl_tree, OptimizeSize>
|
||||
{
|
||||
typedef typename container_detail::bi::make_avl_set_base_hook
|
||||
< container_detail::bi::void_pointer<VoidPointer>
|
||||
, container_detail::bi::link_mode<container_detail::bi::normal_link>
|
||||
, container_detail::bi::optimize_size<OptimizeSize>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class VoidPointer, bool OptimizeSize>
|
||||
struct intrusive_tree_hook<VoidPointer, boost::container::scapegoat_tree, OptimizeSize>
|
||||
{
|
||||
typedef typename container_detail::bi::make_bs_set_base_hook
|
||||
< container_detail::bi::void_pointer<VoidPointer>
|
||||
, container_detail::bi::link_mode<container_detail::bi::normal_link>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class VoidPointer, bool OptimizeSize>
|
||||
struct intrusive_tree_hook<VoidPointer, boost::container::splay_tree, OptimizeSize>
|
||||
{
|
||||
typedef typename container_detail::bi::make_bs_set_base_hook
|
||||
< container_detail::bi::void_pointer<VoidPointer>
|
||||
, container_detail::bi::link_mode<container_detail::bi::normal_link>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
//This trait is used to type-pun std::pair because in C++03
|
||||
//compilers std::pair is useless for C++11 features
|
||||
template<class T>
|
||||
struct rbtree_internal_data_type
|
||||
struct tree_internal_data_type
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T1, class T2>
|
||||
struct rbtree_internal_data_type< std::pair<T1, T2> >
|
||||
struct tree_internal_data_type< std::pair<T1, T2> >
|
||||
{
|
||||
typedef pair<T1, T2> type;
|
||||
};
|
||||
|
||||
|
||||
//The node to be store in the tree
|
||||
template <class T, class VoidPointer>
|
||||
struct rbtree_node
|
||||
: public rbtree_hook<VoidPointer>::type
|
||||
template <class T, class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
|
||||
struct tree_node
|
||||
: public intrusive_tree_hook<VoidPointer, tree_type_value, OptimizeSize>::type
|
||||
{
|
||||
private:
|
||||
//BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
|
||||
rbtree_node();
|
||||
//BOOST_COPYABLE_AND_MOVABLE(tree_node)
|
||||
tree_node();
|
||||
|
||||
public:
|
||||
typedef typename rbtree_hook<VoidPointer>::type hook_type;
|
||||
|
||||
typedef typename intrusive_tree_hook
|
||||
<VoidPointer, tree_type_value, OptimizeSize>::type hook_type;
|
||||
typedef T value_type;
|
||||
typedef typename rbtree_internal_data_type<T>::type internal_type;
|
||||
typedef typename tree_internal_data_type<T>::type internal_type;
|
||||
|
||||
typedef rbtree_node<T, VoidPointer> node_type;
|
||||
typedef tree_node< T, VoidPointer
|
||||
, tree_type_value, OptimizeSize> node_type;
|
||||
|
||||
T &get_data()
|
||||
{
|
||||
@@ -210,52 +248,224 @@ class push_back_functor
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
template<class A, class ValueCompare>
|
||||
struct intrusive_rbtree_type
|
||||
template< class NodeType, class NodeCompareType
|
||||
, class SizeType, class HookType
|
||||
, boost::container::tree_type_enum tree_type_value>
|
||||
struct intrusive_tree_dispatch;
|
||||
|
||||
template<class NodeType, class NodeCompareType, class SizeType, class HookType>
|
||||
struct intrusive_tree_dispatch
|
||||
<NodeType, NodeCompareType, SizeType, HookType, boost::container::red_black_tree>
|
||||
{
|
||||
typedef typename container_detail::bi::make_rbtree
|
||||
<NodeType
|
||||
,container_detail::bi::compare<NodeCompareType>
|
||||
,container_detail::bi::base_hook<HookType>
|
||||
,container_detail::bi::constant_time_size<true>
|
||||
,container_detail::bi::size_type<SizeType>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class NodeType, class NodeCompareType, class SizeType, class HookType>
|
||||
struct intrusive_tree_dispatch
|
||||
<NodeType, NodeCompareType, SizeType, HookType, boost::container::avl_tree>
|
||||
{
|
||||
typedef typename container_detail::bi::make_avltree
|
||||
<NodeType
|
||||
,container_detail::bi::compare<NodeCompareType>
|
||||
,container_detail::bi::base_hook<HookType>
|
||||
,container_detail::bi::constant_time_size<true>
|
||||
,container_detail::bi::size_type<SizeType>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class NodeType, class NodeCompareType, class SizeType, class HookType>
|
||||
struct intrusive_tree_dispatch
|
||||
<NodeType, NodeCompareType, SizeType, HookType, boost::container::scapegoat_tree>
|
||||
{
|
||||
typedef typename container_detail::bi::make_sgtree
|
||||
<NodeType
|
||||
,container_detail::bi::compare<NodeCompareType>
|
||||
,container_detail::bi::base_hook<HookType>
|
||||
,container_detail::bi::floating_point<true>
|
||||
,container_detail::bi::size_type<SizeType>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class NodeType, class NodeCompareType, class SizeType, class HookType>
|
||||
struct intrusive_tree_dispatch
|
||||
<NodeType, NodeCompareType, SizeType, HookType, boost::container::splay_tree>
|
||||
{
|
||||
typedef typename container_detail::bi::make_splaytree
|
||||
<NodeType
|
||||
,container_detail::bi::compare<NodeCompareType>
|
||||
,container_detail::bi::base_hook<HookType>
|
||||
,container_detail::bi::constant_time_size<true>
|
||||
,container_detail::bi::size_type<SizeType>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class A, class ValueCompare, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
|
||||
struct intrusive_tree_type
|
||||
{
|
||||
private:
|
||||
typedef typename boost::container::
|
||||
allocator_traits<A>::value_type value_type;
|
||||
typedef typename boost::container::
|
||||
allocator_traits<A>::void_pointer void_pointer;
|
||||
typedef typename boost::container::
|
||||
allocator_traits<A>::size_type size_type;
|
||||
typedef typename container_detail::rbtree_node
|
||||
<value_type, void_pointer> node_type;
|
||||
typedef typename container_detail::tree_node
|
||||
< value_type, void_pointer
|
||||
, tree_type_value, OptimizeSize> node_type;
|
||||
typedef node_compare<ValueCompare, node_type> node_compare_type;
|
||||
typedef typename container_detail::bi::make_rbtree
|
||||
<node_type
|
||||
,container_detail::bi::compare<node_compare_type>
|
||||
,container_detail::bi::base_hook<typename rbtree_hook<void_pointer>::type>
|
||||
,container_detail::bi::constant_time_size<true>
|
||||
,container_detail::bi::size_type<size_type>
|
||||
>::type container_type;
|
||||
typedef container_type type ;
|
||||
//Deducing the hook type from node_type (e.g. node_type::hook_type) would
|
||||
//provoke an early instantiation of node_type that could ruin recursive
|
||||
//tree definitions, so retype the complete type to avoid any problem.
|
||||
typedef typename intrusive_tree_hook
|
||||
<void_pointer, tree_type_value
|
||||
, OptimizeSize>::type hook_type;
|
||||
public:
|
||||
typedef typename intrusive_tree_dispatch
|
||||
< node_type, node_compare_type
|
||||
, size_type, hook_type
|
||||
, tree_type_value>::type type;
|
||||
};
|
||||
|
||||
//Trait to detect manually rebalanceable tree types
|
||||
template<boost::container::tree_type_enum tree_type_value>
|
||||
struct is_manually_balanceable
|
||||
{ static const bool value = true; };
|
||||
|
||||
template<> struct is_manually_balanceable<red_black_tree>
|
||||
{ static const bool value = false; };
|
||||
|
||||
template<> struct is_manually_balanceable<avl_tree>
|
||||
{ static const bool value = false; };
|
||||
|
||||
//Proxy traits to implement different operations depending on the
|
||||
//is_manually_balanceable<>::value
|
||||
template< boost::container::tree_type_enum tree_type_value
|
||||
, bool IsManuallyRebalanceable = is_manually_balanceable<tree_type_value>::value>
|
||||
struct intrusive_tree_proxy
|
||||
{
|
||||
template<class Icont>
|
||||
static void rebalance(Icont &) {}
|
||||
};
|
||||
|
||||
template<boost::container::tree_type_enum tree_type_value>
|
||||
struct intrusive_tree_proxy<tree_type_value, true>
|
||||
{
|
||||
template<class Icont>
|
||||
static void rebalance(Icont &c)
|
||||
{ c.rebalance(); }
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
//This functor will be used with Intrusive clone functions to obtain
|
||||
//already allocated nodes from a intrusive container instead of
|
||||
//allocating new ones. When the intrusive container runs out of nodes
|
||||
//the node holder is used instead.
|
||||
template<class AllocHolder, bool DoMove>
|
||||
class RecyclingCloner
|
||||
{
|
||||
typedef typename AllocHolder::intrusive_container intrusive_container;
|
||||
typedef typename AllocHolder::Node node_type;
|
||||
typedef typename AllocHolder::NodePtr node_ptr_type;
|
||||
|
||||
public:
|
||||
RecyclingCloner(AllocHolder &holder, intrusive_container &itree)
|
||||
: m_holder(holder), m_icont(itree)
|
||||
{}
|
||||
|
||||
static void do_assign(node_ptr_type &p, const node_type &other, bool_<true>)
|
||||
{ p->do_assign(other.m_data); }
|
||||
|
||||
static void do_assign(node_ptr_type &p, const node_type &other, bool_<false>)
|
||||
{ p->do_move_assign(const_cast<node_type &>(other).m_data); }
|
||||
|
||||
node_ptr_type operator()(const node_type &other) const
|
||||
{
|
||||
if(node_ptr_type p = m_icont.unlink_leftmost_without_rebalance()){
|
||||
//First recycle a node (this can't throw)
|
||||
BOOST_TRY{
|
||||
//This can throw
|
||||
this->do_assign(p, other, bool_<DoMove>());
|
||||
return p;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//If there is an exception destroy the whole source
|
||||
m_holder.destroy_node(p);
|
||||
while((p = m_icont.unlink_leftmost_without_rebalance())){
|
||||
m_holder.destroy_node(p);
|
||||
}
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
else{
|
||||
return m_holder.create_node(other.m_data);
|
||||
}
|
||||
}
|
||||
|
||||
AllocHolder &m_holder;
|
||||
intrusive_container &m_icont;
|
||||
};
|
||||
|
||||
template<class KeyValueCompare, class Node>
|
||||
//where KeyValueCompare is tree_value_compare<Key, Value, KeyCompare, KeyOfValue>
|
||||
struct key_node_compare
|
||||
: private KeyValueCompare
|
||||
{
|
||||
explicit key_node_compare(const KeyValueCompare &comp)
|
||||
: KeyValueCompare(comp)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
struct is_node
|
||||
{
|
||||
static const bool value = is_same<T, Node>::value;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
typename enable_if_c<is_node<T>::value, const typename KeyValueCompare::value_type &>::type
|
||||
key_forward(const T &node) const
|
||||
{ return node.get_data(); }
|
||||
|
||||
template<class T>
|
||||
typename enable_if_c<!is_node<T>::value, const T &>::type
|
||||
key_forward(const T &key) const
|
||||
{ return key; }
|
||||
|
||||
template<class KeyType, class KeyType2>
|
||||
bool operator()(const KeyType &key1, const KeyType2 &key2) const
|
||||
{ return KeyValueCompare::operator()(this->key_forward(key1), this->key_forward(key2)); }
|
||||
};
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
class rbtree
|
||||
class KeyCompare, class A,
|
||||
class Options = tree_assoc_defaults>
|
||||
class tree
|
||||
: protected container_detail::node_alloc_holder
|
||||
< A
|
||||
, typename container_detail::intrusive_rbtree_type
|
||||
<A, tree_value_compare<Key, Value, KeyCompare, KeyOfValue>
|
||||
>::type
|
||||
, tree_value_compare<Key, Value, KeyCompare, KeyOfValue>
|
||||
, typename container_detail::intrusive_tree_type
|
||||
< A, tree_value_compare<Key, Value, KeyCompare, KeyOfValue> //ValComp
|
||||
, Options::tree_type, Options::optimize_size>::type
|
||||
>
|
||||
{
|
||||
typedef tree_value_compare
|
||||
<Key, Value, KeyCompare, KeyOfValue> ValComp;
|
||||
typedef typename container_detail::intrusive_rbtree_type
|
||||
< A, ValComp>::type Icont;
|
||||
typedef typename container_detail::intrusive_tree_type
|
||||
< A, ValComp, Options::tree_type
|
||||
, Options::optimize_size>::type Icont;
|
||||
typedef container_detail::node_alloc_holder
|
||||
<A, Icont, ValComp> AllocHolder;
|
||||
<A, Icont> AllocHolder;
|
||||
typedef typename AllocHolder::NodePtr NodePtr;
|
||||
typedef rbtree < Key, Value, KeyOfValue
|
||||
, KeyCompare, A> ThisType;
|
||||
typedef tree < Key, Value, KeyOfValue
|
||||
, KeyCompare, A, Options> ThisType;
|
||||
typedef typename AllocHolder::NodeAlloc NodeAlloc;
|
||||
typedef typename AllocHolder::ValAlloc ValAlloc;
|
||||
typedef typename AllocHolder::Node Node;
|
||||
@@ -265,84 +475,9 @@ class rbtree
|
||||
typedef typename AllocHolder::allocator_v1 allocator_v1;
|
||||
typedef typename AllocHolder::allocator_v2 allocator_v2;
|
||||
typedef typename AllocHolder::alloc_version alloc_version;
|
||||
typedef intrusive_tree_proxy<Options::tree_type> intrusive_tree_proxy_t;
|
||||
|
||||
class RecyclingCloner;
|
||||
friend class RecyclingCloner;
|
||||
|
||||
class RecyclingCloner
|
||||
{
|
||||
public:
|
||||
RecyclingCloner(AllocHolder &holder, Icont &irbtree)
|
||||
: m_holder(holder), m_icont(irbtree)
|
||||
{}
|
||||
|
||||
NodePtr operator()(const Node &other) const
|
||||
{
|
||||
if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
|
||||
//First recycle a node (this can't throw)
|
||||
BOOST_TRY{
|
||||
//This can throw
|
||||
p->do_assign(other.m_data);
|
||||
return p;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//If there is an exception destroy the whole source
|
||||
m_holder.destroy_node(p);
|
||||
while((p = m_icont.unlink_leftmost_without_rebalance())){
|
||||
m_holder.destroy_node(p);
|
||||
}
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
else{
|
||||
return m_holder.create_node(other.m_data);
|
||||
}
|
||||
}
|
||||
|
||||
AllocHolder &m_holder;
|
||||
Icont &m_icont;
|
||||
};
|
||||
|
||||
class RecyclingMoveCloner;
|
||||
friend class RecyclingMoveCloner;
|
||||
|
||||
class RecyclingMoveCloner
|
||||
{
|
||||
public:
|
||||
RecyclingMoveCloner(AllocHolder &holder, Icont &irbtree)
|
||||
: m_holder(holder), m_icont(irbtree)
|
||||
{}
|
||||
|
||||
NodePtr operator()(const Node &other) const
|
||||
{
|
||||
if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
|
||||
//First recycle a node (this can't throw)
|
||||
BOOST_TRY{
|
||||
//This can throw
|
||||
p->do_move_assign(const_cast<Node &>(other).m_data);
|
||||
return p;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//If there is an exception destroy the whole source
|
||||
m_holder.destroy_node(p);
|
||||
while((p = m_icont.unlink_leftmost_without_rebalance())){
|
||||
m_holder.destroy_node(p);
|
||||
}
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
else{
|
||||
return m_holder.create_node(other.m_data);
|
||||
}
|
||||
}
|
||||
|
||||
AllocHolder &m_holder;
|
||||
Icont &m_icont;
|
||||
};
|
||||
|
||||
BOOST_COPYABLE_AND_MOVABLE(rbtree)
|
||||
BOOST_COPYABLE_AND_MOVABLE(tree)
|
||||
|
||||
public:
|
||||
|
||||
@@ -363,45 +498,16 @@ class rbtree
|
||||
allocator_traits<A>::size_type size_type;
|
||||
typedef typename boost::container::
|
||||
allocator_traits<A>::difference_type difference_type;
|
||||
typedef difference_type rbtree_difference_type;
|
||||
typedef pointer rbtree_pointer;
|
||||
typedef const_pointer rbtree_const_pointer;
|
||||
typedef reference rbtree_reference;
|
||||
typedef const_reference rbtree_const_reference;
|
||||
typedef difference_type tree_difference_type;
|
||||
typedef pointer tree_pointer;
|
||||
typedef const_pointer tree_const_pointer;
|
||||
typedef reference tree_reference;
|
||||
typedef const_reference tree_const_reference;
|
||||
typedef NodeAlloc stored_allocator_type;
|
||||
|
||||
private:
|
||||
|
||||
template<class KeyValueCompare>
|
||||
struct key_node_compare
|
||||
: private KeyValueCompare
|
||||
{
|
||||
key_node_compare(const KeyValueCompare &comp)
|
||||
: KeyValueCompare(comp)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
struct is_node
|
||||
{
|
||||
static const bool value = is_same<T, Node>::value;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
typename enable_if_c<is_node<T>::value, const value_type &>::type
|
||||
key_forward(const T &node) const
|
||||
{ return node.get_data(); }
|
||||
|
||||
template<class T>
|
||||
typename enable_if_c<!is_node<T>::value, const T &>::type
|
||||
key_forward(const T &key) const
|
||||
{ return key; }
|
||||
|
||||
template<class KeyType, class KeyType2>
|
||||
bool operator()(const KeyType &key1, const KeyType2 &key2) const
|
||||
{ return KeyValueCompare::operator()(this->key_forward(key1), this->key_forward(key2)); }
|
||||
};
|
||||
|
||||
typedef key_node_compare<value_compare> KeyNodeCompare;
|
||||
typedef key_node_compare<value_compare, Node> KeyNodeCompare;
|
||||
|
||||
public:
|
||||
typedef container_detail::iterator<iiterator, false> iterator;
|
||||
@@ -409,20 +515,20 @@ class rbtree
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
rbtree()
|
||||
tree()
|
||||
: AllocHolder(ValComp(key_compare()))
|
||||
{}
|
||||
|
||||
explicit rbtree(const key_compare& comp, const allocator_type& a = allocator_type())
|
||||
explicit tree(const key_compare& comp, const allocator_type& a = allocator_type())
|
||||
: AllocHolder(a, ValComp(comp))
|
||||
{}
|
||||
|
||||
explicit rbtree(const allocator_type& a)
|
||||
explicit tree(const allocator_type& a)
|
||||
: AllocHolder(a)
|
||||
{}
|
||||
|
||||
template <class InputIterator>
|
||||
rbtree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
|
||||
tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
|
||||
const allocator_type& a
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
@@ -450,7 +556,7 @@ class rbtree
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
rbtree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
|
||||
tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
|
||||
const allocator_type& a
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
@@ -479,7 +585,7 @@ class rbtree
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
rbtree( ordered_range_t, InputIterator first, InputIterator last
|
||||
tree( ordered_range_t, InputIterator first, InputIterator last
|
||||
, const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
@@ -496,7 +602,7 @@ class rbtree
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
rbtree( ordered_range_t, InputIterator first, InputIterator last
|
||||
tree( ordered_range_t, InputIterator first, InputIterator last
|
||||
, const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
@@ -513,25 +619,25 @@ class rbtree
|
||||
, container_detail::push_back_functor<Node, Icont>(this->icont()));
|
||||
}
|
||||
|
||||
rbtree(const rbtree& x)
|
||||
tree(const tree& x)
|
||||
: AllocHolder(x, x.value_comp())
|
||||
{
|
||||
this->icont().clone_from
|
||||
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
|
||||
}
|
||||
|
||||
rbtree(BOOST_RV_REF(rbtree) x)
|
||||
tree(BOOST_RV_REF(tree) x)
|
||||
: AllocHolder(::boost::move(static_cast<AllocHolder&>(x)), x.value_comp())
|
||||
{}
|
||||
|
||||
rbtree(const rbtree& x, const allocator_type &a)
|
||||
tree(const tree& x, const allocator_type &a)
|
||||
: AllocHolder(a, x.value_comp())
|
||||
{
|
||||
this->icont().clone_from
|
||||
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
|
||||
}
|
||||
|
||||
rbtree(BOOST_RV_REF(rbtree) x, const allocator_type &a)
|
||||
tree(BOOST_RV_REF(tree) x, const allocator_type &a)
|
||||
: AllocHolder(a, x.value_comp())
|
||||
{
|
||||
if(this->node_alloc() == x.node_alloc()){
|
||||
@@ -543,10 +649,10 @@ class rbtree
|
||||
}
|
||||
}
|
||||
|
||||
~rbtree()
|
||||
~tree()
|
||||
{} //AllocHolder clears the tree
|
||||
|
||||
rbtree& operator=(BOOST_COPY_ASSIGN_REF(rbtree) x)
|
||||
tree& operator=(BOOST_COPY_ASSIGN_REF(tree) x)
|
||||
{
|
||||
if (&x != this){
|
||||
NodeAlloc &this_alloc = this->get_stored_allocator();
|
||||
@@ -565,7 +671,7 @@ class rbtree
|
||||
//Now recreate the source tree reusing nodes stored by other_tree
|
||||
this->icont().clone_from
|
||||
(x.icont()
|
||||
, RecyclingCloner(*this, other_tree)
|
||||
, RecyclingCloner<AllocHolder, false>(*this, other_tree)
|
||||
, Destroyer(this->node_alloc()));
|
||||
|
||||
//If there are remaining nodes, destroy them
|
||||
@@ -577,7 +683,7 @@ class rbtree
|
||||
return *this;
|
||||
}
|
||||
|
||||
rbtree& operator=(BOOST_RV_REF(rbtree) x)
|
||||
tree& operator=(BOOST_RV_REF(tree) x)
|
||||
{
|
||||
if (&x != this){
|
||||
NodeAlloc &this_alloc = this->get_stored_allocator();
|
||||
@@ -600,7 +706,7 @@ class rbtree
|
||||
//Now recreate the source tree reusing nodes stored by other_tree
|
||||
this->icont().clone_from
|
||||
(x.icont()
|
||||
, RecyclingMoveCloner(*this, other_tree)
|
||||
, RecyclingCloner<AllocHolder, true>(*this, other_tree)
|
||||
, Destroyer(this->node_alloc()));
|
||||
|
||||
//If there are remaining nodes, destroy them
|
||||
@@ -965,7 +1071,8 @@ class rbtree
|
||||
void clear()
|
||||
{ AllocHolder::clear(alloc_version()); }
|
||||
|
||||
// set operations:
|
||||
// search operations. Const and non-const overloads even if no iterator is returned
|
||||
// so splay implementations can to their rebalancing when searching in non-const versions
|
||||
iterator find(const key_type& k)
|
||||
{ return iterator(this->icont().find(k, KeyNodeCompare(value_comp()))); }
|
||||
|
||||
@@ -1001,70 +1108,47 @@ class rbtree
|
||||
return std::pair<const_iterator,const_iterator>
|
||||
(const_iterator(ret.first), const_iterator(ret.second));
|
||||
}
|
||||
|
||||
std::pair<iterator,iterator> lower_bound_range(const key_type& k)
|
||||
{
|
||||
std::pair<iiterator, iiterator> ret =
|
||||
this->icont().lower_bound_range(k, KeyNodeCompare(value_comp()));
|
||||
return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator> lower_bound_range(const key_type& k) const
|
||||
{
|
||||
std::pair<iiterator, iiterator> ret =
|
||||
this->non_const_icont().lower_bound_range(k, KeyNodeCompare(value_comp()));
|
||||
return std::pair<const_iterator,const_iterator>
|
||||
(const_iterator(ret.first), const_iterator(ret.second));
|
||||
}
|
||||
|
||||
void rebalance()
|
||||
{ intrusive_tree_proxy_t::rebalance(this->icont()); }
|
||||
|
||||
friend bool operator==(const tree& x, const tree& y)
|
||||
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
friend bool operator<(const tree& x, const tree& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
friend bool operator!=(const tree& x, const tree& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
friend bool operator>(const tree& x, const tree& y)
|
||||
{ return y < x; }
|
||||
|
||||
friend bool operator<=(const tree& x, const tree& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
friend bool operator>=(const tree& x, const tree& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
friend void swap(tree& x, tree& y)
|
||||
{ x.swap(y); }
|
||||
};
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
inline bool
|
||||
operator==(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
|
||||
{
|
||||
return x.size() == y.size() &&
|
||||
std::equal(x.begin(), x.end(), y.begin());
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
inline bool
|
||||
operator<(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
|
||||
{
|
||||
return std::lexicographical_compare(x.begin(), x.end(),
|
||||
y.begin(), y.end());
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
inline bool
|
||||
operator!=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
inline bool
|
||||
operator>(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
|
||||
return y < x;
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
inline bool
|
||||
operator<=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
|
||||
return !(y < x);
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
inline bool
|
||||
operator>=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
|
||||
return !(x < y);
|
||||
}
|
||||
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
inline void
|
||||
swap(rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
|
||||
{
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
/*
|
||||
@@ -1073,7 +1157,7 @@ swap(rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
template <class K, class V, class KOV,
|
||||
class C, class A>
|
||||
struct has_trivial_destructor_after_move
|
||||
<boost::container::container_detail::rbtree<K, V, KOV, C, A> >
|
||||
<boost::container::container_detail::tree<K, V, KOV, C, A> >
|
||||
{
|
||||
static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// (C) Copyright John Maddock 2000.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -19,7 +19,8 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/move/utility.hpp>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -11,8 +11,9 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include "workaround.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring> //for ::memcpy
|
||||
#include <boost/type_traits/is_fundamental.hpp>
|
||||
@@ -24,6 +25,7 @@
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/move/iterator.hpp>
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
@@ -109,25 +111,47 @@ template<class T>
|
||||
const T &min_value(const T &a, const T &b)
|
||||
{ return a < b ? a : b; }
|
||||
|
||||
template <class SizeType>
|
||||
SizeType
|
||||
get_next_capacity(const SizeType max_size
|
||||
,const SizeType capacity
|
||||
,const SizeType n)
|
||||
enum NextCapacityOption { NextCapacityDouble, NextCapacity60Percent };
|
||||
|
||||
template<class SizeType, NextCapacityOption Option>
|
||||
struct next_capacity_calculator;
|
||||
|
||||
template<class SizeType>
|
||||
struct next_capacity_calculator<SizeType, NextCapacityDouble>
|
||||
{
|
||||
// if (n > max_size - capacity)
|
||||
// throw std::length_error("get_next_capacity");
|
||||
static SizeType get(const SizeType max_size
|
||||
,const SizeType capacity
|
||||
,const SizeType n)
|
||||
{
|
||||
const SizeType remaining = max_size - capacity;
|
||||
if ( remaining < n )
|
||||
boost::container::throw_length_error("get_next_capacity, allocator's max_size reached");
|
||||
const SizeType additional = max_value(n, capacity);
|
||||
return ( remaining < additional ) ? max_size : ( capacity + additional );
|
||||
}
|
||||
};
|
||||
|
||||
const SizeType m3 = max_size/3;
|
||||
|
||||
if (capacity < m3)
|
||||
return capacity + max_value(3*(capacity+1)/5, n);
|
||||
template<class SizeType>
|
||||
struct next_capacity_calculator<SizeType, NextCapacity60Percent>
|
||||
{
|
||||
static SizeType get(const SizeType max_size
|
||||
,const SizeType capacity
|
||||
,const SizeType n)
|
||||
{
|
||||
const SizeType remaining = max_size - capacity;
|
||||
if ( remaining < n )
|
||||
boost::container::throw_length_error("get_next_capacity, allocator's max_size reached");
|
||||
const SizeType m3 = max_size/3;
|
||||
|
||||
if (capacity < m3*2)
|
||||
return capacity + max_value((capacity+1)/2, n);
|
||||
if (capacity < m3)
|
||||
return capacity + max_value(3*(capacity+1)/5, n);
|
||||
|
||||
return max_size;
|
||||
}
|
||||
if (capacity < m3*2)
|
||||
return capacity + max_value((capacity+1)/2, n);
|
||||
return max_size;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline T* to_raw_pointer(T* p)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -17,7 +17,7 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -15,8 +15,9 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <cstddef> //std::size_t
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -16,7 +16,8 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
@@ -87,6 +88,6 @@ struct version
|
||||
} //namespace container {
|
||||
} //namespace boost{
|
||||
|
||||
#include "config_end.hpp"
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -34,18 +34,7 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
/// @cond
|
||||
// Forward declarations of operators == and <, needed for friend declarations.
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
class flat_map;
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator==(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y);
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator<(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y);
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace container_detail{
|
||||
|
||||
@@ -62,8 +51,7 @@ static D force_copy(S s)
|
||||
|
||||
} //namespace container_detail{
|
||||
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! A flat_map is a kind of associative container that supports unique keys (contains at
|
||||
//! most one of each key value) and provides for fast retrieval of values of another
|
||||
@@ -88,6 +76,12 @@ static D force_copy(S s)
|
||||
//! pointing to elements that come after (their keys are bigger) the erased element.
|
||||
//!
|
||||
//! This container provides random-access iterators.
|
||||
//!
|
||||
//! \tparam Key is the key_type of the map
|
||||
//! \tparam Value is the <code>mapped_type</code>
|
||||
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
||||
//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
|
||||
//! (e.g. <i>allocator< std::pair<Key, T> > </i>).
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator< std::pair< Key, T> > >
|
||||
#else
|
||||
@@ -95,7 +89,7 @@ template <class Key, class T, class Compare, class Allocator>
|
||||
#endif
|
||||
class flat_map
|
||||
{
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_map)
|
||||
//This is the tree that we should store if pair was movable
|
||||
@@ -129,7 +123,7 @@ class flat_map
|
||||
<typename allocator_traits<Allocator>::pointer>::reverse_iterator reverse_iterator_impl;
|
||||
typedef typename container_detail::get_flat_tree_iterators
|
||||
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
|
||||
@@ -168,7 +162,11 @@ class flat_map
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
flat_map()
|
||||
: m_flat_tree() {}
|
||||
: m_flat_tree()
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified
|
||||
//! comparison object and allocator.
|
||||
@@ -176,14 +174,20 @@ class flat_map
|
||||
//! <b>Complexity</b>: Constant.
|
||||
explicit flat_map(const Compare& comp, const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
explicit flat_map(const allocator_type& a)
|
||||
: m_flat_tree(container_detail::force<impl_allocator_type>(a))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
|
||||
//! allocator, and inserts elements from the range [first ,last ).
|
||||
@@ -194,7 +198,10 @@ class flat_map
|
||||
flat_map(InputIterator first, InputIterator last, const Compare& comp = Compare(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(true, first, last, comp, container_detail::force<impl_allocator_type>(a))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
|
||||
//! allocator, and inserts elements from the ordered unique range [first ,last). This function
|
||||
@@ -210,13 +217,20 @@ class flat_map
|
||||
flat_map( ordered_unique_range_t, InputIterator first, InputIterator last
|
||||
, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(ordered_range, first, last, comp, a)
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a flat_map.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_map(const flat_map& x)
|
||||
: m_flat_tree(x.m_flat_tree) {}
|
||||
: m_flat_tree(x.m_flat_tree)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a flat_map.
|
||||
//! Constructs *this using x's resources.
|
||||
@@ -226,14 +240,20 @@ class flat_map
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
flat_map(BOOST_RV_REF(flat_map) x)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a flat_map using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_map(const flat_map& x, const allocator_type &a)
|
||||
: m_flat_tree(x.m_flat_tree, a)
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a flat_map using the specified allocator.
|
||||
//! Constructs *this using x's resources.
|
||||
@@ -241,7 +261,10 @@ class flat_map
|
||||
//! <b>Complexity</b>: Constant if x.get_allocator() == a, linear otherwise.
|
||||
flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree), a)
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
@@ -834,22 +857,57 @@ class flat_map
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic
|
||||
std::pair<iterator,iterator> equal_range(const key_type& x)
|
||||
{ return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
|
||||
{ return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.lower_bound_range(x)); }
|
||||
|
||||
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic
|
||||
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
|
||||
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
|
||||
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.lower_bound_range(x)); }
|
||||
|
||||
/// @cond
|
||||
template <class K1, class T1, class C1, class A1>
|
||||
friend bool operator== (const flat_map<K1, T1, C1, A1>&,
|
||||
const flat_map<K1, T1, C1, A1>&);
|
||||
template <class K1, class T1, class C1, class A1>
|
||||
friend bool operator< (const flat_map<K1, T1, C1, A1>&,
|
||||
const flat_map<K1, T1, C1, A1>&);
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const flat_map& x, const flat_map& y)
|
||||
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const flat_map& x, const flat_map& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const flat_map& x, const flat_map& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const flat_map& x, const flat_map& y)
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const flat_map& x, const flat_map& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const flat_map& x, const flat_map& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(flat_map& x, flat_map& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
mapped_type &priv_subscript(const key_type& k)
|
||||
{
|
||||
@@ -872,45 +930,10 @@ class flat_map
|
||||
}
|
||||
return (*i).second;
|
||||
}
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator==(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y)
|
||||
{ return x.m_flat_tree == y.m_flat_tree; }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator<(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y)
|
||||
{ return x.m_flat_tree < y.m_flat_tree; }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator!=(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator>(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y)
|
||||
{ return y < x; }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator<=(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator>=(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline void swap(flat_map<Key,T,Compare,Allocator>& x,
|
||||
flat_map<Key,T,Compare,Allocator>& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
} //namespace container {
|
||||
|
||||
@@ -924,18 +947,7 @@ struct has_trivial_destructor_after_move<boost::container::flat_map<K, T, C, All
|
||||
|
||||
namespace container {
|
||||
|
||||
// Forward declaration of operators < and ==, needed for friend declaration.
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
class flat_multimap;
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator==(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y);
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator<(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y);
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! A flat_multimap is a kind of associative container that supports equivalent keys
|
||||
//! (possibly containing multiple copies of the same key value) and provides for
|
||||
@@ -960,6 +972,12 @@ inline bool operator<(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
//! pointing to elements that come after (their keys are bigger) the erased element.
|
||||
//!
|
||||
//! This container provides random-access iterators.
|
||||
//!
|
||||
//! \tparam Key is the key_type of the map
|
||||
//! \tparam Value is the <code>mapped_type</code>
|
||||
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
||||
//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
|
||||
//! (e.g. <i>allocator< std::pair<Key, T> > </i>).
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator< std::pair< Key, T> > >
|
||||
#else
|
||||
@@ -967,7 +985,7 @@ template <class Key, class T, class Compare, class Allocator>
|
||||
#endif
|
||||
class flat_multimap
|
||||
{
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_multimap)
|
||||
typedef container_detail::flat_tree<Key,
|
||||
@@ -999,7 +1017,7 @@ class flat_multimap
|
||||
<typename allocator_traits<Allocator>::pointer>::reverse_iterator reverse_iterator_impl;
|
||||
typedef typename container_detail::get_flat_tree_iterators
|
||||
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
|
||||
@@ -1037,7 +1055,11 @@ class flat_multimap
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
flat_multimap()
|
||||
: m_flat_tree() {}
|
||||
: m_flat_tree()
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison
|
||||
//! object and allocator.
|
||||
@@ -1046,14 +1068,20 @@ class flat_multimap
|
||||
explicit flat_multimap(const Compare& comp,
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
explicit flat_multimap(const allocator_type& a)
|
||||
: m_flat_tree(container_detail::force<impl_allocator_type>(a))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
|
||||
//! and allocator, and inserts elements from the range [first ,last ).
|
||||
@@ -1065,7 +1093,10 @@ class flat_multimap
|
||||
const Compare& comp = Compare(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(false, first, last, comp, container_detail::force<impl_allocator_type>(a))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
|
||||
//! allocator, and inserts elements from the ordered range [first ,last). This function
|
||||
@@ -1081,13 +1112,20 @@ class flat_multimap
|
||||
const Compare& comp = Compare(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(ordered_range, first, last, comp, a)
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a flat_multimap.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_multimap(const flat_multimap& x)
|
||||
: m_flat_tree(x.m_flat_tree) { }
|
||||
: m_flat_tree(x.m_flat_tree)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources.
|
||||
//!
|
||||
@@ -1096,14 +1134,20 @@ class flat_multimap
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
flat_multimap(BOOST_RV_REF(flat_multimap) x)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a flat_multimap using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_multimap(const flat_multimap& x, const allocator_type &a)
|
||||
: m_flat_tree(x.m_flat_tree, a)
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a flat_multimap using the specified allocator.
|
||||
//! Constructs *this using x's resources.
|
||||
@@ -1111,7 +1155,10 @@ class flat_multimap
|
||||
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
|
||||
flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree), a)
|
||||
{ }
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
@@ -1637,54 +1684,52 @@ class flat_multimap
|
||||
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
|
||||
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
|
||||
|
||||
/// @cond
|
||||
template <class K1, class T1, class C1, class A1>
|
||||
friend bool operator== (const flat_multimap<K1, T1, C1, A1>& x,
|
||||
const flat_multimap<K1, T1, C1, A1>& y);
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const flat_multimap& x, const flat_multimap& y)
|
||||
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
template <class K1, class T1, class C1, class A1>
|
||||
friend bool operator< (const flat_multimap<K1, T1, C1, A1>& x,
|
||||
const flat_multimap<K1, T1, C1, A1>& y);
|
||||
/// @endcond
|
||||
};
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const flat_multimap& x, const flat_multimap& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator==(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y)
|
||||
{ return x.m_flat_tree == y.m_flat_tree; }
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const flat_multimap& x, const flat_multimap& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator<(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y)
|
||||
{ return x.m_flat_tree < y.m_flat_tree; }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator!=(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator>(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y)
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const flat_multimap& x, const flat_multimap& y)
|
||||
{ return y < x; }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator<=(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y)
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const flat_multimap& x, const flat_multimap& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator>=(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y)
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const flat_multimap& x, const flat_multimap& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline void swap(flat_multimap<Key,T,Compare,Allocator>& x, flat_multimap<Key,T,Compare,Allocator>& y)
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(flat_multimap& x, flat_multimap& y)
|
||||
{ x.swap(y); }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1698,7 +1743,7 @@ struct has_trivial_destructor_after_move< boost::container::flat_multimap<K, T,
|
||||
|
||||
} //namespace boost {
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -47,7 +47,7 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
namespace container_detail {
|
||||
|
||||
template<class VoidPointer>
|
||||
@@ -99,7 +99,7 @@ struct intrusive_list_type
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! A list is a doubly linked list. That is, it is a Sequence that supports both
|
||||
//! forward and backward traversal, and (amortized) constant time insertion and
|
||||
@@ -111,6 +111,9 @@ struct intrusive_list_type
|
||||
//! after a list operation than it did before), but the iterators themselves will
|
||||
//! not be invalidated or made to point to different elements unless that invalidation
|
||||
//! or mutation is explicit.
|
||||
//!
|
||||
//! \tparam T The type of object that is stored in the list
|
||||
//! \tparam Allocator The allocator used for all internal memory management
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class T, class Allocator = std::allocator<T> >
|
||||
#else
|
||||
@@ -120,7 +123,7 @@ class list
|
||||
: protected container_detail::node_alloc_holder
|
||||
<Allocator, typename container_detail::intrusive_list_type<Allocator>::type>
|
||||
{
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef typename
|
||||
container_detail::intrusive_list_type<Allocator>::type Icont;
|
||||
typedef container_detail::node_alloc_holder<Allocator, Icont> AllocHolder;
|
||||
@@ -167,7 +170,7 @@ class list
|
||||
|
||||
typedef container_detail::iterator<typename Icont::iterator, false> iterator_impl;
|
||||
typedef container_detail::iterator<typename Icont::iterator, true> const_iterator_impl;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////
|
||||
@@ -1214,9 +1217,65 @@ class list
|
||||
//!
|
||||
//! <b>Note</b>: Iterators and references are not invalidated
|
||||
void reverse() BOOST_CONTAINER_NOEXCEPT
|
||||
{ this->icont().reverse(); }
|
||||
{ this->icont().reverse(); }
|
||||
|
||||
/// @cond
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const list& x, const list& y)
|
||||
{
|
||||
if(x.size() != y.size()){
|
||||
return false;
|
||||
}
|
||||
typedef typename list::const_iterator const_iterator;
|
||||
const_iterator end1 = x.end();
|
||||
|
||||
const_iterator i1 = x.begin();
|
||||
const_iterator i2 = y.begin();
|
||||
while (i1 != end1 && *i1 == *i2) {
|
||||
++i1;
|
||||
++i2;
|
||||
}
|
||||
return i1 == end1;
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const list& x, const list& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const list& x, const list& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const list& x, const list& y)
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const list& x, const list& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const list& x, const list& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(list& x, list& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
|
||||
bool priv_try_shrink(size_type new_size)
|
||||
@@ -1303,66 +1362,11 @@ class list
|
||||
bool operator()(const value_type &a, const value_type &b) const
|
||||
{ return a == b; }
|
||||
};
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
};
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator==(const list<T,Allocator>& x, const list<T,Allocator>& y)
|
||||
{
|
||||
if(x.size() != y.size()){
|
||||
return false;
|
||||
}
|
||||
typedef typename list<T,Allocator>::const_iterator const_iterator;
|
||||
const_iterator end1 = x.end();
|
||||
|
||||
const_iterator i1 = x.begin();
|
||||
const_iterator i2 = y.begin();
|
||||
while (i1 != end1 && *i1 == *i2) {
|
||||
++i1;
|
||||
++i2;
|
||||
}
|
||||
return i1 == end1;
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator<(const list<T,Allocator>& x,
|
||||
const list<T,Allocator>& y)
|
||||
{
|
||||
return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator!=(const list<T,Allocator>& x, const list<T,Allocator>& y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator>(const list<T,Allocator>& x, const list<T,Allocator>& y)
|
||||
{
|
||||
return y < x;
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator<=(const list<T,Allocator>& x, const list<T,Allocator>& y)
|
||||
{
|
||||
return !(y < x);
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator>=(const list<T,Allocator>& x, const list<T,Allocator>& y)
|
||||
{
|
||||
return !(x < y);
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline void swap(list<T, Allocator>& x, list<T, Allocator>& y)
|
||||
{
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
} //namespace container {
|
||||
|
||||
@@ -1375,7 +1379,7 @@ struct has_trivial_destructor_after_move<boost::container::list<T, Allocator> >
|
||||
|
||||
namespace container {
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
}}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
346
include/boost/container/node_allocator.hpp
Normal file
346
include/boost/container/node_allocator.hpp
Normal file
@@ -0,0 +1,346 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_POOLED_NODE_ALLOCATOR_HPP
|
||||
#define BOOST_CONTAINER_POOLED_NODE_ALLOCATOR_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
#include <boost/container/detail/node_pool.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/container/detail/alloc_lib_auto_link.hpp>
|
||||
#include <boost/container/detail/singleton.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//!An STL node allocator that uses a modified DlMalloc as memory
|
||||
//!source.
|
||||
//!
|
||||
//!This node allocator shares a segregated storage between all instances
|
||||
//!of node_allocator with equal sizeof(T).
|
||||
//!
|
||||
//!NodesPerBlock is the number of nodes allocated at once when the allocator
|
||||
//!runs out of nodes
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template
|
||||
< class T
|
||||
, std::size_t NodesPerBlock = NodeAlloc_nodes_per_block>
|
||||
#else
|
||||
template
|
||||
< class T
|
||||
, std::size_t NodesPerBlock
|
||||
, std::size_t Version>
|
||||
#endif
|
||||
class node_allocator
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
//! If Version is 1, the allocator is a STL conforming allocator. If Version is 2,
|
||||
//! the allocator offers advanced expand in place and burst allocation capabilities.
|
||||
public:
|
||||
typedef unsigned int allocation_type;
|
||||
typedef node_allocator<T, NodesPerBlock, Version> self_t;
|
||||
|
||||
static const std::size_t nodes_per_block = NodesPerBlock;
|
||||
|
||||
BOOST_STATIC_ASSERT((Version <=2));
|
||||
#endif
|
||||
|
||||
public:
|
||||
//-------
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
typedef const T * const_pointer;
|
||||
typedef typename ::boost::container::
|
||||
container_detail::unvoid<T>::type & reference;
|
||||
typedef const typename ::boost::container::
|
||||
container_detail::unvoid<T>::type & const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
typedef boost::container::container_detail::
|
||||
version_type<self_t, Version> version;
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef boost::container::container_detail::
|
||||
basic_multiallocation_chain<void*> multiallocation_chain_void;
|
||||
typedef boost::container::container_detail::
|
||||
transform_multiallocation_chain
|
||||
<multiallocation_chain_void, T> multiallocation_chain;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//!Obtains node_allocator from
|
||||
//!node_allocator
|
||||
template<class T2>
|
||||
struct rebind
|
||||
{
|
||||
typedef node_allocator< T2, NodesPerBlock
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
, Version
|
||||
#endif
|
||||
> other;
|
||||
};
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
//!Not assignable from related node_allocator
|
||||
template<class T2, std::size_t N2>
|
||||
node_allocator& operator=
|
||||
(const node_allocator<T2, N2>&);
|
||||
|
||||
//!Not assignable from other node_allocator
|
||||
node_allocator& operator=(const node_allocator&);
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
|
||||
//!Default constructor
|
||||
node_allocator() BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Copy constructor from other node_allocator.
|
||||
node_allocator(const node_allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Copy constructor from related node_allocator.
|
||||
template<class T2>
|
||||
node_allocator
|
||||
(const node_allocator<T2, NodesPerBlock
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
, Version
|
||||
#endif
|
||||
> &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Destructor
|
||||
~node_allocator() BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Returns the number of elements that could be allocated.
|
||||
//!Never throws
|
||||
size_type max_size() const
|
||||
{ return size_type(-1)/sizeof(T); }
|
||||
|
||||
//!Allocate memory for an array of count elements.
|
||||
//!Throws std::bad_alloc if there is no enough memory
|
||||
pointer allocate(size_type count, const void * = 0)
|
||||
{
|
||||
if(count > this->max_size())
|
||||
boost::container::throw_bad_alloc();
|
||||
|
||||
if(Version == 1 && count == 1){
|
||||
typedef container_detail::shared_node_pool
|
||||
<sizeof(T), NodesPerBlock> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
return pointer(static_cast<T*>(singleton_t::instance().allocate_node()));
|
||||
}
|
||||
else{
|
||||
void *ret = boost_cont_malloc(count*sizeof(T));
|
||||
if(!ret)
|
||||
boost::container::throw_bad_alloc();
|
||||
return static_cast<pointer>(ret);
|
||||
}
|
||||
}
|
||||
|
||||
//!Deallocate allocated memory.
|
||||
//!Never throws
|
||||
void deallocate(const pointer &ptr, size_type count) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
(void)count;
|
||||
if(Version == 1 && count == 1){
|
||||
typedef container_detail::shared_node_pool
|
||||
<sizeof(T), NodesPerBlock> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
singleton_t::instance().deallocate_node(ptr);
|
||||
}
|
||||
else{
|
||||
boost_cont_free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
//!Deallocates all free blocks of the pool
|
||||
static void deallocate_free_blocks() BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
typedef container_detail::shared_node_pool
|
||||
<sizeof(T), NodesPerBlock> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
singleton_t::instance().deallocate_free_blocks();
|
||||
}
|
||||
|
||||
std::pair<pointer, bool>
|
||||
allocation_command(allocation_type command,
|
||||
size_type limit_size,
|
||||
size_type preferred_size,
|
||||
size_type &received_size, pointer reuse = pointer())
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
std::pair<pointer, bool> ret =
|
||||
priv_allocation_command(command, limit_size, preferred_size, received_size, reuse);
|
||||
if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
|
||||
boost::container::throw_bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//!Returns maximum the number of objects the previously allocated memory
|
||||
//!pointed by p can hold.
|
||||
size_type size(pointer p) const BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
return boost_cont_size(p);
|
||||
}
|
||||
|
||||
//!Allocates just one object. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
//!Throws bad_alloc if there is no enough memory
|
||||
pointer allocate_one()
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
typedef container_detail::shared_node_pool
|
||||
<sizeof(T), NodesPerBlock> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
return (pointer)singleton_t::instance().allocate_node();
|
||||
}
|
||||
|
||||
//!Allocates many elements of size == 1.
|
||||
//!Elements must be individually deallocated with deallocate_one()
|
||||
void allocate_individual(std::size_t num_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
typedef container_detail::shared_node_pool
|
||||
<sizeof(T), NodesPerBlock> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
typename shared_pool_t::multiallocation_chain ch;
|
||||
singleton_t::instance().allocate_nodes(num_elements, ch);
|
||||
chain.incorporate_after(chain.before_begin(), (T*)&*ch.begin(), (T*)&*ch.last(), ch.size());
|
||||
}
|
||||
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
||||
//!with other functions different from allocate_one(). Never throws
|
||||
void deallocate_one(pointer p) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
typedef container_detail::shared_node_pool
|
||||
<sizeof(T), NodesPerBlock> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
singleton_t::instance().deallocate_node(p);
|
||||
}
|
||||
|
||||
void deallocate_individual(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
typedef container_detail::shared_node_pool
|
||||
<sizeof(T), NodesPerBlock> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
typename shared_pool_t::multiallocation_chain ch(&*chain.begin(), &*chain.last(), chain.size());
|
||||
singleton_t::instance().deallocate_nodes(ch);
|
||||
}
|
||||
|
||||
//!Allocates many elements of size elem_size.
|
||||
//!Elements must be individually deallocated with deallocate()
|
||||
void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
boost_cont_memchain ch;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
|
||||
if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
chain.incorporate_after( chain.before_begin()
|
||||
, (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
, (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
, BOOST_CONTAINER_MEMCHAIN_SIZE(&ch));
|
||||
}
|
||||
|
||||
//!Allocates n_elements elements, each one of size elem_sizes[i]
|
||||
//!Elements must be individually deallocated with deallocate()
|
||||
void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
boost_cont_memchain ch;
|
||||
boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch);
|
||||
if(BOOST_CONTAINER_MEMCHAIN_EMPTY(&ch)){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
chain.incorporate_after( chain.before_begin()
|
||||
, (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
, (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
, BOOST_CONTAINER_MEMCHAIN_SIZE(&ch));
|
||||
}
|
||||
|
||||
void deallocate_many(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
void *first = &*chain.begin();
|
||||
void *last = &*chain.last();
|
||||
size_t num = chain.size();
|
||||
boost_cont_memchain ch;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&ch, first, last, num);
|
||||
boost_cont_multidealloc(&ch);
|
||||
}
|
||||
|
||||
//!Swaps allocators. Does not throw. If each allocator is placed in a
|
||||
//!different memory segment, the result is undefined.
|
||||
friend void swap(self_t &, self_t &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!An allocator always compares to true, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator==(const node_allocator &, const node_allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return true; }
|
||||
|
||||
//!An allocator always compares to false, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator!=(const node_allocator &, const node_allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return false; }
|
||||
|
||||
private:
|
||||
std::pair<pointer, bool> priv_allocation_command
|
||||
(allocation_type command, std::size_t limit_size
|
||||
,std::size_t preferred_size,std::size_t &received_size, void *reuse_ptr)
|
||||
{
|
||||
boost_cont_command_ret_t ret = {0 , 0};
|
||||
if(limit_size > this->max_size() || preferred_size > this->max_size()){
|
||||
//ret.first = 0;
|
||||
return std::pair<pointer, bool>(pointer(), false);
|
||||
}
|
||||
std::size_t l_size = limit_size*sizeof(T);
|
||||
std::size_t p_size = preferred_size*sizeof(T);
|
||||
std::size_t r_size;
|
||||
{
|
||||
ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr);
|
||||
}
|
||||
received_size = r_size/sizeof(T);
|
||||
return std::pair<pointer, bool>(static_cast<pointer>(ret.first), !!ret.second);
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_POOLED_NODE_ALLOCATOR_HPP
|
||||
72
include/boost/container/options.hpp
Normal file
72
include/boost/container/options.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_OPTIONS_HPP
|
||||
#define BOOST_CONTAINER_OPTIONS_HPP
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/intrusive/pack_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
template<tree_type_enum TreeType, bool OptimizeSize>
|
||||
struct tree_opt
|
||||
{
|
||||
static const boost::container::tree_type_enum tree_type = TreeType;
|
||||
static const bool optimize_size = OptimizeSize;
|
||||
};
|
||||
|
||||
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//!This option setter specifies the underlying tree type
|
||||
//!(red-black, AVL, Scapegoat or Splay) for ordered associative containers
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(tree_type, tree_type_enum, TreeType, tree_type)
|
||||
|
||||
//!This option setter specifies if node size is optimized
|
||||
//!storing rebalancing data masked into pointers for ordered associative containers
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size)
|
||||
|
||||
//! Helper metafunction to combine options into a single type to be used
|
||||
//! by \c boost::container::set, \c boost::container::multiset
|
||||
//! \c boost::container::map and \c boost::container::multimap.
|
||||
//! Supported options are: \c boost::container::optimize_size and \c boost::container::tree_type
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
|
||||
#endif
|
||||
struct tree_assoc_options
|
||||
{
|
||||
/// @cond
|
||||
typedef typename ::boost::intrusive::pack_options
|
||||
< tree_assoc_defaults,
|
||||
#if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type packed_options;
|
||||
typedef tree_opt<packed_options::tree_type, packed_options::optimize_size> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_OPTIONS_HPP
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -46,7 +46,7 @@ namespace boost { namespace container {
|
||||
//! and if T is used in a context where a container must call such a constructor, then the program is
|
||||
//! ill-formed.
|
||||
//!
|
||||
//! [Example:
|
||||
//! <code>
|
||||
//! template <class T, class Allocator = allocator<T> >
|
||||
//! class Z {
|
||||
//! public:
|
||||
@@ -64,7 +64,7 @@ namespace boost { namespace container {
|
||||
//! template <class T, class Allocator = allocator<T> >
|
||||
//! struct constructible_with_allocator_suffix<Z<T,Allocator> >
|
||||
//! : ::boost::true_type { };
|
||||
//! -- end example]
|
||||
//! </code>
|
||||
//!
|
||||
//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)"
|
||||
//! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as
|
||||
@@ -90,7 +90,7 @@ struct constructible_with_allocator_suffix
|
||||
//! called with these initial arguments, and if T is used in a context where a container must call such
|
||||
//! a constructor, then the program is ill-formed.
|
||||
//!
|
||||
//! [Example:
|
||||
//! <code>
|
||||
//! template <class T, class Allocator = allocator<T> >
|
||||
//! class Y {
|
||||
//! public:
|
||||
@@ -115,7 +115,7 @@ struct constructible_with_allocator_suffix
|
||||
//! struct constructible_with_allocator_prefix<Y<T,Allocator> >
|
||||
//! : ::boost::true_type { };
|
||||
//!
|
||||
//! -- end example]
|
||||
//! </code>
|
||||
//!
|
||||
//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)"
|
||||
//! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as
|
||||
@@ -130,7 +130,7 @@ struct constructible_with_allocator_prefix
|
||||
: ::boost::false_type
|
||||
{};
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
@@ -159,7 +159,7 @@ struct uses_allocator_imp
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Remark</b>: Automatically detects if T has a nested allocator_type that is convertible from
|
||||
//! Alloc. Meets the BinaryTypeTrait requirements ([meta.rqmts] 20.4.1). A program may
|
||||
@@ -173,7 +173,7 @@ struct uses_allocator
|
||||
: boost::integral_constant<bool, container_detail::uses_allocator_imp<T, Alloc>::value>
|
||||
{};
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
@@ -675,16 +675,16 @@ class scoped_allocator_adaptor_base
|
||||
friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
|
||||
{ l.swap(r); }
|
||||
|
||||
inner_allocator_type& inner_allocator()
|
||||
inner_allocator_type& inner_allocator() BOOST_CONTAINER_NOEXCEPT
|
||||
{ return m_inner; }
|
||||
|
||||
inner_allocator_type const& inner_allocator() const
|
||||
inner_allocator_type const& inner_allocator() const BOOST_CONTAINER_NOEXCEPT
|
||||
{ return m_inner; }
|
||||
|
||||
outer_allocator_type & outer_allocator()
|
||||
outer_allocator_type & outer_allocator() BOOST_CONTAINER_NOEXCEPT
|
||||
{ return static_cast<outer_allocator_type&>(*this); }
|
||||
|
||||
const outer_allocator_type &outer_allocator() const
|
||||
const outer_allocator_type &outer_allocator() const BOOST_CONTAINER_NOEXCEPT
|
||||
{ return static_cast<const outer_allocator_type&>(*this); }
|
||||
|
||||
scoped_allocator_type select_on_container_copy_construction() const
|
||||
@@ -1008,7 +1008,7 @@ class scoped_allocator_adaptor_base
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//Scoped allocator
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
@@ -1038,14 +1038,14 @@ class scoped_allocator_adaptor_base
|
||||
//! scoped_allocator_adaptor is derived from the outer allocator type so it can be
|
||||
//! substituted for the outer allocator type in most expressions. -end note]
|
||||
//!
|
||||
//! In the construct member functions, `OUTERMOST(x)` is x if x does not have
|
||||
//! an `outer_allocator()` member function and
|
||||
//! `OUTERMOST(x.outer_allocator())` otherwise; `OUTERMOST_ALLOC_TRAITS(x)` is
|
||||
//! `allocator_traits<decltype(OUTERMOST(x))>`.
|
||||
//! In the construct member functions, <code>OUTERMOST(x)</code> is x if x does not have
|
||||
//! an <code>outer_allocator()</code> member function and
|
||||
//! <code>OUTERMOST(x.outer_allocator())</code> otherwise; <code>OUTERMOST_ALLOC_TRAITS(x)</code> is
|
||||
//! <code>allocator_traits<decltype(OUTERMOST(x))></code>.
|
||||
//!
|
||||
//! [<b>Note</b>: `OUTERMOST(x)` and
|
||||
//! `OUTERMOST_ALLOC_TRAITS(x)` are recursive operations. It is incumbent upon
|
||||
//! the definition of `outer_allocator()` to ensure that the recursion terminates.
|
||||
//! [<b>Note</b>: <code>OUTERMOST(x)</code> and
|
||||
//! <code>OUTERMOST_ALLOC_TRAITS(x)</code> are recursive operations. It is incumbent upon
|
||||
//! the definition of <code>outer_allocator()</code> to ensure that the recursion terminates.
|
||||
//! It will terminate for all instantiations of scoped_allocator_adaptor. -end note]
|
||||
template <typename OuterAlloc, typename ...InnerAllocs>
|
||||
class scoped_allocator_adaptor
|
||||
@@ -1076,7 +1076,7 @@ class scoped_allocator_adaptor
|
||||
BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor)
|
||||
|
||||
public:
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef container_detail::scoped_allocator_adaptor_base
|
||||
<OuterAlloc
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
@@ -1086,13 +1086,13 @@ class scoped_allocator_adaptor
|
||||
#endif
|
||||
> base_type;
|
||||
typedef typename base_type::internal_type_t internal_type_t;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef OuterAlloc outer_allocator_type;
|
||||
//! Type: For exposition only
|
||||
//!
|
||||
typedef allocator_traits<OuterAlloc> outer_traits_type;
|
||||
//! Type: `scoped_allocator_adaptor<OuterAlloc>` if `sizeof...(InnerAllocs)` is zero; otherwise,
|
||||
//! `scoped_allocator_adaptor<InnerAllocs...>`.
|
||||
//! Type: <code>scoped_allocator_adaptor<OuterAlloc></code> if <code>sizeof...(InnerAllocs)</code> is zero; otherwise,
|
||||
//! <code>scoped_allocator_adaptor<InnerAllocs...></code>.
|
||||
typedef typename base_type::inner_allocator_type inner_allocator_type;
|
||||
typedef allocator_traits<inner_allocator_type> inner_traits_type;
|
||||
typedef typename outer_traits_type::value_type value_type;
|
||||
@@ -1102,23 +1102,23 @@ class scoped_allocator_adaptor
|
||||
typedef typename outer_traits_type::const_pointer const_pointer;
|
||||
typedef typename outer_traits_type::void_pointer void_pointer;
|
||||
typedef typename outer_traits_type::const_void_pointer const_void_pointer;
|
||||
//! Type: `true_type` if `allocator_traits<Allocator>::propagate_on_container_copy_assignment::value` is
|
||||
//! true for any `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type.
|
||||
//! Type: <code>true_type</code> if <code>allocator_traits<Allocator>::propagate_on_container_copy_assignment::value</code> is
|
||||
//! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>; otherwise, false_type.
|
||||
typedef typename base_type::
|
||||
propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
|
||||
//! Type: `true_type` if `allocator_traits<Allocator>::propagate_on_container_move_assignment::value` is
|
||||
//! true for any `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type.
|
||||
//! Type: <code>true_type</code> if <code>allocator_traits<Allocator>::propagate_on_container_move_assignment::value</code> is
|
||||
//! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>; otherwise, false_type.
|
||||
typedef typename base_type::
|
||||
propagate_on_container_move_assignment propagate_on_container_move_assignment;
|
||||
//! Type: `true_type` if `allocator_traits<Allocator>::propagate_on_container_swap::value` is true for any
|
||||
//! `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type.
|
||||
//! Type: <code>true_type</code> if <code>allocator_traits<Allocator>::propagate_on_container_swap::value</code> is true for any
|
||||
//! <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>; otherwise, false_type.
|
||||
typedef typename base_type::
|
||||
propagate_on_container_swap propagate_on_container_swap;
|
||||
|
||||
//! Type: Rebinds scoped allocator to
|
||||
//! `typedef scoped_allocator_adaptor
|
||||
//! <code>typedef scoped_allocator_adaptor
|
||||
//! < typename outer_traits_type::template portable_rebind_alloc<U>::type
|
||||
//! , InnerAllocs... >`
|
||||
//! , InnerAllocs... ></code>
|
||||
template <class U>
|
||||
struct rebind
|
||||
{
|
||||
@@ -1224,55 +1224,55 @@ class scoped_allocator_adaptor
|
||||
friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r);
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! `static_cast<OuterAlloc&>(*this)`.
|
||||
outer_allocator_type & outer_allocator();
|
||||
//! <code>static_cast<OuterAlloc&>(*this)</code>.
|
||||
outer_allocator_type & outer_allocator() BOOST_CONTAINER_NOEXCEPT;
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! `static_cast<const OuterAlloc&>(*this)`.
|
||||
const outer_allocator_type &outer_allocator() const;
|
||||
//! <code>static_cast<const OuterAlloc&>(*this)</code>.
|
||||
const outer_allocator_type &outer_allocator() const BOOST_CONTAINER_NOEXCEPT;
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner.
|
||||
inner_allocator_type& inner_allocator();
|
||||
//! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
|
||||
inner_allocator_type& inner_allocator() BOOST_CONTAINER_NOEXCEPT;
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner.
|
||||
inner_allocator_type const& inner_allocator() const;
|
||||
//! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
|
||||
inner_allocator_type const& inner_allocator() const BOOST_CONTAINER_NOEXCEPT;
|
||||
|
||||
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! `allocator_traits<OuterAlloc>::max_size(outer_allocator())`.
|
||||
size_type max_size() const
|
||||
//! <code>allocator_traits<OuterAlloc>::max_size(outer_allocator())</code>.
|
||||
size_type max_size() const BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
return outer_traits_type::max_size(this->outer_allocator());
|
||||
}
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! calls `OUTERMOST_ALLOC_TRAITS(*this)::destroy(OUTERMOST(*this), p)`.
|
||||
//! calls <code>OUTERMOST_ALLOC_TRAITS(*this)::destroy(OUTERMOST(*this), p)</code>.
|
||||
template <class T>
|
||||
void destroy(T* p)
|
||||
void destroy(T* p) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
allocator_traits<typename outermost_allocator<OuterAlloc>::type>
|
||||
::destroy(get_outermost_allocator(this->outer_allocator()), p);
|
||||
}
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! `allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)`.
|
||||
//! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)</code>.
|
||||
pointer allocate(size_type n)
|
||||
{
|
||||
return outer_traits_type::allocate(this->outer_allocator(), n);
|
||||
}
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! `allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)`.
|
||||
//! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)</code>.
|
||||
pointer allocate(size_type n, const_void_pointer hint)
|
||||
{
|
||||
return outer_traits_type::allocate(this->outer_allocator(), n, hint);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! `allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n)`.
|
||||
//! <code>allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n)</code>.
|
||||
void deallocate(pointer p, size_type n)
|
||||
{
|
||||
outer_traits_type::deallocate(this->outer_allocator(), p, n);
|
||||
@@ -1281,45 +1281,45 @@ class scoped_allocator_adaptor
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
//! <b>Returns</b>: Allocator new scoped_allocator_adaptor object where each allocator
|
||||
//! A in the adaptor is initialized from the result of calling
|
||||
//! `allocator_traits<Allocator>::select_on_container_copy_construction()` on
|
||||
//! <code>allocator_traits<Allocator>::select_on_container_copy_construction()</code> on
|
||||
//! the corresponding allocator in *this.
|
||||
scoped_allocator_adaptor select_on_container_copy_construction() const;
|
||||
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
base_type &base() { return *this; }
|
||||
|
||||
const base_type &base() const { return *this; }
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! 1) If `uses_allocator<T, inner_allocator_type>::value` is false calls
|
||||
//! `OUTERMOST_ALLOC_TRAITS(*this)::construct
|
||||
//! (OUTERMOST(*this), p, std::forward<Args>(args)...)`.
|
||||
//! 1) If <code>uses_allocator<T, inner_allocator_type>::value</code> is false calls
|
||||
//! <code>OUTERMOST_ALLOC_TRAITS(*this)::construct
|
||||
//! (OUTERMOST(*this), p, std::forward<Args>(args)...)</code>.
|
||||
//!
|
||||
//! 2) Otherwise, if `uses_allocator<T, inner_allocator_type>::value` is true and
|
||||
//! `is_constructible<T, allocator_arg_t, inner_allocator_type, Args...>::value` is true, calls
|
||||
//! `OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, allocator_arg,
|
||||
//! inner_allocator(), std::forward<Args>(args)...)`.
|
||||
//! 2) Otherwise, if <code>uses_allocator<T, inner_allocator_type>::value</code> is true and
|
||||
//! <code>is_constructible<T, allocator_arg_t, inner_allocator_type, Args...>::value</code> is true, calls
|
||||
//! <code>OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, allocator_arg,
|
||||
//! inner_allocator(), std::forward<Args>(args)...)</code>.
|
||||
//!
|
||||
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, `is_constructible` can't
|
||||
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't
|
||||
//! be implemented so that condition will be replaced by
|
||||
//! constructible_with_allocator_prefix<T>::value. -end note]
|
||||
//!
|
||||
//! 3) Otherwise, if uses_allocator<T, inner_allocator_type>::value is true and
|
||||
//! `is_constructible<T, Args..., inner_allocator_type>::value` is true, calls
|
||||
//! `OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p,
|
||||
//! std::forward<Args>(args)..., inner_allocator())`.
|
||||
//! <code>is_constructible<T, Args..., inner_allocator_type>::value</code> is true, calls
|
||||
//! <code>OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p,
|
||||
//! std::forward<Args>(args)..., inner_allocator())</code>.
|
||||
//!
|
||||
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, `is_constructible` can't be
|
||||
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't be
|
||||
//! implemented so that condition will be replaced by
|
||||
//! `constructible_with_allocator_suffix<T>::value`. -end note]
|
||||
//! <code>constructible_with_allocator_suffix<T>::value</code>. -end note]
|
||||
//!
|
||||
//! 4) Otherwise, the program is ill-formed.
|
||||
//!
|
||||
//! [<b>Note</b>: An error will result if `uses_allocator` evaluates
|
||||
//! [<b>Note</b>: An error will result if <code>uses_allocator</code> evaluates
|
||||
//! to true but the specific constructor does not take an allocator. This definition prevents a silent
|
||||
//! failure to pass an inner allocator to a contained element. -end note]
|
||||
template < typename T, class ...Args>
|
||||
@@ -1395,7 +1395,7 @@ class scoped_allocator_adaptor
|
||||
, BOOST_RV_REF_BEG container_detail::pair<U, V> BOOST_RV_REF_END x)
|
||||
{ this->construct_pair(p, x); }
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
template <class Pair>
|
||||
void construct_pair(Pair* p)
|
||||
@@ -1463,7 +1463,7 @@ class scoped_allocator_adaptor
|
||||
: base_type(internal_type_t(), ::boost::forward<OuterA2>(outer), inner)
|
||||
{}
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
template <typename OuterA1, typename OuterA2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
|
||||
#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
|
||||
|
||||
//! \file
|
||||
//! This header file forward declares boost::container::scoped_allocator_adaptor
|
||||
//! and defines the following types:
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
@@ -25,7 +29,7 @@
|
||||
|
||||
namespace boost { namespace container {
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
@@ -55,7 +59,7 @@ class scoped_allocator_adaptor;
|
||||
|
||||
#endif
|
||||
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! The allocator_arg_t struct is an empty structure type used as a unique type to
|
||||
//! disambiguate constructor and function overloading. Specifically, several types
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -48,7 +48,7 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template <class T, class Allocator>
|
||||
class slist;
|
||||
@@ -106,7 +106,7 @@ struct intrusive_slist_type
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! An slist is a singly linked list: a list where each element is linked to the next
|
||||
//! element, but not to the previous element. That is, it is a Sequence that
|
||||
@@ -140,6 +140,9 @@ struct intrusive_slist_type
|
||||
//! possible. If you find that insert_after and erase_after aren't adequate for your
|
||||
//! needs, and that you often need to use insert and erase in the middle of the list,
|
||||
//! then you should probably use list instead of slist.
|
||||
//!
|
||||
//! \tparam T The type of object that is stored in the list
|
||||
//! \tparam Allocator The allocator used for all internal memory management
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class T, class Allocator = std::allocator<T> >
|
||||
#else
|
||||
@@ -149,7 +152,7 @@ class slist
|
||||
: protected container_detail::node_alloc_holder
|
||||
<Allocator, typename container_detail::intrusive_slist_type<Allocator>::type>
|
||||
{
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef typename
|
||||
container_detail::intrusive_slist_type<Allocator>::type Icont;
|
||||
typedef container_detail::node_alloc_holder<Allocator, Icont> AllocHolder;
|
||||
@@ -195,7 +198,7 @@ class slist
|
||||
BOOST_COPYABLE_AND_MOVABLE(slist)
|
||||
typedef container_detail::iterator<typename Icont::iterator, false> iterator_impl;
|
||||
typedef container_detail::iterator<typename Icont::iterator, true > const_iterator_impl;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////
|
||||
@@ -313,7 +316,7 @@ class slist
|
||||
this->icont().swap(x.icont());
|
||||
}
|
||||
else{
|
||||
this->insert(this->cbegin(), x.begin(), x.end());
|
||||
this->insert_after(this->cbefore_begin(), x.begin(), x.end());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1423,14 +1426,70 @@ class slist
|
||||
void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
|
||||
{ this->splice(p, static_cast<slist&>(x), first, last); }
|
||||
|
||||
/// @cond
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const slist& x, const slist& y)
|
||||
{
|
||||
if(x.size() != y.size()){
|
||||
return false;
|
||||
}
|
||||
typedef typename slist<T,Allocator>::const_iterator const_iterator;
|
||||
const_iterator end1 = x.end();
|
||||
|
||||
const_iterator i1 = x.begin();
|
||||
const_iterator i2 = y.begin();
|
||||
while (i1 != end1 && *i1 == *i2){
|
||||
++i1;
|
||||
++i2;
|
||||
}
|
||||
return i1 == end1;
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const slist& x, const slist& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const slist& x, const slist& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const slist& x, const slist& y)
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const slist& x, const slist& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const slist& x, const slist& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(slist& x, slist& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
|
||||
void priv_push_front (const T &x)
|
||||
{ this->insert(this->cbegin(), x); }
|
||||
{ this->insert_after(this->cbefore_begin(), x); }
|
||||
|
||||
void priv_push_front (BOOST_RV_REF(T) x)
|
||||
{ this->insert(this->cbegin(), ::boost::move(x)); }
|
||||
{ this->insert_after(this->cbefore_begin(), ::boost::move(x)); }
|
||||
|
||||
bool priv_try_shrink(size_type new_size, const_iterator &last_pos)
|
||||
{
|
||||
@@ -1505,63 +1564,12 @@ class slist
|
||||
|
||||
const value_type &m_ref;
|
||||
};
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool
|
||||
operator==(const slist<T,Allocator>& x, const slist<T,Allocator>& y)
|
||||
{
|
||||
if(x.size() != y.size()){
|
||||
return false;
|
||||
}
|
||||
typedef typename slist<T,Allocator>::const_iterator const_iterator;
|
||||
const_iterator end1 = x.end();
|
||||
|
||||
const_iterator i1 = x.begin();
|
||||
const_iterator i2 = y.begin();
|
||||
while (i1 != end1 && *i1 == *i2){
|
||||
++i1;
|
||||
++i2;
|
||||
}
|
||||
return i1 == end1;
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool
|
||||
operator<(const slist<T,Allocator>& sL1, const slist<T,Allocator>& sL2)
|
||||
{
|
||||
return std::lexicographical_compare
|
||||
(sL1.begin(), sL1.end(), sL2.begin(), sL2.end());
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool
|
||||
operator!=(const slist<T,Allocator>& sL1, const slist<T,Allocator>& sL2)
|
||||
{ return !(sL1 == sL2); }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool
|
||||
operator>(const slist<T,Allocator>& sL1, const slist<T,Allocator>& sL2)
|
||||
{ return sL2 < sL1; }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool
|
||||
operator<=(const slist<T,Allocator>& sL1, const slist<T,Allocator>& sL2)
|
||||
{ return !(sL2 < sL1); }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool
|
||||
operator>=(const slist<T,Allocator>& sL1, const slist<T,Allocator>& sL2)
|
||||
{ return !(sL1 < sL2); }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline void swap(slist<T,Allocator>& x, slist<T,Allocator>& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
}}
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1574,14 +1582,14 @@ struct has_trivial_destructor_after_move<boost::container::slist<T, Allocator> >
|
||||
|
||||
namespace container {
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
}} //namespace boost{ namespace container {
|
||||
|
||||
// Specialization of insert_iterator so that insertions will be constant
|
||||
// time rather than linear time.
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//Ummm, I don't like to define things in namespace std, but
|
||||
//there is no other way
|
||||
@@ -1620,7 +1628,7 @@ class insert_iterator<boost::container::slist<T, Allocator> >
|
||||
|
||||
} //namespace std;
|
||||
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-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)
|
||||
//
|
||||
@@ -47,18 +47,18 @@
|
||||
#include <memory>
|
||||
#include <new> //placement new
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#include <boost/container/vector.hpp>
|
||||
|
||||
//#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
|
||||
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace stable_vector_detail{
|
||||
|
||||
@@ -393,7 +393,7 @@ struct index_traits
|
||||
|
||||
#endif //#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! Originally developed by Joaquin M. Lopez Munoz, stable_vector is a std::vector
|
||||
//! drop-in replacement implemented as a node container, offering iterator and reference
|
||||
@@ -426,6 +426,9 @@ struct index_traits
|
||||
//!
|
||||
//! Exception safety: As stable_vector does not internally copy elements around, some
|
||||
//! operations provide stronger exception safety guarantees than in std::vector.
|
||||
//!
|
||||
//! \tparam T The type of object that is stored in the stable_vector
|
||||
//! \tparam Allocator The allocator used for all internal memory management
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class T, class Allocator = std::allocator<T> >
|
||||
#else
|
||||
@@ -433,7 +436,7 @@ template <class T, class Allocator>
|
||||
#endif
|
||||
class stable_vector
|
||||
{
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||
typedef boost::intrusive::
|
||||
pointer_traits
|
||||
@@ -504,7 +507,7 @@ class stable_vector
|
||||
typedef stable_vector_detail::iterator
|
||||
< typename allocator_traits<Allocator>::pointer
|
||||
, false> const_iterator_impl;
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
public:
|
||||
|
||||
//////////////////////////////////////////////
|
||||
@@ -526,7 +529,7 @@ class stable_vector
|
||||
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
|
||||
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(stable_vector)
|
||||
static const size_type ExtraPointers = index_traits_type::ExtraPointers;
|
||||
@@ -536,7 +539,7 @@ class stable_vector
|
||||
|
||||
class push_back_rollback;
|
||||
friend class push_back_rollback;
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////
|
||||
@@ -1510,8 +1513,49 @@ class stable_vector
|
||||
void clear() BOOST_CONTAINER_NOEXCEPT
|
||||
{ this->erase(this->cbegin(),this->cend()); }
|
||||
|
||||
/// @cond
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const stable_vector& x, const stable_vector& y)
|
||||
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const stable_vector& x, const stable_vector& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const stable_vector& x, const stable_vector& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const stable_vector& x, const stable_vector& y)
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const stable_vector& x, const stable_vector& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const stable_vector& x, const stable_vector& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(stable_vector& x, stable_vector& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
|
||||
class insert_rollback
|
||||
@@ -1836,58 +1880,14 @@ class stable_vector
|
||||
const node_allocator_type &priv_node_alloc() const { return internal_data; }
|
||||
|
||||
index_type index;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
template <typename T,typename Allocator>
|
||||
bool operator==(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
|
||||
{
|
||||
return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
|
||||
}
|
||||
|
||||
template <typename T,typename Allocator>
|
||||
bool operator< (const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
|
||||
{
|
||||
return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
|
||||
}
|
||||
|
||||
template <typename T,typename Allocator>
|
||||
bool operator!=(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
|
||||
{
|
||||
return !(x==y);
|
||||
}
|
||||
|
||||
template <typename T,typename Allocator>
|
||||
bool operator> (const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
|
||||
{
|
||||
return y<x;
|
||||
}
|
||||
|
||||
template <typename T,typename Allocator>
|
||||
bool operator>=(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
|
||||
{
|
||||
return !(x<y);
|
||||
}
|
||||
|
||||
template <typename T,typename Allocator>
|
||||
bool operator<=(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
|
||||
{
|
||||
return !(x>y);
|
||||
}
|
||||
|
||||
// specialized algorithms:
|
||||
|
||||
template <typename T, typename Allocator>
|
||||
void swap(stable_vector<T,Allocator>& x,stable_vector<T,Allocator>& y)
|
||||
{
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#undef STABLE_VECTOR_CHECK_INVARIANT
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
/*
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
namespace boost { namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
template<class T, std::size_t N>
|
||||
@@ -61,46 +63,46 @@ class static_storage_allocator
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
/**
|
||||
* @defgroup static_vector_non_member static_vector non-member functions
|
||||
*/
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
/**
|
||||
* @brief A variable-size array container with fixed capacity.
|
||||
*
|
||||
* static_vector is a sequence container like boost::container::vector with contiguous storage that can
|
||||
* change in size, along with the static allocation, low overhead, and fixed capacity of boost::array.
|
||||
*
|
||||
* A static_vector is a sequence that supports random access to elements, constant time insertion and
|
||||
* removal of elements at the end, and linear time insertion and removal of elements at the beginning or
|
||||
* in the middle. The number of elements in a static_vector may vary dynamically up to a fixed capacity
|
||||
* because elements are stored within the object itself similarly to an array. However, objects are
|
||||
* initialized as they are inserted into static_vector unlike C arrays or std::array which must construct
|
||||
* all elements on instantiation. The behavior of static_vector enables the use of statically allocated
|
||||
* elements in cases with complex object lifetime requirements that would otherwise not be trivially
|
||||
* possible.
|
||||
*
|
||||
* @par Error Handling
|
||||
* Insertion beyond the capacity result in throwing std::bad_alloc() if exceptions are enabled or
|
||||
* calling throw_bad_alloc() if not enabled.
|
||||
*
|
||||
* std::out_of_range is thrown if out of bound access is performed in `at()` if exceptions are
|
||||
* enabled, throw_out_of_range() if not enabled.
|
||||
*
|
||||
* @tparam Value The type of element that will be stored.
|
||||
* @tparam Capacity The maximum number of elements static_vector can store, fixed at compile time.
|
||||
*/
|
||||
//!
|
||||
//!@brief A variable-size array container with fixed capacity.
|
||||
//!
|
||||
//!static_vector is a sequence container like boost::container::vector with contiguous storage that can
|
||||
//!change in size, along with the static allocation, low overhead, and fixed capacity of boost::array.
|
||||
//!
|
||||
//!A static_vector is a sequence that supports random access to elements, constant time insertion and
|
||||
//!removal of elements at the end, and linear time insertion and removal of elements at the beginning or
|
||||
//!in the middle. The number of elements in a static_vector may vary dynamically up to a fixed capacity
|
||||
//!because elements are stored within the object itself similarly to an array. However, objects are
|
||||
//!initialized as they are inserted into static_vector unlike C arrays or std::array which must construct
|
||||
//!all elements on instantiation. The behavior of static_vector enables the use of statically allocated
|
||||
//!elements in cases with complex object lifetime requirements that would otherwise not be trivially
|
||||
//!possible.
|
||||
//!
|
||||
//!@par Error Handling
|
||||
//! Insertion beyond the capacity result in throwing std::bad_alloc() if exceptions are enabled or
|
||||
//! calling throw_bad_alloc() if not enabled.
|
||||
//!
|
||||
//! std::out_of_range is thrown if out of bound access is performed in <code>at()</code> if exceptions are
|
||||
//! enabled, throw_out_of_range() if not enabled.
|
||||
//!
|
||||
//!@tparam Value The type of element that will be stored.
|
||||
//!@tparam Capacity The maximum number of elements static_vector can store, fixed at compile time.
|
||||
template <typename Value, std::size_t Capacity>
|
||||
class static_vector
|
||||
: public vector<Value, container_detail::static_storage_allocator<Value, Capacity> >
|
||||
{
|
||||
typedef vector<Value, container_detail::static_storage_allocator<Value, Capacity> > base_t;
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef vector<Value, container_detail::static_storage_allocator<Value, Capacity> > base_t;
|
||||
|
||||
BOOST_COPYABLE_AND_MOVABLE(static_vector)
|
||||
BOOST_COPYABLE_AND_MOVABLE(static_vector)
|
||||
|
||||
template<class U, std::size_t OtherCapacity>
|
||||
friend class static_vector;
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//! @brief The type of elements stored in the container.
|
||||
typedef typename base_t::value_type value_type;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -52,7 +52,7 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
namespace container_detail {
|
||||
// ------------------------------------------------------------
|
||||
// Class basic_string_base.
|
||||
@@ -268,7 +268,12 @@ class basic_string_base
|
||||
}
|
||||
|
||||
size_type next_capacity(size_type additional_objects) const
|
||||
{ return get_next_capacity(allocator_traits_type::max_size(this->alloc()), this->priv_storage(), additional_objects); }
|
||||
{
|
||||
return next_capacity_calculator
|
||||
<size_type, NextCapacityDouble /*NextCapacity60Percent*/>::
|
||||
get( allocator_traits_type::max_size(this->alloc())
|
||||
, this->priv_storage(), additional_objects );
|
||||
}
|
||||
|
||||
void deallocate(pointer p, size_type n)
|
||||
{
|
||||
@@ -433,7 +438,7 @@ class basic_string_base
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! The basic_string class represents a Sequence of characters. It contains all the
|
||||
//! usual operations of a Sequence, and, additionally, it contains standard string
|
||||
@@ -463,6 +468,10 @@ class basic_string_base
|
||||
//! end(), rbegin(), rend(), operator[], c_str(), and data() do not invalidate iterators.
|
||||
//! In this implementation, iterators are only invalidated by member functions that
|
||||
//! explicitly change the string's contents.
|
||||
//!
|
||||
//! \tparam CharT The type of character it contains.
|
||||
//! \tparam Traits The Character Traits type, which encapsulates basic character operations
|
||||
//! \tparam Allocator The allocator, used for internal memory management.
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT> >
|
||||
#else
|
||||
@@ -471,7 +480,7 @@ template <class CharT, class Traits, class Allocator>
|
||||
class basic_string
|
||||
: private container_detail::basic_string_base<Allocator>
|
||||
{
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||
BOOST_COPYABLE_AND_MOVABLE(basic_string)
|
||||
@@ -483,19 +492,22 @@ class basic_string
|
||||
|
||||
template <class Tr>
|
||||
struct Eq_traits
|
||||
: public std::binary_function<typename Tr::char_type,
|
||||
typename Tr::char_type,
|
||||
bool>
|
||||
{
|
||||
bool operator()(const typename Tr::char_type& x,
|
||||
const typename Tr::char_type& y) const
|
||||
//Compatibility with std::binary_function
|
||||
typedef typename Tr::char_type first_argument_type;
|
||||
typedef typename Tr::char_type second_argument_type;
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator()(const first_argument_type& x, const second_argument_type& y) const
|
||||
{ return Tr::eq(x, y); }
|
||||
};
|
||||
|
||||
template <class Tr>
|
||||
struct Not_within_traits
|
||||
: public std::unary_function<typename Tr::char_type, bool>
|
||||
{
|
||||
typedef typename Tr::char_type argument_type;
|
||||
typedef bool result_type;
|
||||
|
||||
typedef const typename Tr::char_type* Pointer;
|
||||
const Pointer m_first;
|
||||
const Pointer m_last;
|
||||
@@ -509,7 +521,7 @@ class basic_string
|
||||
std::bind1st(Eq_traits<Tr>(), x)) == m_last;
|
||||
}
|
||||
};
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////
|
||||
@@ -533,14 +545,14 @@ class basic_string
|
||||
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
|
||||
static const size_type npos = size_type(-1);
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
typedef constant_iterator<CharT, difference_type> cvalue_iterator;
|
||||
typedef typename base_t::allocator_v1 allocator_v1;
|
||||
typedef typename base_t::allocator_v2 allocator_v2;
|
||||
typedef typename base_t::alloc_version alloc_version;
|
||||
typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public: // Constructor, destructor, assignment.
|
||||
//////////////////////////////////////////////
|
||||
@@ -548,7 +560,7 @@ class basic_string
|
||||
// construct/copy/destroy
|
||||
//
|
||||
//////////////////////////////////////////////
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
struct reserve_t {};
|
||||
|
||||
basic_string(reserve_t, size_type n,
|
||||
@@ -559,7 +571,7 @@ class basic_string
|
||||
, n + 1)
|
||||
{ this->priv_terminate_string(); }
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Effects</b>: Default constructs a basic_string.
|
||||
//!
|
||||
@@ -668,6 +680,15 @@ class basic_string
|
||||
this->assign(n, c);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
|
||||
//! and is initialized by n default-initialized characters.
|
||||
basic_string(size_type n, default_init_t, const allocator_type& a = allocator_type())
|
||||
: base_t(a, n + 1)
|
||||
{
|
||||
this->priv_size(n);
|
||||
this->priv_terminate_string();
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
|
||||
//! and a range of iterators.
|
||||
template <class InputIterator>
|
||||
@@ -945,6 +966,26 @@ class basic_string
|
||||
void resize(size_type n)
|
||||
{ resize(n, CharT()); }
|
||||
|
||||
|
||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||
//! the size becomes n. New elements are uninitialized.
|
||||
//!
|
||||
//! <b>Throws</b>: If memory allocation throws
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension
|
||||
void resize(size_type n, default_init_t)
|
||||
{
|
||||
if (n <= this->size())
|
||||
this->erase(this->begin() + n, this->end());
|
||||
else{
|
||||
this->priv_reserve(n, false);
|
||||
this->priv_size(n);
|
||||
this->priv_terminate_string();
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Number of elements for which memory has been allocated.
|
||||
//! capacity() is always greater than or equal to size().
|
||||
//!
|
||||
@@ -961,29 +1002,7 @@ class basic_string
|
||||
//!
|
||||
//! <b>Throws</b>: If memory allocation allocation throws
|
||||
void reserve(size_type res_arg)
|
||||
{
|
||||
if (res_arg > this->max_size()){
|
||||
throw_length_error("basic_string::reserve max_size() exceeded");
|
||||
}
|
||||
|
||||
if (this->capacity() < res_arg){
|
||||
size_type n = container_detail::max_value(res_arg, this->size()) + 1;
|
||||
size_type new_cap = this->next_capacity(n);
|
||||
pointer new_start = this->allocation_command
|
||||
(allocate_new, n, new_cap, new_cap).first;
|
||||
size_type new_length = 0;
|
||||
|
||||
const pointer addr = this->priv_addr();
|
||||
new_length += priv_uninitialized_copy
|
||||
(addr, addr + this->priv_size(), new_start);
|
||||
this->priv_construct_null(new_start + new_length);
|
||||
this->deallocate_block();
|
||||
this->is_short(false);
|
||||
this->priv_long_addr(new_start);
|
||||
this->priv_long_size(new_length);
|
||||
this->priv_storage(new_cap);
|
||||
}
|
||||
}
|
||||
{ this->priv_reserve(res_arg); }
|
||||
|
||||
//! <b>Effects</b>: Tries to deallocate the excess of memory created
|
||||
//! with previous allocations. The size of the string is unchanged
|
||||
@@ -1228,6 +1247,20 @@ class basic_string
|
||||
basic_string& assign(size_type n, CharT c)
|
||||
{ return this->assign(cvalue_iterator(c, n), cvalue_iterator()); }
|
||||
|
||||
//! <b>Effects</b>: Equivalent to assign(basic_string(first, last)).
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
basic_string& assign(const CharT* first, const CharT* last)
|
||||
{
|
||||
size_type n = static_cast<size_type>(last - first);
|
||||
this->reserve(n);
|
||||
CharT* ptr = container_detail::to_raw_pointer(this->priv_addr());
|
||||
Traits::copy(ptr, first, n);
|
||||
this->priv_construct_null(ptr + n);
|
||||
this->priv_size(n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Equivalent to assign(basic_string(first, last)).
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
@@ -2296,8 +2329,35 @@ class basic_string
|
||||
int compare(size_type pos1, size_type n1, const CharT* s) const
|
||||
{ return this->compare(pos1, n1, s, Traits::length(s)); }
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
void priv_reserve(size_type res_arg, const bool null_terminate = true)
|
||||
{
|
||||
if (res_arg > this->max_size()){
|
||||
throw_length_error("basic_string::reserve max_size() exceeded");
|
||||
}
|
||||
|
||||
if (this->capacity() < res_arg){
|
||||
size_type n = container_detail::max_value(res_arg, this->size()) + 1;
|
||||
size_type new_cap = this->next_capacity(n);
|
||||
pointer new_start = this->allocation_command
|
||||
(allocate_new, n, new_cap, new_cap).first;
|
||||
size_type new_length = 0;
|
||||
|
||||
const pointer addr = this->priv_addr();
|
||||
new_length += priv_uninitialized_copy
|
||||
(addr, addr + this->priv_size(), new_start);
|
||||
if(null_terminate){
|
||||
this->priv_construct_null(new_start + new_length);
|
||||
}
|
||||
this->deallocate_block();
|
||||
this->is_short(false);
|
||||
this->priv_long_addr(new_start);
|
||||
this->priv_long_size(new_length);
|
||||
this->priv_storage(new_cap);
|
||||
}
|
||||
}
|
||||
|
||||
static int s_compare(const_pointer f1, const_pointer l1,
|
||||
const_pointer f2, const_pointer l2)
|
||||
{
|
||||
@@ -2431,9 +2491,11 @@ class basic_string
|
||||
return this->priv_replace(first, last, f, l, Category());
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//!Typedef for a basic_string of
|
||||
//!narrow characters
|
||||
typedef basic_string
|
||||
@@ -2450,6 +2512,8 @@ typedef basic_string
|
||||
,std::allocator<wchar_t> >
|
||||
wstring;
|
||||
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Non-member functions.
|
||||
|
||||
@@ -2663,7 +2727,7 @@ template <class CharT, class Traits, class Allocator>
|
||||
inline void swap(basic_string<CharT,Traits,Allocator>& x, basic_string<CharT,Traits,Allocator>& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
// I/O.
|
||||
namespace container_detail {
|
||||
|
||||
@@ -2683,7 +2747,7 @@ string_fill(std::basic_ostream<CharT, Traits>& os,
|
||||
}
|
||||
|
||||
} //namespace container_detail {
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template <class CharT, class Traits, class Allocator>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
@@ -2814,7 +2878,7 @@ inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, Allocator>
|
||||
|
||||
}}
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -2827,7 +2891,7 @@ struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, Al
|
||||
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
|
||||
@@ -76,26 +76,82 @@ namespace container {
|
||||
|
||||
#else //defined(BOOST_NO_EXCEPTIONS)
|
||||
|
||||
//! Exception callback called by Boost.Container when fails to allocate the requested storage space.
|
||||
//! <ul>
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::bad_alloc()</code> is thrown.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
||||
//! is NOT defined <code>BOOST_ASSERT(!"boost::container bad_alloc thrown")</code> is called
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
||||
//! </ul>
|
||||
inline void throw_bad_alloc()
|
||||
{
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to signal arguments out of range.
|
||||
//! <ul>
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::out_of_range(str)</code> is thrown.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str)</code> is called
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
||||
//! </ul>
|
||||
inline void throw_out_of_range(const char* str)
|
||||
{
|
||||
throw std::out_of_range(str);
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to signal errors resizing.
|
||||
//! <ul>
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::length_error(str)</code> is thrown.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container length_error thrown", str)</code> is called
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
||||
//! </ul>
|
||||
inline void throw_length_error(const char* str)
|
||||
{
|
||||
throw std::length_error(str);
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to report errors in the internal logical
|
||||
//! of the program, such as violation of logical preconditions or class invariants.
|
||||
//! <ul>
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::logic_error(str)</code> is thrown.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str)</code> is called
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
||||
//! </ul>
|
||||
inline void throw_logic_error(const char* str)
|
||||
{
|
||||
throw std::logic_error(str);
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to report errors that can only be detected during runtime.
|
||||
//! <ul>
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::runtime_error(str)</code> is thrown.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str)</code> is called
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
||||
//! </ul>
|
||||
inline void throw_runtime_error(const char* str)
|
||||
{
|
||||
throw std::runtime_error(str);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
<!--
|
||||
Copyright 2005-2012 Ion Gaztanaga
|
||||
Copyright 2005-2013 Ion Gaztanaga
|
||||
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)
|
||||
-->
|
||||
|
||||
@@ -60,4 +60,6 @@ Add hash for containers
|
||||
|
||||
Add std:: hashing support
|
||||
|
||||
Fix trivial destructor after move and other optimizing traits
|
||||
Fix trivial destructor after move and other optimizing traits
|
||||
|
||||
Implement n3586, "Splicing Maps and Sets" (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3586.pdf)
|
||||
|
||||
138
proj/vc7ide/alloc_basic_test.vcproj
Normal file
138
proj/vc7ide/alloc_basic_test.vcproj
Normal file
@@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="alloc_basic_test"
|
||||
ProjectGUID="{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/alloc_basic_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="BOOST_CONTAINER_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/alloc_basic_test_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/debug"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/alloc_basic_test.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/alloc_basic_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;BOOST_CONTAINER_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/alloc_basic_test.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/release"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{34957FC1-7BC5-1646-05A6-27542AA2A2FF}">
|
||||
<File
|
||||
RelativePath="..\..\test\alloc_basic_test.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93A78280-B78D-4B31-7E8B-6255ACE1E5FB}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
133
proj/vc7ide/alloc_full_test.vcproj
Normal file
133
proj/vc7ide/alloc_full_test.vcproj
Normal file
@@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="alloc_full_test"
|
||||
ProjectGUID="{CD57C283-1862-9FE5-BF87-BA91293A76D3}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/alloc_full_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="BOOST_CONTAINER_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/alloc_full_test_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/debug"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/alloc_full_test.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/alloc_full_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;BOOST_CONTAINER_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/alloc_full_test.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/release"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{3857F2C1-BC75-1646-05A6-2AF850A42A2E}">
|
||||
<File
|
||||
RelativePath="..\..\test\alloc_full_test.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
199
proj/vc7ide/alloc_lib.vcproj
Normal file
199
proj/vc7ide/alloc_lib.vcproj
Normal file
@@ -0,0 +1,199 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="_alloc_lib"
|
||||
ProjectGUID="{685AC59C-E667-4096-9DAA-AB76083C7092}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="..\..\Bin\Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\..\.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/alloc_lib.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="..\..\Bin\Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="..\..\..\.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/alloc_lib.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath="..\..\src\alloc_lib.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\adaptive_pool.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\allocator.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\node_allocator.hpp">
|
||||
</File>
|
||||
<Filter
|
||||
Name="detail"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\detail\adaptive_node_pool.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\detail\alloc_lib.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\detail\alloc_lib_auto_link.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\detail\auto_link.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\detail\mutex.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\detail\node_pool.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\detail\pool_common_alloc.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\detail\singleton.hpp">
|
||||
</File>
|
||||
<Filter
|
||||
Name="Included Sources"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\dlmalloc_2_8_6.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dlmalloc_ext_2_8_6.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="test"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\test\Jamfile.v2">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="doc"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\doc\Applying classic memory allocation improvements to C++ containers.html">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -20,7 +20,7 @@
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
GeneratePreprocessedFile="0"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
@@ -74,7 +74,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
@@ -128,14 +128,6 @@
|
||||
RelativePath="..\..\test\allocator_traits_test.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93815995-89BD-b043-5E8B-65FBE52E2AFB}">
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\detail\node_alloc_holder.hpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
|
||||
133
proj/vc7ide/bench_adaptive_node_pool.vcproj
Normal file
133
proj/vc7ide/bench_adaptive_node_pool.vcproj
Normal file
@@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="bench_adaptive_node_pool"
|
||||
ProjectGUID="{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/bench_adaptive_node_pool"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="BOOST_CONTAINER_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/bench_adaptive_node_pool_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/debug;../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/bench_adaptive_node_pool.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/bench_adaptive_node_pool"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;BOOST_CONTAINER_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/bench_adaptive_node_pool.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/release;../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{818563C3-6640-0A65-55CB-202E5BAD7FAF}">
|
||||
<File
|
||||
RelativePath="..\..\bench\bench_adaptive_node_pool.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
133
proj/vc7ide/bench_alloc.vcproj
Normal file
133
proj/vc7ide/bench_alloc.vcproj
Normal file
@@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="bench_alloc"
|
||||
ProjectGUID="{7CC83A22-8612-7BF8-2F4E-BD9493C6A071}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/bench_alloc"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="BOOST_CONTAINER_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/bench_alloc_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/debug;../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/bench_alloc.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/bench_alloc"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;BOOST_CONTAINER_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/bench_alloc.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/release;../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{D127F725-A615-C5B6-6640-27A2AE5757AF}">
|
||||
<File
|
||||
RelativePath="..\..\bench\bench_alloc.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
133
proj/vc7ide/bench_alloc_expand_bwd.vcproj
Normal file
133
proj/vc7ide/bench_alloc_expand_bwd.vcproj
Normal file
@@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="bench_alloc_expand_bwd"
|
||||
ProjectGUID="{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/bench_alloc_expand_bwd"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="BOOST_CONTAINER_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/bench_alloc_expand_bwd_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/debug;../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/bench_alloc_expand_bwd.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/bench_alloc_expand_bwd"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;BOOST_CONTAINER_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/bench_alloc_expand_bwd.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/release;../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{D1217F85-BC56-6640-05A6-247AF7A2A58F}">
|
||||
<File
|
||||
RelativePath="..\..\bench\bench_alloc_expand_bwd.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
133
proj/vc7ide/bench_alloc_expand_fwd.vcproj
Normal file
133
proj/vc7ide/bench_alloc_expand_fwd.vcproj
Normal file
@@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="bench_alloc_expand_fwd"
|
||||
ProjectGUID="{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/bench_alloc_expand_fwd"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="BOOST_CONTAINER_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/bench_alloc_expand_fwd_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/debug;../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/bench_alloc_expand_fwd.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/bench_alloc_expand_fwd"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;BOOST_CONTAINER_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/bench_alloc_expand_fwd.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/release;../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{D1217F85-BC56-6640-05A6-247AF7A2A58F}">
|
||||
<File
|
||||
RelativePath="..\..\bench\bench_alloc_expand_fwd.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
133
proj/vc7ide/bench_alloc_shrink_to_fit.vcproj
Normal file
133
proj/vc7ide/bench_alloc_shrink_to_fit.vcproj
Normal file
@@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="bench_alloc_shrink_to_fit"
|
||||
ProjectGUID="{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/bench_alloc_shrink_to_fit"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="BOOST_CONTAINER_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/bench_alloc_shrink_to_fit_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/debug;../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/bench_alloc_shrink_to_fit.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/bench_alloc_shrink_to_fit"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;BOOST_CONTAINER_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/bench_alloc_shrink_to_fit.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/release;../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{D1217F85-BC56-6640-05A6-247AF7A2A58F}">
|
||||
<File
|
||||
RelativePath="..\..\bench\bench_alloc_shrink_to_fit.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
134
proj/vc7ide/bench_alloc_stable_vector_burst_allocation.vcproj
Normal file
134
proj/vc7ide/bench_alloc_stable_vector_burst_allocation.vcproj
Normal file
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="bench_alloc_stable_vector_burst_allocation"
|
||||
ProjectGUID="{C3AD2582-79BF-2FE1-8612-BD707552A6A1}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/bench_alloc_stable_vector_burst_allocation"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="BOOST_CONTAINER_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/bench_alloc_stable_vector_burst_allocation_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/debug;../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/bench_alloc_stable_vector_burst_allocation.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/bench_alloc_stable_vector_burst_allocation"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="1"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;BOOST_CONTAINER_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib alloc_lib.lib"
|
||||
OutputFile="$(OutDir)/bench_alloc_stable_vector_burst_allocation.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../bin/release;../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{D80184F5-6450-3A65-55CB-2375A7BCDAEF}">
|
||||
<File
|
||||
RelativePath="..\..\bench\bench_alloc_stable_vector_burst_allocation.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
134
proj/vc7ide/bench_flat_multiset.vcproj
Normal file
134
proj/vc7ide/bench_flat_multiset.vcproj
Normal file
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="bench_flat_multiset"
|
||||
ProjectGUID="{E5C01323-3F2C-D074-F4A9-D16B31CC275B}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/bench_flat_multiset"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
ExceptionHandling="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/bench_flat_multiset_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/bench_flat_multiset.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/bench_flat_multiset"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/bench_flat_multiset.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{CF7232AE-72A6-3417-8ABF-5418BA30DA7A}">
|
||||
<File
|
||||
RelativePath="..\..\bench\bench_flat_multiset.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user