mirror of
https://github.com/boostorg/container.git
synced 2025-08-03 14:34:27 +02:00
Default initialization for vector-like containers
Complexity guarantees for associative container constructors and ordered input ranges Fix for #9166 Added benchmark for associative containers Removed check for old MSVC compilers and #pragma once. [SVN r85970]
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 /boost/system//boost_system /boost/thread//boost_thread
|
||||
all_rules += [ run $(fileb) /boost/timer//boost_timer
|
||||
: # additional args
|
||||
: # test-files
|
||||
: # requirements
|
||||
|
348
bench/bench_set.cpp
Normal file
348
bench/bench_set.cpp
Normal file
@@ -0,0 +1,348 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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 <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();
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
//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;
|
||||
}
|
@@ -20,7 +20,6 @@
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <boost/timer/timer.hpp>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_VARRAY_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_VARRAY_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if (defined _MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -293,7 +293,7 @@ public:
|
||||
|
||||
//! @pre <tt>count <= capacity()</tt>
|
||||
//!
|
||||
//! @brief Constructs a varray containing count default constructed Values.
|
||||
//! @brief Constructs a varray containing count value initialized Values.
|
||||
//!
|
||||
//! @param count The number of values which will be contained in the container.
|
||||
//!
|
||||
@@ -616,7 +616,7 @@ public:
|
||||
//! @pre <tt>count <= capacity()</tt>
|
||||
//!
|
||||
//! @brief Inserts or erases elements at the end such that
|
||||
//! the size becomes count. New elements are default constructed.
|
||||
//! the size becomes count. New elements are value initialized.
|
||||
//!
|
||||
//! @param count The number of elements which will be stored in the container.
|
||||
//!
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#ifndef BOOST_CONTAINER_VARRAY_HPP
|
||||
#define BOOST_CONTAINER_VARRAY_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if (defined _MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
|
||||
//! @pre <tt>count <= capacity()</tt>
|
||||
//!
|
||||
//! @brief Constructs a varray containing count default constructed Values.
|
||||
//! @brief Constructs a varray containing count value initialized Values.
|
||||
//!
|
||||
//! @param count The number of values which will be contained in the container.
|
||||
//!
|
||||
@@ -311,7 +311,7 @@ public:
|
||||
//! @pre <tt>count <= capacity()</tt>
|
||||
//!
|
||||
//! @brief Inserts or erases elements at the end such that
|
||||
//! the size becomes count. New elements are default constructed.
|
||||
//! the size becomes count. New elements are value initialized.
|
||||
//!
|
||||
//! @param count The number of elements which will be stored in the container.
|
||||
//!
|
||||
|
@@ -502,6 +502,52 @@ are a particular case where `static_vector` can be beneficial.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:extended_functionality Extended functionality]
|
||||
|
||||
[section:default_initialialization Default initialization for vector-like containers]
|
||||
|
||||
STL and most other containers value initialize new elements in common operations like
|
||||
`vector::resize(size_type n)` or `explicit vector::vector(size_type n)`.
|
||||
|
||||
In some performance-sensitive environments, where vectors are used as a replacement for
|
||||
variable-size buffers for file or network operations,
|
||||
[@http://en.cppreference.com/w/cpp/language/value_initialization value initialization]
|
||||
is a cost that is not negligible as elements are going to be overwritten by an external source
|
||||
shortly after new elements are added to the container.
|
||||
|
||||
[*Boost.Container] offers two new members for `vector`, `static_vector` and `stable_vector`:
|
||||
`explicit container::container(size_type n, default_init_t)` and
|
||||
`explicit container::resize(size_type n, default_init_t)`, where new elements are constructed
|
||||
using [@http://en.cppreference.com/w/cpp/language/default_initialization default initialization].
|
||||
|
||||
[endsect]
|
||||
|
||||
[/
|
||||
/a__section:get_stored_allocator Obtain stored allocator__a
|
||||
/
|
||||
/STL containers offer a `get_allocator()` member to obtain a copy of the allocator that
|
||||
/the container is using to allocate and construct elements. For performance reasons, some
|
||||
/applications need o
|
||||
/
|
||||
/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]
|
||||
|
||||
[section:Cpp11_conformance C++11 Conformance]
|
||||
|
||||
[*Boost.Container] aims for full C++11 conformance except reasoned deviations,
|
||||
|
@@ -17,12 +17,13 @@
|
||||
#ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
|
||||
#define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/intrusive/detail/memory_util.hpp>
|
||||
#include <boost/container/detail/memory_util.hpp>
|
||||
@@ -387,6 +388,10 @@ struct allocator_traits
|
||||
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template<class T>
|
||||
static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p, ::boost::container::default_init_t)
|
||||
{ ::new((void*)p) T; }
|
||||
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
///@endcond
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP
|
||||
#define BOOST_CONTAINER_CONTAINER_FWD_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -135,20 +135,28 @@ class basic_string;
|
||||
struct ordered_range_t
|
||||
{};
|
||||
|
||||
//! Value used to tag that the input range is
|
||||
//! guaranteed to be ordered
|
||||
static const ordered_range_t ordered_range = ordered_range_t();
|
||||
|
||||
//! Type used to tag that the input range is
|
||||
//! guaranteed to be ordered and unique
|
||||
struct ordered_unique_range_t
|
||||
: public ordered_range_t
|
||||
{};
|
||||
|
||||
//! Value used to tag that the input range is
|
||||
//! guaranteed to be ordered
|
||||
static const ordered_range_t ordered_range = ordered_range_t();
|
||||
|
||||
//! Value used to tag that the input range is
|
||||
//! 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
|
||||
struct default_init_t
|
||||
{};
|
||||
|
||||
//! Value used to tag that the input range is
|
||||
//! guaranteed to be ordered and unique
|
||||
static const default_init_t default_init = default_init_t();
|
||||
/// @cond
|
||||
|
||||
namespace detail_really_deep_namespace {
|
||||
@@ -161,6 +169,7 @@ struct dummy
|
||||
{
|
||||
(void)ordered_range;
|
||||
(void)ordered_unique_range;
|
||||
(void)default_init;
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_DEQUE_HPP
|
||||
#define BOOST_CONTAINER_DEQUE_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -540,7 +540,7 @@ class deque : protected deque_base<Allocator>
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
|
||||
//! and inserts n default contructed values.
|
||||
//! and inserts n value initialized values.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
||||
//! throws or T's default or copy constructor throws.
|
||||
@@ -549,7 +549,24 @@ class deque : protected deque_base<Allocator>
|
||||
explicit deque(size_type n)
|
||||
: Base(n, allocator_type())
|
||||
{
|
||||
container_detail::insert_default_constructed_n_proxy<Allocator, iterator> proxy(this->alloc());
|
||||
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
|
||||
proxy.uninitialized_copy_n_and_update(this->begin(), n);
|
||||
//deque_base will deallocate in case of exception...
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
|
||||
//! and inserts n default initialized values.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
||||
//! throws or T's default or copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to n.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension
|
||||
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);
|
||||
//deque_base will deallocate in case of exception...
|
||||
}
|
||||
@@ -949,9 +966,9 @@ class deque : protected deque_base<Allocator>
|
||||
{ return allocator_traits_type::max_size(this->alloc()); }
|
||||
|
||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||
//! the size becomes n. New elements are default constructed.
|
||||
//! the size becomes n. New elements are value initialized.
|
||||
//!
|
||||
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
|
||||
//! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
||||
void resize(size_type new_size)
|
||||
@@ -961,7 +978,27 @@ 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_constructed_n_proxy<Allocator, iterator> proxy(this->alloc());
|
||||
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
|
||||
priv_insert_back_aux_impl(n, proxy);
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||
//! the size becomes n. New elements are default initialized.
|
||||
//!
|
||||
//! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension
|
||||
void resize(size_type new_size, default_init_t)
|
||||
{
|
||||
const size_type len = size();
|
||||
if (new_size < len)
|
||||
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());
|
||||
priv_insert_back_aux_impl(n, proxy);
|
||||
}
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
|
||||
#define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -99,19 +99,43 @@ struct insert_n_copies_proxy
|
||||
};
|
||||
|
||||
template<class A, class Iterator>
|
||||
struct insert_default_constructed_n_proxy
|
||||
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;
|
||||
|
||||
|
||||
explicit insert_default_constructed_n_proxy(A &a)
|
||||
explicit insert_value_initialized_n_proxy(A &a)
|
||||
: a_(a)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
|
||||
{ boost::container::uninitialized_default_alloc_n(this->a_, n, p); }
|
||||
{ boost::container::uninitialized_value_init_alloc_n(this->a_, n, p); }
|
||||
|
||||
void copy_n_and_update(Iterator, size_type) const
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
}
|
||||
|
||||
private:
|
||||
A &a_;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
|
||||
explicit insert_default_initialized_n_proxy(A &a)
|
||||
: a_(a)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
|
||||
{ boost::container::uninitialized_default_init_alloc_n(this->a_, n, p); }
|
||||
|
||||
void copy_n_and_update(Iterator, size_type) const
|
||||
{
|
||||
|
@@ -13,7 +13,7 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -35,13 +35,13 @@ namespace boost {
|
||||
namespace container {
|
||||
|
||||
template<class It>
|
||||
struct is_default_construct_iterator
|
||||
struct is_value_init_construct_iterator
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class U, class D>
|
||||
struct is_default_construct_iterator<default_construct_iterator<U, D> >
|
||||
struct is_value_init_construct_iterator<value_init_construct_iterator<U, D> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
@@ -64,11 +64,17 @@ inline void construct_in_place(A &a, T* dest, InpIt source)
|
||||
//#endif
|
||||
|
||||
template<class A, class T, class U, class D>
|
||||
inline void construct_in_place(A &a, T *dest, default_construct_iterator<U, D>)
|
||||
inline void construct_in_place(A &a, T *dest, value_init_construct_iterator<U, D>)
|
||||
{
|
||||
boost::container::allocator_traits<A>::construct(a, dest);
|
||||
}
|
||||
|
||||
template<class A, class T, class U, class D>
|
||||
inline void construct_in_place(A &a, T *dest, default_init_construct_iterator<U, D>)
|
||||
{
|
||||
boost::container::allocator_traits<A>::construct(a, dest, default_init);
|
||||
}
|
||||
|
||||
template<class A, class T, class U, class EF, class D>
|
||||
inline void construct_in_place(A &a, T *dest, emplace_iterator<U, EF, D> ei)
|
||||
{
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_ALLOCATION_TYPE_HPP
|
||||
#define BOOST_CONTAINER_ALLOCATION_TYPE_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -92,8 +92,12 @@ struct allocator_version_traits<Allocator, 1>
|
||||
|
||||
static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
|
||||
{
|
||||
while(!holder.empty()){
|
||||
a.deallocate(holder.pop_front(), 1);
|
||||
size_type n = holder.size();
|
||||
typename multiallocation_chain::iterator it = holder.begin();
|
||||
while(n--){
|
||||
pointer p = boost::intrusive::pointer_traits<pointer>::pointer_to(*it);
|
||||
++it;
|
||||
a.deallocate(p, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -46,4 +46,5 @@
|
||||
#pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
|
||||
#pragma warning (disable : 4671) // the copy constructor is inaccessible
|
||||
#pragma warning (disable : 4584) // X is already a base-class of Y
|
||||
#pragma warning (disable : 4510) // default constructor could not be generated
|
||||
#endif //BOOST_MSVC
|
||||
|
@@ -13,7 +13,7 @@
|
||||
#ifndef BOOST_CONTAINER_DESTROYERS_HPP
|
||||
#define BOOST_CONTAINER_DESTROYERS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -68,6 +68,9 @@ struct scoped_deallocator
|
||||
pointer get() const
|
||||
{ return m_ptr; }
|
||||
|
||||
void set(const pointer &p)
|
||||
{ m_ptr = p; }
|
||||
|
||||
void release()
|
||||
{ m_ptr = 0; }
|
||||
};
|
||||
@@ -87,6 +90,9 @@ struct null_scoped_deallocator
|
||||
|
||||
pointer get() const
|
||||
{ return pointer(); }
|
||||
|
||||
void set(const pointer &)
|
||||
{}
|
||||
};
|
||||
|
||||
//!A deleter for scoped_ptr that deallocates the memory
|
||||
@@ -249,6 +255,11 @@ class scoped_destructor
|
||||
void release()
|
||||
{ pv_ = 0; }
|
||||
|
||||
|
||||
void set(value_type *ptr) { pv_ = ptr; }
|
||||
|
||||
value_type *get() const { return pv_; }
|
||||
|
||||
private:
|
||||
value_type *pv_;
|
||||
A &a_;
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_FLAT_TREE_HPP
|
||||
#define BOOST_CONTAINER_FLAT_TREE_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -240,11 +240,19 @@ class flat_tree
|
||||
, const allocator_type& a = allocator_type())
|
||||
: m_data(comp, a)
|
||||
{
|
||||
//Use cend() as hint to achieve linear time for
|
||||
//ordered ranges as required by the standard
|
||||
//for the constructor
|
||||
//Call end() every iteration as reallocation might have invalidated iterators
|
||||
if(unique_insertion){
|
||||
this->insert_unique(first, last);
|
||||
for ( ; first != last; ++first){
|
||||
this->insert_unique(this->cend(), *first);
|
||||
}
|
||||
}
|
||||
else{
|
||||
this->insert_equal(first, last);
|
||||
for ( ; first != last; ++first){
|
||||
this->insert_equal(this->cend(), *first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,7 +397,11 @@ class flat_tree
|
||||
|
||||
template <class InIt>
|
||||
void insert_unique(InIt first, InIt last)
|
||||
{ this->priv_insert_unique_loop(first, last); }
|
||||
{
|
||||
for ( ; first != last; ++first){
|
||||
this->insert_unique(*first);
|
||||
}
|
||||
}
|
||||
|
||||
template <class InIt>
|
||||
void insert_equal(InIt first, InIt last
|
||||
@@ -487,7 +499,13 @@ class flat_tree
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{ this->priv_insert_unique_loop_hint(first, last); }
|
||||
{
|
||||
const_iterator pos(this->cend());
|
||||
for ( ; first != last; ++first){
|
||||
pos = this->insert_unique(pos, *first);
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
||||
template <class BidirIt>
|
||||
void insert_unique(ordered_unique_range_t, BidirIt first, BidirIt last
|
||||
@@ -677,22 +695,21 @@ class flat_tree
|
||||
// set operations:
|
||||
iterator find(const key_type& k)
|
||||
{
|
||||
const Compare &key_cmp = this->m_data.get_comp();
|
||||
iterator i = this->lower_bound(k);
|
||||
|
||||
if (i != this->end() && key_cmp(k, KeyOfValue()(*i))){
|
||||
i = this->end();
|
||||
iterator end_it = this->end();
|
||||
if (i != end_it && this->m_data.get_comp()(k, KeyOfValue()(*i))){
|
||||
i = end_it;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
const_iterator find(const key_type& k) const
|
||||
{
|
||||
const Compare &key_cmp = this->m_data.get_comp();
|
||||
const_iterator i = this->lower_bound(k);
|
||||
|
||||
if (i != this->end() && key_cmp(k, KeyOfValue()(*i))){
|
||||
i = this->end();
|
||||
const_iterator end_it = this->cend();
|
||||
if (i != end_it && this->m_data.get_comp()(k, KeyOfValue()(*i))){
|
||||
i = end_it;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
@@ -708,19 +725,19 @@ class flat_tree
|
||||
{ return this->priv_lower_bound(this->begin(), this->end(), k); }
|
||||
|
||||
const_iterator lower_bound(const key_type& k) const
|
||||
{ return this->priv_lower_bound(this->begin(), this->end(), k); }
|
||||
{ return this->priv_lower_bound(this->cbegin(), this->cend(), k); }
|
||||
|
||||
iterator upper_bound(const key_type& k)
|
||||
{ return this->priv_upper_bound(this->begin(), this->end(), k); }
|
||||
|
||||
const_iterator upper_bound(const key_type& k) const
|
||||
{ return this->priv_upper_bound(this->begin(), this->end(), k); }
|
||||
{ return this->priv_upper_bound(this->cbegin(), this->cend(), k); }
|
||||
|
||||
std::pair<iterator,iterator> equal_range(const key_type& k)
|
||||
{ return this->priv_equal_range(this->begin(), this->end(), k); }
|
||||
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
|
||||
{ return this->priv_equal_range(this->begin(), this->end(), k); }
|
||||
{ return this->priv_equal_range(this->cbegin(), this->cend(), k); }
|
||||
|
||||
size_type capacity() const
|
||||
{ return this->m_data.m_vect.capacity(); }
|
||||
@@ -817,7 +834,6 @@ class flat_tree
|
||||
//in the remaining range [pos, end)
|
||||
return this->priv_insert_unique_prepare(pos, cend_it, val, commit_data);
|
||||
}
|
||||
//return priv_insert_unique_prepare(val, commit_data);
|
||||
}
|
||||
|
||||
template<class Convertible>
|
||||
@@ -835,11 +851,11 @@ class flat_tree
|
||||
{
|
||||
const Compare &key_cmp = this->m_data.get_comp();
|
||||
KeyOfValue key_extract;
|
||||
difference_type len = last - first, half;
|
||||
size_type len = static_cast<size_type>(last - first);
|
||||
RanIt middle;
|
||||
|
||||
while (len > 0) {
|
||||
half = len >> 1;
|
||||
while (len) {
|
||||
size_type half = len >> 1;
|
||||
middle = first;
|
||||
middle += half;
|
||||
|
||||
@@ -854,17 +870,18 @@ class flat_tree
|
||||
return first;
|
||||
}
|
||||
|
||||
|
||||
template <class RanIt>
|
||||
RanIt priv_upper_bound(RanIt first, RanIt last,
|
||||
const key_type & key) const
|
||||
{
|
||||
const Compare &key_cmp = this->m_data.get_comp();
|
||||
KeyOfValue key_extract;
|
||||
difference_type len = last - first, half;
|
||||
size_type len = static_cast<size_type>(last - first);
|
||||
RanIt middle;
|
||||
|
||||
while (len > 0) {
|
||||
half = len >> 1;
|
||||
while (len) {
|
||||
size_type half = len >> 1;
|
||||
middle = first;
|
||||
middle += half;
|
||||
|
||||
@@ -885,11 +902,11 @@ class flat_tree
|
||||
{
|
||||
const Compare &key_cmp = this->m_data.get_comp();
|
||||
KeyOfValue key_extract;
|
||||
difference_type len = last - first, half;
|
||||
RanIt middle, left, right;
|
||||
size_type len = static_cast<size_type>(last - first);
|
||||
RanIt middle;
|
||||
|
||||
while (len > 0) {
|
||||
half = len >> 1;
|
||||
while (len) {
|
||||
size_type half = len >> 1;
|
||||
middle = first;
|
||||
middle += half;
|
||||
|
||||
@@ -902,10 +919,11 @@ class flat_tree
|
||||
len = half;
|
||||
}
|
||||
else {
|
||||
left = this->priv_lower_bound(first, middle, key);
|
||||
first += len;
|
||||
right = this->priv_upper_bound(++middle, first, key);
|
||||
return std::pair<RanIt, RanIt>(left, right);
|
||||
//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>(first, first);
|
||||
@@ -924,24 +942,10 @@ class flat_tree
|
||||
{
|
||||
const_iterator pos(this->cend());
|
||||
for ( ; first != last; ++first){
|
||||
//If ordered, then try hint version
|
||||
//to achieve constant-time complexity per insertion
|
||||
pos = this->insert_equal(pos, *first);
|
||||
}
|
||||
}
|
||||
|
||||
template<class InIt>
|
||||
void priv_insert_unique_loop(InIt first, InIt last)
|
||||
{
|
||||
for ( ; first != last; ++first){
|
||||
this->insert_unique(*first);
|
||||
}
|
||||
}
|
||||
|
||||
template<class InIt>
|
||||
void priv_insert_unique_loop_ordered(InIt first, InIt last)
|
||||
{
|
||||
const_iterator pos(this->cend());
|
||||
for ( ; first != last; ++first){
|
||||
pos = this->insert_unique(pos, *first);
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -14,7 +14,7 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -148,79 +148,79 @@ class constant_iterator
|
||||
};
|
||||
|
||||
template <class T, class Difference = std::ptrdiff_t>
|
||||
class default_construct_iterator
|
||||
class value_init_construct_iterator
|
||||
: public std::iterator
|
||||
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
|
||||
{
|
||||
typedef default_construct_iterator<T, Difference> this_type;
|
||||
typedef value_init_construct_iterator<T, Difference> this_type;
|
||||
|
||||
public:
|
||||
explicit default_construct_iterator(Difference range_size)
|
||||
explicit value_init_construct_iterator(Difference range_size)
|
||||
: m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
default_construct_iterator()
|
||||
value_init_construct_iterator()
|
||||
: m_num(0){}
|
||||
|
||||
default_construct_iterator& operator++()
|
||||
value_init_construct_iterator& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
default_construct_iterator operator++(int)
|
||||
value_init_construct_iterator operator++(int)
|
||||
{
|
||||
default_construct_iterator result (*this);
|
||||
value_init_construct_iterator result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
default_construct_iterator& operator--()
|
||||
value_init_construct_iterator& operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
default_construct_iterator operator--(int)
|
||||
value_init_construct_iterator operator--(int)
|
||||
{
|
||||
default_construct_iterator result (*this);
|
||||
value_init_construct_iterator result (*this);
|
||||
decrement();
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2)
|
||||
friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2)
|
||||
friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2)
|
||||
friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return i.less(i2); }
|
||||
|
||||
friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2)
|
||||
friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2)
|
||||
friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2)
|
||||
friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2)
|
||||
friend Difference operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
default_construct_iterator& operator+=(Difference off)
|
||||
value_init_construct_iterator& operator+=(Difference off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
default_construct_iterator operator+(Difference off) const
|
||||
value_init_construct_iterator operator+(Difference off) const
|
||||
{
|
||||
default_construct_iterator other(*this);
|
||||
value_init_construct_iterator other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right)
|
||||
friend value_init_construct_iterator operator+(Difference off, const value_init_construct_iterator& right)
|
||||
{ return right + off; }
|
||||
|
||||
default_construct_iterator& operator-=(Difference off)
|
||||
value_init_construct_iterator& operator-=(Difference off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
default_construct_iterator operator-(Difference off) const
|
||||
value_init_construct_iterator operator-(Difference off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
//This pseudo-iterator's dereference operations have no sense since value is not
|
||||
@@ -258,6 +258,118 @@ class default_construct_iterator
|
||||
{ return m_num - other.m_num; }
|
||||
};
|
||||
|
||||
template <class T, class Difference = std::ptrdiff_t>
|
||||
class default_init_construct_iterator
|
||||
: public std::iterator
|
||||
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
|
||||
{
|
||||
typedef default_init_construct_iterator<T, Difference> this_type;
|
||||
|
||||
public:
|
||||
explicit default_init_construct_iterator(Difference range_size)
|
||||
: m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
default_init_construct_iterator()
|
||||
: m_num(0){}
|
||||
|
||||
default_init_construct_iterator& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
default_init_construct_iterator operator++(int)
|
||||
{
|
||||
default_init_construct_iterator result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
default_init_construct_iterator& operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
default_init_construct_iterator operator--(int)
|
||||
{
|
||||
default_init_construct_iterator result (*this);
|
||||
decrement();
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return i.less(i2); }
|
||||
|
||||
friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
friend Difference operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
default_init_construct_iterator& operator+=(Difference off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
default_init_construct_iterator operator+(Difference off) const
|
||||
{
|
||||
default_init_construct_iterator other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
friend default_init_construct_iterator operator+(Difference off, const default_init_construct_iterator& right)
|
||||
{ return right + off; }
|
||||
|
||||
default_init_construct_iterator& operator-=(Difference off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
default_init_construct_iterator operator-(Difference off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
//This pseudo-iterator's dereference operations have no sense since value is not
|
||||
//constructed until ::boost::container::construct_in_place is called.
|
||||
//So comment them to catch bad uses
|
||||
//const T& operator*() const;
|
||||
//const T& operator[](difference_type) const;
|
||||
//const T* operator->() const;
|
||||
|
||||
private:
|
||||
Difference m_num;
|
||||
|
||||
void increment()
|
||||
{ --m_num; }
|
||||
|
||||
void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
bool less(const this_type &other) const
|
||||
{ return other.m_num < m_num; }
|
||||
|
||||
const T & dereference() const
|
||||
{
|
||||
static T dummy;
|
||||
return dummy;
|
||||
}
|
||||
|
||||
void advance(Difference n)
|
||||
{ m_num -= n; }
|
||||
|
||||
Difference distance_to(const this_type &other)const
|
||||
{ return m_num - other.m_num; }
|
||||
};
|
||||
|
||||
|
||||
template <class T, class Difference = std::ptrdiff_t>
|
||||
class repeat_iterator
|
||||
: public std::iterator
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP
|
||||
#define BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
|
||||
#define BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -243,10 +243,10 @@ class transform_multiallocation_chain
|
||||
|
||||
iterator before_begin()
|
||||
{ return iterator(holder_.before_begin()); }
|
||||
|
||||
*/
|
||||
iterator begin()
|
||||
{ return iterator(holder_.begin()); }
|
||||
|
||||
{ return iterator(this->MultiallocationChain::begin()); }
|
||||
/*
|
||||
iterator end()
|
||||
{ return iterator(holder_.end()); }
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
|
||||
#define BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/utilities.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/allocator_version_traits.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/container/detail/allocator_version_traits.hpp>
|
||||
@@ -80,6 +81,7 @@ struct node_alloc_holder
|
||||
typedef typename allocator_traits_type::template
|
||||
portable_rebind_alloc<Node>::type NodeAlloc;
|
||||
typedef allocator_traits<NodeAlloc> node_allocator_traits_type;
|
||||
typedef container_detail::allocator_version_traits<NodeAlloc> node_allocator_version_traits_type;
|
||||
typedef A ValAlloc;
|
||||
typedef typename node_allocator_traits_type::pointer NodePtr;
|
||||
typedef container_detail::scoped_deallocator<NodeAlloc> Deallocator;
|
||||
@@ -233,45 +235,41 @@ struct node_alloc_holder
|
||||
(FwdIterator beg, difference_type n, Inserter inserter)
|
||||
{
|
||||
if(n){
|
||||
/*
|
||||
NodePtr p = this->allocate_one();
|
||||
Deallocator node_deallocator(p, this->node_alloc());
|
||||
::boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), it);
|
||||
node_deallocator.release();
|
||||
//This does not throw
|
||||
typedef typename Node::hook_type hook_type;
|
||||
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
|
||||
return (p);
|
||||
*/
|
||||
typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
|
||||
typedef typename node_allocator_version_traits_type::multiallocation_chain multiallocation_chain;
|
||||
|
||||
//Try to allocate memory in a single block
|
||||
typedef typename multiallocation_chain::iterator multialloc_iterator;
|
||||
multiallocation_chain mem;
|
||||
this->node_alloc().allocate_individual(n, mem);
|
||||
NodeAlloc &nalloc = this->node_alloc();
|
||||
node_allocator_version_traits_type::allocate_individual(nalloc, n, mem);
|
||||
multialloc_iterator itbeg(mem.begin()), itlast(mem.last());
|
||||
mem.clear();
|
||||
Node *p = 0;
|
||||
NodeAlloc &nalloc = this->node_alloc();
|
||||
BOOST_TRY{
|
||||
Deallocator node_deallocator(NodePtr(), nalloc);
|
||||
container_detail::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0);
|
||||
while(n--){
|
||||
p = container_detail::to_raw_pointer(&*itbeg);
|
||||
node_deallocator.set(p);
|
||||
++itbeg;
|
||||
//This can throw
|
||||
Deallocator node_deallocator(p, nalloc);
|
||||
boost::container::construct_in_place(nalloc, container_detail::addressof(p->m_data), beg);
|
||||
sdestructor.set(p);
|
||||
++beg;
|
||||
node_deallocator.release();
|
||||
//This does not throw
|
||||
typedef typename Node::hook_type hook_type;
|
||||
::new(static_cast<hook_type*>(p)) hook_type;
|
||||
//This can throw in some containers (predicate might throw)
|
||||
//This can throw in some containers (predicate might throw).
|
||||
//(sdestructor will destruct the node and node_deallocator will deallocate it in case of exception)
|
||||
inserter(*p);
|
||||
sdestructor.set(0);
|
||||
}
|
||||
sdestructor.release();
|
||||
node_deallocator.release();
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
mem.incorporate_after(mem.last(), &*itbeg, &*itlast, n);
|
||||
this->node_alloc().deallocate_individual(mem);
|
||||
node_allocator_version_traits_type::deallocate_individual(this->node_alloc(), mem);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
|
||||
#define BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -14,7 +14,7 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -178,6 +178,34 @@ struct rbtree_node
|
||||
{ m_data = ::boost::move(v); }
|
||||
};
|
||||
|
||||
template<class Node, class Icont>
|
||||
class insert_equal_end_hint_functor
|
||||
{
|
||||
Icont &icont_;
|
||||
|
||||
public:
|
||||
insert_equal_end_hint_functor(Icont &icont)
|
||||
: icont_(icont)
|
||||
{}
|
||||
|
||||
void operator()(Node &n)
|
||||
{ this->icont_.insert_equal(this->icont_.cend(), n); }
|
||||
};
|
||||
|
||||
template<class Node, class Icont>
|
||||
class push_back_functor
|
||||
{
|
||||
Icont &icont_;
|
||||
|
||||
public:
|
||||
push_back_functor(Icont &icont)
|
||||
: icont_(icont)
|
||||
{}
|
||||
|
||||
void operator()(Node &n)
|
||||
{ this->icont_.push_back(n); }
|
||||
};
|
||||
|
||||
}//namespace container_detail {
|
||||
|
||||
namespace container_detail {
|
||||
@@ -405,11 +433,19 @@ class rbtree
|
||||
)
|
||||
: AllocHolder(a, value_compare(comp))
|
||||
{
|
||||
//Use cend() as hint to achieve linear time for
|
||||
//ordered ranges as required by the standard
|
||||
//for the constructor
|
||||
const const_iterator end_it(this->cend());
|
||||
if(unique_insertion){
|
||||
this->insert_unique(first, last);
|
||||
for ( ; first != last; ++first){
|
||||
this->insert_unique(end_it, *first);
|
||||
}
|
||||
}
|
||||
else{
|
||||
this->insert_equal(first, last);
|
||||
for ( ; first != last; ++first){
|
||||
this->insert_equal(end_it, *first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,12 +462,19 @@ class rbtree
|
||||
: AllocHolder(a, value_compare(comp))
|
||||
{
|
||||
if(unique_insertion){
|
||||
this->insert_unique(first, last);
|
||||
//Use cend() as hint to achieve linear time for
|
||||
//ordered ranges as required by the standard
|
||||
//for the constructor
|
||||
const const_iterator end_it(this->cend());
|
||||
for ( ; first != last; ++first){
|
||||
this->insert_unique(end_it, *first);
|
||||
}
|
||||
}
|
||||
else{
|
||||
//Optimized allocation and construction
|
||||
this->allocate_many_and_construct
|
||||
(first, std::distance(first, last), insert_equal_end_hint_functor(this->icont()));
|
||||
( first, std::distance(first, last)
|
||||
, insert_equal_end_hint_functor<Node, Icont>(this->icont()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,7 +490,9 @@ class rbtree
|
||||
)
|
||||
: AllocHolder(a, value_compare(comp))
|
||||
{
|
||||
this->insert_equal(first, last);
|
||||
for ( ; first != last; ++first){
|
||||
this->push_back_impl(*first);
|
||||
}
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
@@ -464,7 +509,8 @@ class rbtree
|
||||
{
|
||||
//Optimized allocation and construction
|
||||
this->allocate_many_and_construct
|
||||
(first, std::distance(first, last), push_back_functor(this->icont()));
|
||||
( first, std::distance(first, last)
|
||||
, container_detail::push_back_functor<Node, Icont>(this->icont()));
|
||||
}
|
||||
|
||||
rbtree(const rbtree& x)
|
||||
@@ -534,8 +580,8 @@ class rbtree
|
||||
rbtree& operator=(BOOST_RV_REF(rbtree) x)
|
||||
{
|
||||
if (&x != this){
|
||||
NodeAlloc &this_alloc = this->node_alloc();
|
||||
NodeAlloc &x_alloc = x.node_alloc();
|
||||
NodeAlloc &this_alloc = this->get_stored_allocator();
|
||||
const NodeAlloc &x_alloc = x.get_stored_allocator();
|
||||
//If allocators are equal we can just swap pointers
|
||||
if(this_alloc == x_alloc){
|
||||
//Destroy and swap pointers
|
||||
@@ -678,8 +724,10 @@ class rbtree
|
||||
iterator insert_unique_commit(const value_type& v, insert_commit_data &data)
|
||||
{
|
||||
NodePtr tmp = AllocHolder::create_node(v);
|
||||
iiterator it(this->icont().insert_unique_commit(*tmp, data));
|
||||
return iterator(it);
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_unique_commit(*tmp, data));
|
||||
destroy_deallocator.release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class MovableConvertible>
|
||||
@@ -687,8 +735,10 @@ class rbtree
|
||||
(BOOST_FWD_REF(MovableConvertible) mv, insert_commit_data &data)
|
||||
{
|
||||
NodePtr tmp = AllocHolder::create_node(boost::forward<MovableConvertible>(mv));
|
||||
iiterator it(this->icont().insert_unique_commit(*tmp, data));
|
||||
return iterator(it);
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_unique_commit(*tmp, data));
|
||||
destroy_deallocator.release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::pair<iterator,bool> insert_unique(const value_type& v)
|
||||
@@ -696,10 +746,10 @@ class rbtree
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret =
|
||||
this->insert_unique_check(KeyOfValue()(v), data);
|
||||
if(!ret.second)
|
||||
if(ret.second){
|
||||
ret.first = this->insert_unique_commit(v, data);
|
||||
}
|
||||
return ret;
|
||||
return std::pair<iterator,bool>
|
||||
(this->insert_unique_commit(v, data), true);
|
||||
}
|
||||
|
||||
template<class MovableConvertible>
|
||||
@@ -708,13 +758,22 @@ class rbtree
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret =
|
||||
this->insert_unique_check(KeyOfValue()(mv), data);
|
||||
if(!ret.second)
|
||||
if(ret.second){
|
||||
ret.first = this->insert_unique_commit(boost::forward<MovableConvertible>(mv), data);
|
||||
}
|
||||
return ret;
|
||||
return std::pair<iterator,bool>
|
||||
(this->insert_unique_commit(boost::forward<MovableConvertible>(mv), data), true);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<class MovableConvertible>
|
||||
void push_back_impl(BOOST_FWD_REF(MovableConvertible) mv)
|
||||
{
|
||||
NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
|
||||
//push_back has no-throw guarantee so avoid any deallocator/destroyer
|
||||
this->icont().push_back(*tmp);
|
||||
}
|
||||
|
||||
std::pair<iterator, bool> emplace_unique_impl(NodePtr p)
|
||||
{
|
||||
value_type &v = p->get_data();
|
||||
@@ -760,15 +819,21 @@ class rbtree
|
||||
template <class... Args>
|
||||
iterator emplace_equal(Args&&... args)
|
||||
{
|
||||
NodePtr p(AllocHolder::create_node(boost::forward<Args>(args)...));
|
||||
return iterator(this->icont().insert_equal(this->icont().end(), *p));
|
||||
NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
|
||||
destroy_deallocator.release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint_equal(const_iterator hint, Args&&... args)
|
||||
{
|
||||
NodePtr p(AllocHolder::create_node(boost::forward<Args>(args)...));
|
||||
return iterator(this->icont().insert_equal(hint.get(), *p));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
|
||||
destroy_deallocator.release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
@@ -792,16 +857,22 @@ class rbtree
|
||||
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
|
||||
iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
||||
{ \
|
||||
NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
|
||||
return iterator(this->icont().insert_equal(this->icont().end(), *p)); \
|
||||
NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); \
|
||||
iterator ret(this->icont().insert_equal(this->icont().end(), *tmp)); \
|
||||
destroy_deallocator.release(); \
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
|
||||
iterator emplace_hint_equal(const_iterator hint \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
||||
{ \
|
||||
NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
|
||||
return iterator(this->icont().insert_equal(hint.get(), *p)); \
|
||||
NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); \
|
||||
iterator ret(this->icont().insert_equal(hint.get(), *tmp)); \
|
||||
destroy_deallocator.release(); \
|
||||
return ret; \
|
||||
} \
|
||||
//!
|
||||
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
@@ -833,53 +904,53 @@ class rbtree
|
||||
template <class InputIterator>
|
||||
void insert_unique(InputIterator first, InputIterator last)
|
||||
{
|
||||
if(this->empty()){
|
||||
//Insert with end hint, to achieve linear
|
||||
//complexity if [first, last) is ordered
|
||||
const_iterator hint(this->cend());
|
||||
for( ; first != last; ++first)
|
||||
hint = this->insert_unique(hint, *first);
|
||||
}
|
||||
else{
|
||||
for( ; first != last; ++first)
|
||||
this->insert_unique(*first);
|
||||
}
|
||||
}
|
||||
|
||||
iterator insert_equal(const value_type& v)
|
||||
{
|
||||
NodePtr p(AllocHolder::create_node(v));
|
||||
return iterator(this->icont().insert_equal(this->icont().end(), *p));
|
||||
NodePtr tmp(AllocHolder::create_node(v));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
|
||||
destroy_deallocator.release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class MovableConvertible>
|
||||
iterator insert_equal(BOOST_FWD_REF(MovableConvertible) mv)
|
||||
{
|
||||
NodePtr p(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
|
||||
return iterator(this->icont().insert_equal(this->icont().end(), *p));
|
||||
NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
|
||||
destroy_deallocator.release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
iterator insert_equal(const_iterator hint, const value_type& v)
|
||||
{
|
||||
NodePtr p(AllocHolder::create_node(v));
|
||||
return iterator(this->icont().insert_equal(hint.get(), *p));
|
||||
NodePtr tmp(AllocHolder::create_node(v));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
|
||||
destroy_deallocator.release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class MovableConvertible>
|
||||
iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv)
|
||||
{
|
||||
NodePtr p(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
|
||||
return iterator(this->icont().insert_equal(hint.get(), *p));
|
||||
NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
|
||||
destroy_deallocator.release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
void insert_equal(InputIterator first, InputIterator last)
|
||||
{
|
||||
//Insert with end hint, to achieve linear
|
||||
//complexity if [first, last) is ordered
|
||||
const_iterator hint(this->cend());
|
||||
for( ; first != last; ++first)
|
||||
hint = this->insert_equal(hint, *first);
|
||||
this->insert_equal(*first);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
@@ -930,41 +1001,6 @@ class rbtree
|
||||
return std::pair<const_iterator,const_iterator>
|
||||
(const_iterator(ret.first), const_iterator(ret.second));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
class insert_equal_end_hint_functor;
|
||||
friend class insert_equal_end_hint_functor;
|
||||
|
||||
class insert_equal_end_hint_functor
|
||||
{
|
||||
Icont &icont_;
|
||||
const iconst_iterator cend_;
|
||||
|
||||
public:
|
||||
insert_equal_end_hint_functor(Icont &icont)
|
||||
: icont_(icont), cend_(this->icont_.cend())
|
||||
{}
|
||||
|
||||
void operator()(Node &n)
|
||||
{ this->icont_.insert_equal(cend_, n); }
|
||||
};
|
||||
|
||||
class push_back_functor;
|
||||
friend class push_back_functor;
|
||||
|
||||
class push_back_functor
|
||||
{
|
||||
Icont &icont_;
|
||||
|
||||
public:
|
||||
push_back_functor(Icont &icont)
|
||||
: icont_(icont)
|
||||
{}
|
||||
|
||||
void operator()(Node &n)
|
||||
{ this->icont_.push_back(n); }
|
||||
};
|
||||
};
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
|
@@ -15,7 +15,7 @@
|
||||
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
#define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -622,7 +622,7 @@ inline typename container_detail::enable_if_memcpy_copy_constructible<I, F, I>::
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_default_alloc_n
|
||||
// uninitialized_value_init_alloc_n
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -636,7 +636,7 @@ inline typename container_detail::enable_if_memcpy_copy_constructible<I, F, I>::
|
||||
template
|
||||
<typename A,
|
||||
typename F> // F models ForwardIterator
|
||||
inline F uninitialized_default_alloc_n(A &a, typename allocator_traits<A>::difference_type n, F r)
|
||||
inline F uninitialized_value_init_alloc_n(A &a, typename allocator_traits<A>::difference_type n, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
@@ -655,6 +655,41 @@ inline F uninitialized_default_alloc_n(A &a, typename allocator_traits<A>::diffe
|
||||
return r;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_default_init_alloc_n
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! \code
|
||||
//! for (; n--; ++r, ++f)
|
||||
//! allocator_traits::construct(a, &*r);
|
||||
//! \endcode
|
||||
//!
|
||||
//! <b>Returns</b>: r
|
||||
template
|
||||
<typename A,
|
||||
typename F> // F models ForwardIterator
|
||||
inline F uninitialized_default_init_alloc_n(A &a, typename allocator_traits<A>::difference_type n, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
while (n--) {
|
||||
allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), default_init);
|
||||
++r;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for (; back != r; ++back){
|
||||
allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return r;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_fill_alloc
|
||||
|
@@ -13,7 +13,7 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_FLAT_MAP_HPP
|
||||
#define BOOST_CONTAINER_FLAT_MAP_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -694,6 +694,8 @@ class flat_map
|
||||
//! search time plus N*size() insertion time.
|
||||
//!
|
||||
//! <b>Note</b>: If an element is inserted it might invalidate elements.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
template <class InputIterator>
|
||||
void insert(ordered_unique_range_t, InputIterator first, InputIterator last)
|
||||
{ m_flat_tree.insert_unique(ordered_unique_range, first, last); }
|
||||
@@ -798,7 +800,7 @@ class flat_map
|
||||
//!
|
||||
//! <b>Complexity</b>: log(size())+count(k)
|
||||
size_type count(const key_type& x) const
|
||||
{ return m_flat_tree.find(x) == m_flat_tree.end() ? 0 : 1; }
|
||||
{ return static_cast<size_type>(m_flat_tree.find(x) != m_flat_tree.end()); }
|
||||
|
||||
//! <b>Returns</b>: An iterator pointing to the first element with key not less
|
||||
//! than k, or a.end() if such an element is not found.
|
||||
@@ -1487,6 +1489,8 @@ class flat_multimap
|
||||
//! search time plus N*size() insertion time.
|
||||
//!
|
||||
//! <b>Note</b>: If an element is inserted it might invalidate elements.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
template <class InputIterator>
|
||||
void insert(ordered_range_t, InputIterator first, InputIterator last)
|
||||
{ m_flat_tree.insert_equal(ordered_range, first, last); }
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_FLAT_SET_HPP
|
||||
#define BOOST_CONTAINER_FLAT_SET_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -636,7 +636,7 @@ class flat_set
|
||||
//!
|
||||
//! <b>Complexity</b>: log(size())+count(k)
|
||||
size_type count(const key_type& x) const
|
||||
{ return m_flat_tree.find(x) == m_flat_tree.end() ? 0 : 1; }
|
||||
{ return static_cast<size_type>(m_flat_tree.find(x) != m_flat_tree.end()); }
|
||||
|
||||
//! <b>Returns</b>: An iterator pointing to the first element with key not less
|
||||
//! than k, or a.end() if such an element is not found.
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#ifndef BOOST_CONTAINER_LIST_HPP
|
||||
#define BOOST_CONTAINER_LIST_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -563,7 +563,7 @@ class list
|
||||
{ return AllocHolder::max_size(); }
|
||||
|
||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||
//! the size becomes n. New elements are default constructed.
|
||||
//! the size becomes n. New elements are value initialized.
|
||||
//!
|
||||
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
|
||||
//!
|
||||
@@ -571,8 +571,8 @@ class list
|
||||
void resize(size_type new_size)
|
||||
{
|
||||
if(!priv_try_shrink(new_size)){
|
||||
typedef default_construct_iterator<value_type, difference_type> default_iterator;
|
||||
this->insert(this->cend(), default_iterator(new_size - this->size()), default_iterator());
|
||||
typedef value_init_construct_iterator<value_type, difference_type> value_init_iterator;
|
||||
this->insert(this->cend(), value_init_iterator(new_size - this->size()), value_init_iterator());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_MAP_HPP
|
||||
#define BOOST_CONTAINER_MAP_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -170,6 +170,8 @@ class map
|
||||
//! unique values.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in N.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
template <class InputIterator>
|
||||
map( ordered_unique_range_t, InputIterator first, InputIterator last
|
||||
, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
|
||||
@@ -711,7 +713,7 @@ class map
|
||||
//!
|
||||
//! <b>Complexity</b>: log(size())+count(k)
|
||||
size_type count(const key_type& x) const
|
||||
{ return m_tree.find(x) == m_tree.end() ? 0 : 1; }
|
||||
{ return static_cast<size_type>(m_tree.find(x) != m_tree.end()); }
|
||||
|
||||
//! <b>Returns</b>: An iterator pointing to the first element with key not less
|
||||
//! than k, or a.end() if such an element is not found.
|
||||
@@ -971,6 +973,8 @@ class multimap
|
||||
//! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in N.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
template <class InputIterator>
|
||||
multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(),
|
||||
const allocator_type& a = allocator_type())
|
||||
|
@@ -17,7 +17,7 @@
|
||||
#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
|
||||
#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
|
||||
|
||||
#if (defined MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined (_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
|
||||
#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
|
||||
|
||||
#if (defined MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_SET_HPP
|
||||
#define BOOST_CONTAINER_SET_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -139,6 +139,8 @@ class set
|
||||
//! unique values.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in N.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
template <class InputIterator>
|
||||
set( ordered_unique_range_t, InputIterator first, InputIterator last
|
||||
, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
|
||||
@@ -556,7 +558,7 @@ class set
|
||||
//!
|
||||
//! <b>Complexity</b>: log(size())+count(k)
|
||||
size_type count(const key_type& x) const
|
||||
{ return m_tree.find(x) == m_tree.end() ? 0 : 1; }
|
||||
{ return static_cast<size_type>(m_tree.find(x) != m_tree.end()); }
|
||||
|
||||
//! <b>Returns</b>: An iterator pointing to the first element with key not less
|
||||
//! than k, or a.end() if such an element is not found.
|
||||
@@ -770,6 +772,8 @@ class multiset
|
||||
//! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in N.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
template <class InputIterator>
|
||||
multiset( ordered_range_t, InputIterator first, InputIterator last
|
||||
, const Compare& comp = Compare()
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_SLIST_HPP
|
||||
#define BOOST_CONTAINER_SLIST_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -588,7 +588,7 @@ class slist
|
||||
{ return AllocHolder::max_size(); }
|
||||
|
||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||
//! the size becomes n. New elements are default constructed.
|
||||
//! the size becomes n. New elements are value initialized.
|
||||
//!
|
||||
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
|
||||
//!
|
||||
@@ -597,8 +597,8 @@ class slist
|
||||
{
|
||||
const_iterator last_pos;
|
||||
if(!priv_try_shrink(new_size, last_pos)){
|
||||
typedef default_construct_iterator<value_type, difference_type> default_iterator;
|
||||
this->insert_after(last_pos, default_iterator(new_size - this->size()), default_iterator());
|
||||
typedef value_init_construct_iterator<value_type, difference_type> value_init_iterator;
|
||||
this->insert_after(last_pos, value_init_iterator(new_size - this->size()), value_init_iterator());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -19,7 +19,7 @@
|
||||
#ifndef BOOST_CONTAINER_STABLE_VECTOR_HPP
|
||||
#define BOOST_CONTAINER_STABLE_VECTOR_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -123,8 +123,8 @@ struct node
|
||||
rebind_pointer<void>::type
|
||||
>
|
||||
{
|
||||
private:
|
||||
node();
|
||||
// private:
|
||||
// node();
|
||||
|
||||
public:
|
||||
typename ::boost::intrusive::pointer_traits<Pointer>::element_type value;
|
||||
@@ -568,7 +568,7 @@ class stable_vector
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
|
||||
//! and inserts n default contructed values.
|
||||
//! and inserts n value initialized values.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
||||
//! throws or T's default or copy constructor throws.
|
||||
@@ -583,6 +583,24 @@ class stable_vector
|
||||
cod.release();
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
|
||||
//! and inserts n default initialized values.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
||||
//! throws or T's default or copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to n.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension
|
||||
stable_vector(size_type n, default_init_t)
|
||||
: internal_data(), index()
|
||||
{
|
||||
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
|
||||
this->resize(n, default_init);
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
cod.release();
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
|
||||
//! and inserts n copies of value.
|
||||
//!
|
||||
@@ -960,17 +978,35 @@ class stable_vector
|
||||
{ return this->index.max_size() - ExtraPointers; }
|
||||
|
||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||
//! the size becomes n. New elements are default constructed.
|
||||
//! the size becomes n. New elements are value initialized.
|
||||
//!
|
||||
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
|
||||
//! <b>Throws</b>: If memory allocation throws, or T's default constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
||||
void resize(size_type n)
|
||||
{
|
||||
typedef default_construct_iterator<value_type, difference_type> default_iterator;
|
||||
typedef value_init_construct_iterator<value_type, difference_type> value_init_iterator;
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
if(n > this->size())
|
||||
this->insert(this->cend(), default_iterator(n - this->size()), default_iterator());
|
||||
this->insert(this->cend(), value_init_iterator(n - this->size()), value_init_iterator());
|
||||
else if(n < this->size())
|
||||
this->erase(this->cbegin() + n, this->cend());
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||
//! the size becomes n. New elements are default initialized.
|
||||
//!
|
||||
//! <b>Throws</b>: If memory allocation throws, or T's default constructor 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)
|
||||
{
|
||||
typedef default_init_construct_iterator<value_type, difference_type> default_init_iterator;
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
if(n > this->size())
|
||||
this->insert(this->cend(), default_init_iterator(n - this->size()), default_init_iterator());
|
||||
else if(n < this->size())
|
||||
this->erase(this->cbegin() + n, this->cend());
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#ifndef BOOST_CONTAINER_STATIC_VECTOR_HPP
|
||||
#define BOOST_CONTAINER_STATIC_VECTOR_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -138,7 +138,7 @@ public:
|
||||
|
||||
//! @pre <tt>count <= capacity()</tt>
|
||||
//!
|
||||
//! @brief Constructs a static_vector containing count default constructed Values.
|
||||
//! @brief Constructs a static_vector containing count value initialized values.
|
||||
//!
|
||||
//! @param count The number of values which will be contained in the container.
|
||||
//!
|
||||
@@ -151,6 +151,24 @@ public:
|
||||
: base_t(count)
|
||||
{}
|
||||
|
||||
//! @pre <tt>count <= capacity()</tt>
|
||||
//!
|
||||
//! @brief Constructs a static_vector containing count value initialized values.
|
||||
//!
|
||||
//! @param count The number of values which will be contained in the container.
|
||||
//!
|
||||
//! @par Throws
|
||||
//! If Value's default constructor throws.
|
||||
//!
|
||||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
//!
|
||||
//! @par Note
|
||||
//! Non-standard extension
|
||||
static_vector(size_type count, default_init_t)
|
||||
: base_t(count, default_init_t())
|
||||
{}
|
||||
|
||||
//! @pre <tt>count <= capacity()</tt>
|
||||
//!
|
||||
//! @brief Constructs a static_vector containing count copies of value.
|
||||
@@ -358,7 +376,7 @@ public:
|
||||
//! @pre <tt>count <= capacity()</tt>
|
||||
//!
|
||||
//! @brief Inserts or erases elements at the end such that
|
||||
//! the size becomes count. New elements are default constructed.
|
||||
//! the size becomes count. New elements are value initialized.
|
||||
//!
|
||||
//! @param count The number of elements which will be stored in the container.
|
||||
//!
|
||||
@@ -369,6 +387,23 @@ public:
|
||||
//! Linear O(N).
|
||||
void resize(size_type count);
|
||||
|
||||
//! @pre <tt>count <= capacity()</tt>
|
||||
//!
|
||||
//! @brief Inserts or erases elements at the end such that
|
||||
//! the size becomes count. New elements are default initialized.
|
||||
//!
|
||||
//! @param count The number of elements which will be stored in the container.
|
||||
//!
|
||||
//! @par Throws
|
||||
//! If Value's default constructor throws.
|
||||
//!
|
||||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
//!
|
||||
//! @par Note
|
||||
//! Non-standard extension
|
||||
void resize(size_type count, default_init_t);
|
||||
|
||||
//! @pre <tt>count <= capacity()</tt>
|
||||
//!
|
||||
//! @brief Inserts or erases elements at the end such that
|
||||
|
@@ -937,7 +937,7 @@ class basic_string
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||
//! the size becomes n. New elements are default constructed.
|
||||
//! the size becomes n. New elements are value initialized.
|
||||
//!
|
||||
//! <b>Throws</b>: If memory allocation throws
|
||||
//!
|
||||
|
@@ -14,7 +14,7 @@
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_CONTAINER_VECTOR_HPP
|
||||
#define BOOST_CONTAINER_CONTAINER_VECTOR_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -293,19 +293,27 @@ struct vector_alloc_holder
|
||||
template<class AllocConvertible>
|
||||
explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a, size_type initial_size)
|
||||
: Allocator(boost::forward<AllocConvertible>(a))
|
||||
, m_start()
|
||||
, m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this
|
||||
, m_capacity()
|
||||
{
|
||||
if(initial_size){
|
||||
m_start = this->allocation_command(allocate_new, initial_size, initial_size, m_capacity, m_start).first;
|
||||
}
|
||||
}
|
||||
|
||||
//Constructor, does not throw
|
||||
explicit vector_alloc_holder(size_type initial_size)
|
||||
: Allocator()
|
||||
, m_start()
|
||||
, m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this
|
||||
, m_capacity()
|
||||
{
|
||||
if(initial_size){
|
||||
m_start = this->allocation_command
|
||||
(allocate_new, initial_size, initial_size, m_capacity, m_start).first;
|
||||
}
|
||||
}
|
||||
|
||||
vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_CONTAINER_NOEXCEPT
|
||||
: Allocator(boost::move(static_cast<Allocator&>(holder)))
|
||||
@@ -319,9 +327,11 @@ struct vector_alloc_holder
|
||||
|
||||
void first_allocation(size_type cap)
|
||||
{
|
||||
if(cap){
|
||||
m_start = this->allocation_command
|
||||
(allocate_new, cap, cap, m_capacity, m_start).first;
|
||||
}
|
||||
}
|
||||
|
||||
void first_allocation_same_allocator_type(size_type cap)
|
||||
{ this->first_allocation(cap); }
|
||||
@@ -417,16 +427,18 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
|
||||
template<class AllocConvertible>
|
||||
explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a, size_type initial_size)
|
||||
: Allocator(boost::forward<AllocConvertible>(a))
|
||||
, m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this
|
||||
, m_size(initial_size) //Size is initialized here...
|
||||
{
|
||||
//... and capacity here, so vector, must call uninitialized_xxx in the derived constructor
|
||||
this->first_allocation(initial_size);
|
||||
}
|
||||
|
||||
//Constructor, does not throw
|
||||
explicit vector_alloc_holder(size_type initial_size)
|
||||
: Allocator()
|
||||
, m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this
|
||||
, m_size(initial_size) //Size is initialized here...
|
||||
{
|
||||
//... and capacity here, so vector, must call uninitialized_xxx in the derived constructor
|
||||
this->first_allocation(initial_size);
|
||||
}
|
||||
|
||||
@@ -611,7 +623,7 @@ class vector
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
|
||||
//! and inserts n default contructed values.
|
||||
//! and inserts n value initialized values.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocator_type's default constructor or allocation
|
||||
//! throws or T's default constructor throws.
|
||||
@@ -620,7 +632,24 @@ class vector
|
||||
explicit vector(size_type n)
|
||||
: m_holder(n)
|
||||
{
|
||||
boost::container::uninitialized_default_alloc_n(this->m_holder.alloc(), n, container_detail::to_raw_pointer(this->m_holder.start()));
|
||||
boost::container::uninitialized_value_init_alloc_n
|
||||
(this->m_holder.alloc(), n, container_detail::to_raw_pointer(this->m_holder.start()));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
|
||||
//! and inserts n default initialized values.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocator_type's default constructor or allocation
|
||||
//! throws or T's default constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to n.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension
|
||||
explicit vector(size_type n, default_init_t)
|
||||
: m_holder(n)
|
||||
{
|
||||
boost::container::uninitialized_default_init_alloc_n
|
||||
(this->m_holder.alloc(), n, container_detail::to_raw_pointer(this->m_holder.start()));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a vector
|
||||
@@ -1030,9 +1059,9 @@ class vector
|
||||
{ return allocator_traits_type::max_size(this->m_holder.alloc()); }
|
||||
|
||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||
//! the size becomes n. New elements are default constructed.
|
||||
//! the size becomes n. New elements are value initialized.
|
||||
//!
|
||||
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
|
||||
//! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
||||
void resize(size_type new_size)
|
||||
@@ -1044,7 +1073,29 @@ class vector
|
||||
}
|
||||
else{
|
||||
const size_type n = new_size - this->size();
|
||||
container_detail::insert_default_constructed_n_proxy<Allocator, T*> proxy(this->m_holder.alloc());
|
||||
container_detail::insert_value_initialized_n_proxy<Allocator, T*> proxy(this->m_holder.alloc());
|
||||
this->priv_forward_range_insert_at_end(n, proxy, alloc_version());
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||
//! the size becomes n. New elements are value initialized.
|
||||
//!
|
||||
//! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension
|
||||
void resize(size_type new_size, default_init_t)
|
||||
{
|
||||
const size_type sz = this->size();
|
||||
if (new_size < sz){
|
||||
//Destroy last elements
|
||||
this->priv_destroy_last_n(sz - new_size);
|
||||
}
|
||||
else{
|
||||
const size_type n = new_size - this->size();
|
||||
container_detail::insert_default_initialized_n_proxy<Allocator, T*> proxy(this->m_holder.alloc());
|
||||
this->priv_forward_range_insert_at_end(n, proxy, alloc_version());
|
||||
}
|
||||
}
|
||||
|
134
proj/vc7ide/bench_set.vcproj
Normal file
134
proj/vc7ide/bench_set.vcproj
Normal file
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="bench_set"
|
||||
ProjectGUID="{5E1C1C23-26A9-4FE5-A24E-DA735271C32B}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/bench_set"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
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_set_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/bench_set.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_set"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_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"
|
||||
OutputFile="$(OutDir)/bench_set.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="{4B737ACF-06A6-1243-CC8A-3D7D42A02A3F}">
|
||||
<File
|
||||
RelativePath="..\..\bench\bench_set.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@@ -67,6 +67,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_static_vector", "benc
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_set", "bench_set.vcproj", "{5E1C1C23-26A9-4FE5-A24E-DA735271C32B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
@@ -137,12 +141,14 @@ Global
|
||||
{5A8D91E0-FA57-284F-84FE-D3A6BA792002}.Release.Build.0 = Release|Win32
|
||||
{58E1C1C3-096A-84FE-4FA2-D6BA79201C02}.Debug.ActiveCfg = Debug|Win32
|
||||
{58E1C1C3-096A-84FE-4FA2-D6BA79201C02}.Debug.Build.0 = Debug|Win32
|
||||
{58E1C1C3-096A-84F0-4FA2-D6BA79201C02}.Release.ActiveCfg = Release|Win32
|
||||
{58E1C1C3-096A-84F0-4FA2-D6BA79201C02}.Release.Build.0 = Release|Win32
|
||||
{58E1C1C3-096A-84F1-4FA2-D6BA79201C02}.Debug.ActiveCfg = Debug|Win32
|
||||
{58E1C1C3-096A-84F1-4FA2-D6BA79201C02}.Debug.Build.0 = Debug|Win32
|
||||
{58E1C1C3-096A-84F2-4FA2-D6BA79201C02}.Release.ActiveCfg = Release|Win32
|
||||
{58E1C1C3-096A-84F2-4FA2-D6BA79201C02}.Release.Build.0 = Release|Win32
|
||||
{58E1C1C3-096A-84FE-4FA2-D6BA79201C02}.Release.ActiveCfg = Release|Win32
|
||||
{58E1C1C3-096A-84FE-4FA2-D6BA79201C02}.Debug.ActiveCfg = Debug|Win32
|
||||
{58E1C1C3-096A-84FE-4FA2-D6BA79201C02}.Debug.Build.0 = Debug|Win32
|
||||
{58E1C1C3-096A-84FE-4FA2-D6BA79201C02}.Release.ActiveCfg = Release|Win32
|
||||
{5E1C1C23-26A9-4FE5-A24E-DA735271C32B}.Debug.ActiveCfg = Debug|Win32
|
||||
{5E1C1C23-26A9-4FE5-A24E-DA735271C32B}.Debug.Build.0 = Debug|Win32
|
||||
{5E1C1C23-26A9-4FE5-A24E-DA735271C32B}.Release.ActiveCfg = Release|Win32
|
||||
{5E1C1C23-26A9-4FE5-A24E-DA735271C32B}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
|
@@ -337,6 +337,9 @@
|
||||
<Filter
|
||||
Name="bench"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\bench\Jamfile.v2">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\bench\varray.hpp">
|
||||
</File>
|
||||
|
@@ -25,6 +25,12 @@ class SimpleAllocator
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
template <class U>
|
||||
SimpleAllocator(SimpleAllocator<U>)
|
||||
: allocate_called_(false)
|
||||
, deallocate_called_(false)
|
||||
{}
|
||||
|
||||
SimpleAllocator()
|
||||
: allocate_called_(false)
|
||||
, deallocate_called_(false)
|
||||
@@ -132,6 +138,13 @@ class ComplexAllocator
|
||||
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
template<class U>
|
||||
void construct(U *p, boost::container::default_init_t)
|
||||
{
|
||||
construct_called_ = true;
|
||||
::new (p) U;
|
||||
}
|
||||
|
||||
//getters
|
||||
bool allocate_called() const
|
||||
{ return allocate_called_; }
|
||||
@@ -157,13 +170,13 @@ class ComplexAllocator
|
||||
|
||||
class copymovable
|
||||
{
|
||||
bool copymoveconstructed_;
|
||||
bool moved_;
|
||||
|
||||
BOOST_COPYABLE_AND_MOVABLE(copymovable)
|
||||
|
||||
public:
|
||||
|
||||
bool copymoveconstructed_;
|
||||
bool moved_;
|
||||
|
||||
copymovable(int, int, int)
|
||||
: copymoveconstructed_(false), moved_(false)
|
||||
{}
|
||||
@@ -314,6 +327,22 @@ int main()
|
||||
SAllocTraits::select_on_container_copy_construction(s_alloc);
|
||||
|
||||
//construct
|
||||
{
|
||||
copymovable c;
|
||||
c.copymoveconstructed_ = true;
|
||||
c.copymoveconstructed_ = true;
|
||||
CAllocTraits::construct(c_alloc, &c);
|
||||
if(!c_alloc.construct_called() || c.copymoveconstructed() || c.moved()){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
int i = 5;
|
||||
CAllocTraits::construct(c_alloc, &i, boost::container::default_init);
|
||||
if(!c_alloc.construct_called() || i != 5){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
copymovable c;
|
||||
copymovable c2;
|
||||
@@ -330,6 +359,22 @@ int main()
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
copymovable c;
|
||||
c.copymoveconstructed_ = true;
|
||||
c.copymoveconstructed_ = true;
|
||||
SAllocTraits::construct(s_alloc, &c);
|
||||
if(c.copymoveconstructed() || c.moved()){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
int i = 4;
|
||||
SAllocTraits::construct(s_alloc, &i, boost::container::default_init);
|
||||
if(i != 4){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
copymovable c;
|
||||
copymovable c2;
|
||||
|
@@ -332,6 +332,10 @@ int main ()
|
||||
return 1;
|
||||
if(test::vector_test<MyCopyDeque>())
|
||||
return 1;
|
||||
if(!test::default_init_test< deque<int, test::default_init_allocator<int> > >()){
|
||||
std::cerr << "Default init test failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE);
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_DUMMY_TEST_ALLOCATOR_HPP
|
||||
#define BOOST_CONTAINER_DUMMY_TEST_ALLOCATOR_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if (defined _MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP
|
||||
#define BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if (defined _MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_CONTAINER_HEAP_ALLOCATOR_V1_HPP
|
||||
#define BOOST_CONTAINER_HEAP_ALLOCATOR_V1_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if (defined _MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@@ -66,6 +66,36 @@ void recursive_vector_test()//Test for recursive types
|
||||
}
|
||||
}
|
||||
|
||||
bool default_init_test()//Test for default initialization
|
||||
{
|
||||
typedef stable_vector<int, test::default_init_allocator<int> > svector_t;
|
||||
|
||||
const std::size_t Capacity = 100;
|
||||
|
||||
{
|
||||
test::default_init_allocator<int>::reset_pattern(0);
|
||||
svector_t v(Capacity, default_init);
|
||||
svector_t::iterator it = v.begin();
|
||||
//Compare with the pattern
|
||||
for(std::size_t i = 0; i != Capacity; ++i, ++it){
|
||||
if(*it != static_cast<int>(i))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
{
|
||||
test::default_init_allocator<int>::reset_pattern(100);
|
||||
svector_t v;
|
||||
v.resize(Capacity, default_init);
|
||||
svector_t::iterator it = v.begin();
|
||||
//Compare with the pattern
|
||||
for(std::size_t i = 0; i != Capacity; ++i, ++it){
|
||||
if(*it != static_cast<int>(i+100))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
recursive_vector_test();
|
||||
@@ -102,6 +132,11 @@ int main()
|
||||
if(test::vector_test<MyCopyVector>())
|
||||
return 1;
|
||||
|
||||
if(!test::default_init_test< stable_vector<int, test::default_init_allocator<int> > >()){
|
||||
std::cerr << "Default init test failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE);
|
||||
if(!boost::container::test::test_emplace
|
||||
< stable_vector<test::EmplaceInt>, Options>())
|
||||
|
@@ -611,6 +611,53 @@ void test_sv_elem(T const& t)
|
||||
v.emplace_back(N/2, t);
|
||||
}
|
||||
|
||||
bool default_init_test()//Test for default initialization
|
||||
{
|
||||
typedef static_vector<int, 100> di_vector_t;
|
||||
|
||||
const std::size_t Capacity = 100;
|
||||
|
||||
{
|
||||
di_vector_t v;
|
||||
int *p = v.data();
|
||||
|
||||
for(std::size_t i = 0; i != Capacity; ++i, ++p){
|
||||
*p = static_cast<int>(i);
|
||||
}
|
||||
|
||||
//Destroy the vector, p stilll pointing to the storage
|
||||
v.~di_vector_t();
|
||||
|
||||
di_vector_t &rv = *::new(&v)di_vector_t(Capacity, default_init);
|
||||
di_vector_t::iterator it = rv.begin();
|
||||
|
||||
for(std::size_t i = 0; i != Capacity; ++i, ++it){
|
||||
if(*it != static_cast<int>(i))
|
||||
return false;
|
||||
}
|
||||
|
||||
v.~di_vector_t();
|
||||
}
|
||||
{
|
||||
di_vector_t v;
|
||||
|
||||
int *p = v.data();
|
||||
for(std::size_t i = 0; i != Capacity; ++i, ++p){
|
||||
*p = static_cast<int>(i+100);
|
||||
}
|
||||
|
||||
v.resize(Capacity, default_init);
|
||||
|
||||
di_vector_t::iterator it = v.begin();
|
||||
for(std::size_t i = 0; i != Capacity; ++i, ++it){
|
||||
if(*it != static_cast<int>(i+100))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char* [])
|
||||
{
|
||||
using boost::container::test::movable_and_copyable_int;
|
||||
@@ -727,6 +774,9 @@ int main(int, char* [])
|
||||
BOOST_TEST(counting_value::count() == 0);
|
||||
test_sv_elem<shptr_value, 10>(shptr_value(50));
|
||||
test_sv_elem<movable_and_copyable_int, 10>(movable_and_copyable_int(50));
|
||||
|
||||
BOOST_TEST(default_init_test() == true);
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
@@ -151,6 +151,10 @@ int main()
|
||||
return 1;
|
||||
if(test_expand_bwd())
|
||||
return 1;
|
||||
if(!test::default_init_test< vector<int, test::default_init_allocator<int> > >()){
|
||||
std::cerr << "Default init test failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
MyEnumVector v;
|
||||
Test t;
|
||||
|
@@ -31,12 +31,130 @@
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/move/iterator.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include "insert_test.hpp"
|
||||
|
||||
namespace boost{
|
||||
namespace container {
|
||||
namespace test{
|
||||
|
||||
//
|
||||
template<int Dummy = 0>
|
||||
class default_init_allocator_base
|
||||
{
|
||||
protected:
|
||||
static unsigned char s_pattern;
|
||||
static bool s_ascending;
|
||||
|
||||
public:
|
||||
static void reset_pattern(unsigned char value)
|
||||
{ s_pattern = value; }
|
||||
|
||||
static void set_ascending(bool enable)
|
||||
{ s_ascending = enable; }
|
||||
};
|
||||
|
||||
template<int Dummy>
|
||||
unsigned char default_init_allocator_base<Dummy>::s_pattern = 0u;
|
||||
|
||||
template<int Dummy>
|
||||
bool default_init_allocator_base<Dummy>::s_ascending = true;
|
||||
|
||||
template<class T>
|
||||
class default_init_allocator
|
||||
: public default_init_allocator_base<0>
|
||||
{
|
||||
typedef default_init_allocator_base<0> base_t;
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
default_init_allocator()
|
||||
{}
|
||||
|
||||
template <class U>
|
||||
default_init_allocator(default_init_allocator<U>)
|
||||
{}
|
||||
|
||||
T* allocate(std::size_t n)
|
||||
{
|
||||
//Initialize memory to a pattern
|
||||
T *const p = ::new T[n];
|
||||
unsigned char *puc_raw = reinterpret_cast<unsigned char*>(p);
|
||||
std::size_t max = sizeof(T)*n;
|
||||
if(base_t::s_ascending){
|
||||
for(std::size_t i = 0; i != max; ++i){
|
||||
puc_raw[i] = static_cast<unsigned char>(s_pattern++);
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(std::size_t i = 0; i != max; ++i){
|
||||
puc_raw[i] = static_cast<unsigned char>(s_pattern--);
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void deallocate(T *p, std::size_t)
|
||||
{ delete[] p; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline bool check_ascending_byte_pattern(const T&t)
|
||||
{
|
||||
const unsigned char *pch = &reinterpret_cast<const unsigned char &>(t);
|
||||
const std::size_t max = sizeof(T);
|
||||
for(std::size_t i = 1; i != max; ++i){
|
||||
if( (pch[i-1] != ((unsigned char)(pch[i]-1u))) ){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool check_descending_byte_pattern(const T&t)
|
||||
{
|
||||
const unsigned char *pch = &reinterpret_cast<const unsigned char &>(t);
|
||||
const std::size_t max = sizeof(T);
|
||||
for(std::size_t i = 1; i != max; ++i){
|
||||
if( (pch[i-1] != ((unsigned char)(pch[i]+1u))) ){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class IntDefaultInitAllocVector>
|
||||
bool default_init_test()//Test for default initialization
|
||||
{
|
||||
const std::size_t Capacity = 100;
|
||||
|
||||
{
|
||||
test::default_init_allocator<int>::reset_pattern(0);
|
||||
test::default_init_allocator<int>::set_ascending(true);
|
||||
IntDefaultInitAllocVector v(Capacity, default_init);
|
||||
typename IntDefaultInitAllocVector::iterator it = v.begin();
|
||||
//Compare with the pattern
|
||||
for(std::size_t i = 0; i != Capacity; ++i, ++it){
|
||||
if(!test::check_ascending_byte_pattern(*it))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
{
|
||||
test::default_init_allocator<int>::reset_pattern(100);
|
||||
test::default_init_allocator<int>::set_ascending(false);
|
||||
IntDefaultInitAllocVector v;
|
||||
v.resize(Capacity, default_init);
|
||||
typename IntDefaultInitAllocVector::iterator it = v.begin();
|
||||
//Compare with the pattern
|
||||
for(std::size_t i = 0; i != Capacity; ++i, ++it){
|
||||
if(!test::check_descending_byte_pattern(*it))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class V1, class V2>
|
||||
bool vector_copyable_only(V1 *, V2 *, boost::container::container_detail::false_type)
|
||||
{
|
||||
|
Reference in New Issue
Block a user