mirror of
https://github.com/boostorg/container.git
synced 2025-08-03 22:44:26 +02:00
Additional vector speed improvements, added basic benchmark against varray
[SVN r83126]
This commit is contained in:
34
bench/Jamfile.v2
Normal file
34
bench/Jamfile.v2
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# Boost Container Library Test Jamfile
|
||||||
|
|
||||||
|
# (C) Copyright Ion Gaztanaga 2009.
|
||||||
|
# Use, modification and distribution are subject to the
|
||||||
|
# Boost Software License, Version 1.0. (See accompanying file
|
||||||
|
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
# Adapted from John Maddock's TR1 Jamfile.v2
|
||||||
|
# Copyright John Maddock 2005.
|
||||||
|
# Use, modification and distribution are subject to the
|
||||||
|
# Boost Software License, Version 1.0. (See accompanying file
|
||||||
|
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
# this rule enumerates through all the sources and invokes
|
||||||
|
# the run rule for each source, the result is a list of all
|
||||||
|
# the run rules, which we can pass on to the test_suite rule:
|
||||||
|
|
||||||
|
rule test_all
|
||||||
|
{
|
||||||
|
local all_rules = ;
|
||||||
|
|
||||||
|
for local fileb in [ glob *.cpp ]
|
||||||
|
{
|
||||||
|
all_rules += [ run $(fileb) /boost/timer//boost_timer /boost/system//boost_system /boost/thread//boost_thread
|
||||||
|
: # additional args
|
||||||
|
: # test-files
|
||||||
|
: # requirements
|
||||||
|
] ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $(all_rules) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
test-suite container_test : [ test_all r ] ;
|
147
bench/bench_static_vector.cpp
Normal file
147
bench/bench_static_vector.cpp
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
// benchmark based on: http://cpp-next.com/archive/2010/10/howards-stl-move-semantics-benchmark/
|
||||||
|
//
|
||||||
|
// @file bench_static_vector.cpp
|
||||||
|
// @date Aug 14, 2011
|
||||||
|
// @author Andrew Hundt <ATHundt@gmail.com>
|
||||||
|
//
|
||||||
|
// (C) 2011-2012 Andrew Hundt <ATHundt@gmail.com>
|
||||||
|
// (C) 2013 Ion Gaztanaga
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// @brief varray_benchmark.cpp compares the performance of boost::container::varray to boost::container::vector
|
||||||
|
|
||||||
|
#include "varray.hpp"
|
||||||
|
#include "boost/container/vector.hpp"
|
||||||
|
#include "boost/container/static_vector.hpp"
|
||||||
|
#include "../test/movable_int.hpp"
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <boost/timer/timer.hpp>
|
||||||
|
#include <set>
|
||||||
|
#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 = 1000;
|
||||||
|
#else
|
||||||
|
static const std::size_t N = 100;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BENCH_SIMPLE_CONSTRUCTION
|
||||||
|
//#define BENCH_TRIVIAL_TYPE
|
||||||
|
|
||||||
|
#ifdef BENCH_TRIVIAL_TYPE
|
||||||
|
typedef std::size_t basic_type_t;
|
||||||
|
#else
|
||||||
|
typedef boost::container::test::copyable_int basic_type_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T &get_set(std::size_t)
|
||||||
|
{
|
||||||
|
#ifdef BENCH_SIMPLE_CONSTRUCTION
|
||||||
|
T &t = *new T(N);
|
||||||
|
for (std::size_t i = 0; i < N; ++i)
|
||||||
|
t[i] = basic_type_t(std::rand());
|
||||||
|
#else
|
||||||
|
T &t = *new T;
|
||||||
|
t.reserve(N);
|
||||||
|
for (std::size_t i = 0; i < N; ++i)
|
||||||
|
t.push_back(basic_type_t(std::rand()));
|
||||||
|
#endif
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T &generate()
|
||||||
|
{
|
||||||
|
T &v = *new T;
|
||||||
|
v.reserve(N);
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < N; ++i){
|
||||||
|
typename T::reference r = get_set<typename T::value_type>(i);
|
||||||
|
v.push_back(boost::move(r));
|
||||||
|
delete &r;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
cpu_times time_it()
|
||||||
|
{
|
||||||
|
cpu_timer sortTime,rotateTime,destructionTime;
|
||||||
|
sortTime.stop();rotateTime.stop();destructionTime.stop();
|
||||||
|
cpu_timer totalTime, constructTime;
|
||||||
|
std::srand (0);
|
||||||
|
for(std::size_t i = 0; i< N; ++i){
|
||||||
|
|
||||||
|
constructTime.resume();
|
||||||
|
{
|
||||||
|
T &v = generate<T>();
|
||||||
|
constructTime.stop();
|
||||||
|
sortTime.resume();
|
||||||
|
std::sort(v.begin(), v.end());
|
||||||
|
sortTime.stop();
|
||||||
|
rotateTime.resume();
|
||||||
|
std::rotate(v.begin(), v.begin() + v.size()/2, v.end());
|
||||||
|
rotateTime.stop();
|
||||||
|
|
||||||
|
destructionTime.resume();
|
||||||
|
delete &v;
|
||||||
|
}
|
||||||
|
destructionTime.stop();
|
||||||
|
}
|
||||||
|
totalTime.stop();
|
||||||
|
std::cout << " construction took " << boost::timer::format(constructTime.elapsed());
|
||||||
|
std::cout << " sort took " << boost::timer::format(sortTime.elapsed());
|
||||||
|
std::cout << " rotate took " << boost::timer::format(rotateTime.elapsed());
|
||||||
|
std::cout << " destruction took " << boost::timer::format(destructionTime.elapsed());
|
||||||
|
std::cout << " Total time = " << boost::timer::format(totalTime.elapsed()) << std::endl;
|
||||||
|
return totalTime.elapsed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void compare_times(cpu_times time_numerator, cpu_times time_denominator){
|
||||||
|
std::cout
|
||||||
|
<< "\n wall = " << ((double)time_numerator.wall/(double)time_denominator.wall)
|
||||||
|
<< "\n user = " << ((double)time_numerator.user/(double)time_denominator.user)
|
||||||
|
<< "\n system = " << ((double)time_numerator.system/(double)time_denominator.system)
|
||||||
|
<< "\n (user+system) = " << ((double)(time_numerator.system+time_numerator.user)/(double)(time_denominator.system+time_denominator.user)) << "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
std::cout << "N = " << N << "\n\n";
|
||||||
|
|
||||||
|
std::cout << "varray benchmark:\n";
|
||||||
|
cpu_times time_varray = time_it<boost::container::varray<boost::container::varray<basic_type_t,N>,N > >();
|
||||||
|
|
||||||
|
std::cout << "boost::container::static_vector benchmark\n";
|
||||||
|
cpu_times time_boost_static_vector = time_it<boost::container::static_vector<boost::container::static_vector<basic_type_t,N>,N > >();
|
||||||
|
|
||||||
|
std::cout << "boost::container::vector benchmark\n";
|
||||||
|
cpu_times time_boost_vector = time_it<boost::container::vector<boost::container::vector<basic_type_t> > >();
|
||||||
|
|
||||||
|
std::cout << "std::vector benchmark\n";
|
||||||
|
cpu_times time_standard_vector = time_it<std::vector<std::vector<basic_type_t> > >();
|
||||||
|
|
||||||
|
std::cout << "varray/boost::container::vector total time comparison:";
|
||||||
|
compare_times(time_varray, time_boost_vector);
|
||||||
|
|
||||||
|
std::cout << "varray/boost::container::static_vector total time comparison:";
|
||||||
|
compare_times(time_varray, time_boost_static_vector);
|
||||||
|
|
||||||
|
std::cout << "varray/std::vector total time comparison:";
|
||||||
|
compare_times(time_varray,time_standard_vector);
|
||||||
|
}catch(std::exception e){
|
||||||
|
std::cout << e.what();
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
2274
bench/detail/varray.hpp
Normal file
2274
bench/detail/varray.hpp
Normal file
File diff suppressed because it is too large
Load Diff
60
bench/detail/varray_concept.hpp
Normal file
60
bench/detail/varray_concept.hpp
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
// Boost.Container varray
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012-2013 Andrew Hundt.
|
||||||
|
// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
|
||||||
|
//
|
||||||
|
// Use, modification and distribution is subject to the Boost Software License,
|
||||||
|
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#ifndef BOOST_CONTAINER_VARRAY_CONCEPT_HPP
|
||||||
|
#define BOOST_CONTAINER_VARRAY_CONCEPT_HPP
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
|
||||||
|
namespace boost { namespace container { namespace container_detail { namespace concept {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VArrayStrategyConcept
|
||||||
|
*
|
||||||
|
* \brief Checks strategy for varray<Value,Capacity,Strategy>, which has similarities to std::Allocator
|
||||||
|
* \ingroup varray
|
||||||
|
*/
|
||||||
|
template<typename Strategy>
|
||||||
|
struct VArrayStrategy {
|
||||||
|
#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
|
||||||
|
|
||||||
|
// typedefs are the same as in std::Allocator
|
||||||
|
typedef typename Strategy::value_type value_type;
|
||||||
|
typedef typename Strategy::size_type size_type;
|
||||||
|
typedef typename Strategy::difference_type difference_type;
|
||||||
|
typedef typename Strategy::pointer pointer;
|
||||||
|
typedef typename Strategy::const_pointer const_pointer;
|
||||||
|
typedef typename Strategy::reference reference;
|
||||||
|
typedef typename Strategy::const_reference const_reference;
|
||||||
|
|
||||||
|
struct check_methods
|
||||||
|
{
|
||||||
|
static void apply()
|
||||||
|
{
|
||||||
|
Strategy const* str = 0;
|
||||||
|
|
||||||
|
// must implement allocate_failed
|
||||||
|
str->allocate_failed();
|
||||||
|
|
||||||
|
boost::ignore_unused_variable_warning(str);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public :
|
||||||
|
BOOST_CONCEPT_USAGE(VArrayStrategy)
|
||||||
|
{
|
||||||
|
check_methods::apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}} // namespace boost::container::container_detail::concept
|
||||||
|
|
||||||
|
#endif //BOOST_CONTAINER_VARRAY_CONCEPT_HPP
|
712
bench/detail/varray_util.hpp
Normal file
712
bench/detail/varray_util.hpp
Normal file
@@ -0,0 +1,712 @@
|
|||||||
|
// Boost.Container
|
||||||
|
//
|
||||||
|
// varray details
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
|
||||||
|
// Copyright (c) 2011-2013 Andrew Hundt.
|
||||||
|
//
|
||||||
|
// Use, modification and distribution is subject to the Boost Software License,
|
||||||
|
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#ifndef BOOST_CONTAINER_DETAIL_VARRAY_UTIL_HPP
|
||||||
|
#define BOOST_CONTAINER_DETAIL_VARRAY_UTIL_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstring>
|
||||||
|
#include <memory>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include <boost/mpl/if.hpp>
|
||||||
|
#include <boost/mpl/and.hpp>
|
||||||
|
#include <boost/mpl/or.hpp>
|
||||||
|
#include <boost/mpl/int.hpp>
|
||||||
|
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
#include <boost/type_traits/remove_const.hpp>
|
||||||
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
|
#include <boost/type_traits/has_trivial_assign.hpp>
|
||||||
|
#include <boost/type_traits/has_trivial_copy.hpp>
|
||||||
|
#include <boost/type_traits/has_trivial_constructor.hpp>
|
||||||
|
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||||
|
//#include <boost/type_traits/has_nothrow_constructor.hpp>
|
||||||
|
//#include <boost/type_traits/has_nothrow_copy.hpp>
|
||||||
|
//#include <boost/type_traits/has_nothrow_assign.hpp>
|
||||||
|
//#include <boost/type_traits/has_nothrow_destructor.hpp>
|
||||||
|
|
||||||
|
#include <boost/detail/no_exceptions_support.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/move/move.hpp>
|
||||||
|
#include <boost/utility/addressof.hpp>
|
||||||
|
#include <boost/iterator/iterator_traits.hpp>
|
||||||
|
|
||||||
|
// TODO - move vectors iterators optimization to the other, optional file instead of checking defines?
|
||||||
|
|
||||||
|
#if defined(BOOST_CONTAINER_VARRAY_ENABLE_VECTORS_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/container/vector.hpp>
|
||||||
|
#endif // BOOST_CONTAINER_VARRAY_ENABLE_ITERATORS_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
|
||||||
|
|
||||||
|
namespace boost { namespace container { namespace varray_detail {
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
struct are_elements_contiguous : boost::is_pointer<I>
|
||||||
|
{};
|
||||||
|
|
||||||
|
#if defined(BOOST_CONTAINER_VARRAY_ENABLE_VECTORS_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
|
||||||
|
|
||||||
|
template <typename Pointer>
|
||||||
|
struct are_elements_contiguous<
|
||||||
|
boost::container::container_detail::vector_const_iterator<Pointer>
|
||||||
|
> : boost::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <typename Pointer>
|
||||||
|
struct are_elements_contiguous<
|
||||||
|
boost::container::container_detail::vector_iterator<Pointer>
|
||||||
|
> : boost::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
|
#if defined(BOOST_DINKUMWARE_STDLIB)
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct are_elements_contiguous<
|
||||||
|
std::_Vector_const_iterator<T>
|
||||||
|
> : boost::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct are_elements_contiguous<
|
||||||
|
std::_Vector_iterator<T>
|
||||||
|
> : boost::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
|
#elif defined(BOOST_GNU_STDLIB)
|
||||||
|
|
||||||
|
template <typename P, typename T, typename A>
|
||||||
|
struct are_elements_contiguous<
|
||||||
|
__gnu_cxx::__normal_iterator<P, std::vector<T, A> >
|
||||||
|
> : boost::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
|
#elif defined(_LIBCPP_VERSION)
|
||||||
|
|
||||||
|
// TODO - test it first
|
||||||
|
//template <typename P>
|
||||||
|
//struct are_elements_contiguous<
|
||||||
|
// __wrap_iter<P>
|
||||||
|
//> : boost::true_type
|
||||||
|
//{};
|
||||||
|
|
||||||
|
#else // OTHER_STDLIB
|
||||||
|
|
||||||
|
// TODO - add other iterators implementations
|
||||||
|
|
||||||
|
#endif // STDLIB
|
||||||
|
|
||||||
|
#endif // BOOST_CONTAINER_VARRAY_ENABLE_VECTORS_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
|
||||||
|
|
||||||
|
}}} // namespace boost::container::varray_detail
|
||||||
|
|
||||||
|
namespace boost { namespace container { namespace varray_detail {
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
struct are_corresponding :
|
||||||
|
::boost::mpl::and_<
|
||||||
|
::boost::is_same<
|
||||||
|
::boost::remove_const<
|
||||||
|
typename ::boost::iterator_value<I>::type
|
||||||
|
>,
|
||||||
|
::boost::remove_const<
|
||||||
|
typename ::boost::iterator_value<O>::type
|
||||||
|
>
|
||||||
|
>,
|
||||||
|
are_elements_contiguous<I>,
|
||||||
|
are_elements_contiguous<O>
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <typename I, typename V>
|
||||||
|
struct is_corresponding_value :
|
||||||
|
::boost::is_same<
|
||||||
|
::boost::remove_const<
|
||||||
|
typename ::boost::iterator_value<I>::type
|
||||||
|
>,
|
||||||
|
::boost::remove_const<V>
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
|
// destroy(I, I)
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
void destroy_dispatch(I /*first*/, I /*last*/,
|
||||||
|
boost::true_type const& /*has_trivial_destructor*/)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
void destroy_dispatch(I first, I last,
|
||||||
|
boost::false_type const& /*has_trivial_destructor*/)
|
||||||
|
{
|
||||||
|
typedef typename boost::iterator_value<I>::type value_type;
|
||||||
|
for ( ; first != last ; ++first )
|
||||||
|
first->~value_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
void destroy(I first, I last)
|
||||||
|
{
|
||||||
|
typedef typename boost::iterator_value<I>::type value_type;
|
||||||
|
destroy_dispatch(first, last, has_trivial_destructor<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
// destroy(I)
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
void destroy_dispatch(I /*pos*/,
|
||||||
|
boost::true_type const& /*has_trivial_destructor*/)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
void destroy_dispatch(I pos,
|
||||||
|
boost::false_type const& /*has_trivial_destructor*/)
|
||||||
|
{
|
||||||
|
typedef typename boost::iterator_value<I>::type value_type;
|
||||||
|
pos->~value_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
void destroy(I pos)
|
||||||
|
{
|
||||||
|
typedef typename boost::iterator_value<I>::type value_type;
|
||||||
|
destroy_dispatch(pos, has_trivial_destructor<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy(I, I, O)
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline O copy_dispatch(I first, I last, O dst,
|
||||||
|
boost::mpl::bool_<true> const& /*use_memmove*/)
|
||||||
|
{
|
||||||
|
typedef typename boost::iterator_value<I>::type value_type;
|
||||||
|
typename boost::iterator_difference<I>::type d = std::distance(first, last);
|
||||||
|
|
||||||
|
::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
|
||||||
|
return dst + d;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline O copy_dispatch(I first, I last, O dst,
|
||||||
|
boost::mpl::bool_<false> const& /*use_memmove*/)
|
||||||
|
{
|
||||||
|
return std::copy(first, last, dst); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline O copy(I first, I last, O dst)
|
||||||
|
{
|
||||||
|
typedef typename
|
||||||
|
::boost::mpl::and_<
|
||||||
|
are_corresponding<I, O>,
|
||||||
|
::boost::has_trivial_assign<
|
||||||
|
typename ::boost::iterator_value<O>::type
|
||||||
|
>
|
||||||
|
>::type
|
||||||
|
use_memmove;
|
||||||
|
|
||||||
|
return copy_dispatch(first, last, dst, use_memmove()); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
// uninitialized_copy(I, I, O)
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline
|
||||||
|
O uninitialized_copy_dispatch(I first, I last, O dst,
|
||||||
|
boost::mpl::bool_<true> const& /*use_memcpy*/)
|
||||||
|
{
|
||||||
|
typedef typename boost::iterator_value<I>::type value_type;
|
||||||
|
typename boost::iterator_difference<I>::type d = std::distance(first, last);
|
||||||
|
|
||||||
|
::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
|
||||||
|
return dst + d;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I, typename F>
|
||||||
|
inline
|
||||||
|
F uninitialized_copy_dispatch(I first, I last, F dst,
|
||||||
|
boost::mpl::bool_<false> const& /*use_memcpy*/)
|
||||||
|
{
|
||||||
|
return std::uninitialized_copy(first, last, dst); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I, typename F>
|
||||||
|
inline
|
||||||
|
F uninitialized_copy(I first, I last, F dst)
|
||||||
|
{
|
||||||
|
typedef typename
|
||||||
|
::boost::mpl::and_<
|
||||||
|
are_corresponding<I, F>,
|
||||||
|
::boost::has_trivial_copy<
|
||||||
|
typename ::boost::iterator_value<F>::type
|
||||||
|
>
|
||||||
|
>::type
|
||||||
|
use_memcpy;
|
||||||
|
|
||||||
|
return uninitialized_copy_dispatch(first, last, dst, use_memcpy()); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
// uninitialized_move(I, I, O)
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline
|
||||||
|
O uninitialized_move_dispatch(I first, I last, O dst,
|
||||||
|
boost::mpl::bool_<true> const& /*use_memcpy*/)
|
||||||
|
{
|
||||||
|
typedef typename boost::iterator_value<I>::type value_type;
|
||||||
|
typename boost::iterator_difference<I>::type d = std::distance(first, last);
|
||||||
|
|
||||||
|
::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
|
||||||
|
return dst + d;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline
|
||||||
|
O uninitialized_move_dispatch(I first, I last, O dst,
|
||||||
|
boost::mpl::bool_<false> const& /*use_memcpy*/)
|
||||||
|
{
|
||||||
|
//return boost::uninitialized_move(first, last, dst); // may throw
|
||||||
|
|
||||||
|
O o = dst;
|
||||||
|
|
||||||
|
BOOST_TRY
|
||||||
|
{
|
||||||
|
typedef typename std::iterator_traits<O>::value_type value_type;
|
||||||
|
for (; first != last; ++first, ++o )
|
||||||
|
new (boost::addressof(*o)) value_type(boost::move(*first));
|
||||||
|
}
|
||||||
|
BOOST_CATCH(...)
|
||||||
|
{
|
||||||
|
destroy(dst, o);
|
||||||
|
BOOST_RETHROW;
|
||||||
|
}
|
||||||
|
BOOST_CATCH_END
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline
|
||||||
|
O uninitialized_move(I first, I last, O dst)
|
||||||
|
{
|
||||||
|
typedef typename
|
||||||
|
::boost::mpl::and_<
|
||||||
|
are_corresponding<I, O>,
|
||||||
|
::boost::has_trivial_copy<
|
||||||
|
typename ::boost::iterator_value<O>::type
|
||||||
|
>
|
||||||
|
>::type
|
||||||
|
use_memcpy;
|
||||||
|
|
||||||
|
return uninitialized_move_dispatch(first, last, dst, use_memcpy()); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO - move uses memmove - implement 2nd version using memcpy?
|
||||||
|
|
||||||
|
// move(I, I, O)
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline
|
||||||
|
O move_dispatch(I first, I last, O dst,
|
||||||
|
boost::mpl::bool_<true> const& /*use_memmove*/)
|
||||||
|
{
|
||||||
|
typedef typename boost::iterator_value<I>::type value_type;
|
||||||
|
typename boost::iterator_difference<I>::type d = std::distance(first, last);
|
||||||
|
|
||||||
|
::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
|
||||||
|
return dst + d;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline
|
||||||
|
O move_dispatch(I first, I last, O dst,
|
||||||
|
boost::mpl::bool_<false> const& /*use_memmove*/)
|
||||||
|
{
|
||||||
|
return boost::move(first, last, dst); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline
|
||||||
|
O move(I first, I last, O dst)
|
||||||
|
{
|
||||||
|
typedef typename
|
||||||
|
::boost::mpl::and_<
|
||||||
|
are_corresponding<I, O>,
|
||||||
|
::boost::has_trivial_assign<
|
||||||
|
typename ::boost::iterator_value<O>::type
|
||||||
|
>
|
||||||
|
>::type
|
||||||
|
use_memmove;
|
||||||
|
|
||||||
|
return move_dispatch(first, last, dst, use_memmove()); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
// move_backward(BDI, BDI, BDO)
|
||||||
|
|
||||||
|
template <typename BDI, typename BDO>
|
||||||
|
inline
|
||||||
|
BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
|
||||||
|
boost::mpl::bool_<true> const& /*use_memmove*/)
|
||||||
|
{
|
||||||
|
typedef typename boost::iterator_value<BDI>::type value_type;
|
||||||
|
typename boost::iterator_difference<BDI>::type d = std::distance(first, last);
|
||||||
|
|
||||||
|
BDO foo(dst - d);
|
||||||
|
::memmove(boost::addressof(*foo), boost::addressof(*first), sizeof(value_type) * d);
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename BDI, typename BDO>
|
||||||
|
inline
|
||||||
|
BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
|
||||||
|
boost::mpl::bool_<false> const& /*use_memmove*/)
|
||||||
|
{
|
||||||
|
return boost::move_backward(first, last, dst); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename BDI, typename BDO>
|
||||||
|
inline
|
||||||
|
BDO move_backward(BDI first, BDI last, BDO dst)
|
||||||
|
{
|
||||||
|
typedef typename
|
||||||
|
::boost::mpl::and_<
|
||||||
|
are_corresponding<BDI, BDO>,
|
||||||
|
::boost::has_trivial_assign<
|
||||||
|
typename ::boost::iterator_value<BDO>::type
|
||||||
|
>
|
||||||
|
>::type
|
||||||
|
use_memmove;
|
||||||
|
|
||||||
|
return move_backward_dispatch(first, last, dst, use_memmove()); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct has_nothrow_move : public
|
||||||
|
::boost::mpl::or_<
|
||||||
|
boost::mpl::bool_<
|
||||||
|
::boost::has_nothrow_move<
|
||||||
|
typename ::boost::remove_const<T>::type
|
||||||
|
>::value
|
||||||
|
>,
|
||||||
|
boost::mpl::bool_<
|
||||||
|
::boost::has_nothrow_move<T>::value
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
|
// uninitialized_move_if_noexcept(I, I, O)
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline
|
||||||
|
O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<true> const& /*use_move*/)
|
||||||
|
{ return uninitialized_move(first, last, dst); }
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline
|
||||||
|
O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<false> const& /*use_move*/)
|
||||||
|
{ return uninitialized_copy(first, last, dst); }
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline
|
||||||
|
O uninitialized_move_if_noexcept(I first, I last, O dst)
|
||||||
|
{
|
||||||
|
typedef typename has_nothrow_move<
|
||||||
|
typename ::boost::iterator_value<O>::type
|
||||||
|
>::type use_move;
|
||||||
|
|
||||||
|
return uninitialized_move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
// move_if_noexcept(I, I, O)
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline
|
||||||
|
O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<true> const& /*use_move*/)
|
||||||
|
{ return move(first, last, dst); }
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline
|
||||||
|
O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<false> const& /*use_move*/)
|
||||||
|
{ return copy(first, last, dst); }
|
||||||
|
|
||||||
|
template <typename I, typename O>
|
||||||
|
inline
|
||||||
|
O move_if_noexcept(I first, I last, O dst)
|
||||||
|
{
|
||||||
|
typedef typename has_nothrow_move<
|
||||||
|
typename ::boost::iterator_value<O>::type
|
||||||
|
>::type use_move;
|
||||||
|
|
||||||
|
return move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
// uninitialized_fill(I, I)
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
inline
|
||||||
|
void uninitialized_fill_dispatch(I first, I last,
|
||||||
|
boost::true_type const& /*has_trivial_constructor*/,
|
||||||
|
boost::true_type const& /*disable_trivial_init*/)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
inline
|
||||||
|
void uninitialized_fill_dispatch(I first, I last,
|
||||||
|
boost::true_type const& /*has_trivial_constructor*/,
|
||||||
|
boost::false_type const& /*disable_trivial_init*/)
|
||||||
|
{
|
||||||
|
typedef typename boost::iterator_value<I>::type value_type;
|
||||||
|
for ( ; first != last ; ++first )
|
||||||
|
new (boost::addressof(*first)) value_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I, typename DisableTrivialInit>
|
||||||
|
inline
|
||||||
|
void uninitialized_fill_dispatch(I first, I last,
|
||||||
|
boost::false_type const& /*has_trivial_constructor*/,
|
||||||
|
DisableTrivialInit const& /*not_used*/)
|
||||||
|
{
|
||||||
|
typedef typename boost::iterator_value<I>::type value_type;
|
||||||
|
I it = first;
|
||||||
|
|
||||||
|
BOOST_TRY
|
||||||
|
{
|
||||||
|
for ( ; it != last ; ++it )
|
||||||
|
new (boost::addressof(*it)) value_type(); // may throw
|
||||||
|
}
|
||||||
|
BOOST_CATCH(...)
|
||||||
|
{
|
||||||
|
destroy(first, it);
|
||||||
|
BOOST_RETHROW;
|
||||||
|
}
|
||||||
|
BOOST_CATCH_END
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I, typename DisableTrivialInit>
|
||||||
|
inline
|
||||||
|
void uninitialized_fill(I first, I last, DisableTrivialInit const& disable_trivial_init)
|
||||||
|
{
|
||||||
|
typedef typename boost::iterator_value<I>::type value_type;
|
||||||
|
uninitialized_fill_dispatch(first, last, boost::has_trivial_constructor<value_type>(), disable_trivial_init); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct(I)
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
inline
|
||||||
|
void construct_dispatch(boost::mpl::bool_<true> const& /*dont_init*/, I pos)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
inline
|
||||||
|
void construct_dispatch(boost::mpl::bool_<false> const& /*dont_init*/, I pos)
|
||||||
|
{
|
||||||
|
typedef typename ::boost::iterator_value<I>::type value_type;
|
||||||
|
new (static_cast<void*>(::boost::addressof(*pos))) value_type(); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename DisableTrivialInit, typename I>
|
||||||
|
inline
|
||||||
|
void construct(DisableTrivialInit const&, I pos)
|
||||||
|
{
|
||||||
|
typedef typename ::boost::iterator_value<I>::type value_type;
|
||||||
|
typedef typename ::boost::mpl::and_<
|
||||||
|
boost::has_trivial_constructor<value_type>,
|
||||||
|
DisableTrivialInit
|
||||||
|
>::type dont_init;
|
||||||
|
|
||||||
|
construct_dispatch(dont_init(), pos); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct(I, V)
|
||||||
|
|
||||||
|
template <typename I, typename V>
|
||||||
|
inline
|
||||||
|
void construct_dispatch(I pos, V const& v,
|
||||||
|
boost::mpl::bool_<true> const& /*use_memcpy*/)
|
||||||
|
{
|
||||||
|
::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I, typename P>
|
||||||
|
inline
|
||||||
|
void construct_dispatch(I pos, P const& p,
|
||||||
|
boost::mpl::bool_<false> const& /*use_memcpy*/)
|
||||||
|
{
|
||||||
|
typedef typename boost::iterator_value<I>::type V;
|
||||||
|
new (static_cast<void*>(boost::addressof(*pos))) V(p); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename DisableTrivialInit, typename I, typename P>
|
||||||
|
inline
|
||||||
|
void construct(DisableTrivialInit const&,
|
||||||
|
I pos, P const& p)
|
||||||
|
{
|
||||||
|
typedef typename
|
||||||
|
::boost::mpl::and_<
|
||||||
|
is_corresponding_value<I, P>,
|
||||||
|
::boost::has_trivial_copy<P>
|
||||||
|
>::type
|
||||||
|
use_memcpy;
|
||||||
|
|
||||||
|
construct_dispatch(pos, p, use_memcpy()); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
// Needed by push_back(V &&)
|
||||||
|
|
||||||
|
template <typename DisableTrivialInit, typename I, typename P>
|
||||||
|
inline
|
||||||
|
void construct(DisableTrivialInit const&, I pos, BOOST_RV_REF(P) p)
|
||||||
|
{
|
||||||
|
typedef typename
|
||||||
|
::boost::mpl::and_<
|
||||||
|
is_corresponding_value<I, P>,
|
||||||
|
::boost::has_trivial_copy<P>
|
||||||
|
>::type
|
||||||
|
use_memcpy;
|
||||||
|
|
||||||
|
typedef typename boost::iterator_value<I>::type V;
|
||||||
|
new (static_cast<void*>(boost::addressof(*pos))) V(::boost::move(p)); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
// Needed by emplace_back() and emplace()
|
||||||
|
|
||||||
|
#if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE)
|
||||||
|
#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
template <typename DisableTrivialInit, typename I, class ...Args>
|
||||||
|
inline
|
||||||
|
void construct(DisableTrivialInit const&,
|
||||||
|
I pos,
|
||||||
|
BOOST_FWD_REF(Args) ...args)
|
||||||
|
{
|
||||||
|
typedef typename boost::iterator_value<I>::type V;
|
||||||
|
new (static_cast<void*>(boost::addressof(*pos))) V(::boost::forward<Args>(args)...); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // !BOOST_NO_VARIADIC_TEMPLATES
|
||||||
|
|
||||||
|
// BOOST_NO_RVALUE_REFERENCES -> P0 const& p0
|
||||||
|
// !BOOST_NO_RVALUE_REFERENCES -> P0 && p0
|
||||||
|
// which means that version with one parameter may take V const& v
|
||||||
|
|
||||||
|
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||||
|
template <typename DisableTrivialInit, typename I, typename P BOOST_PP_ENUM_TRAILING_PARAMS(n, typename P) > \
|
||||||
|
inline \
|
||||||
|
void construct(DisableTrivialInit const&, \
|
||||||
|
I pos, \
|
||||||
|
BOOST_CONTAINER_PP_PARAM(P, p) \
|
||||||
|
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
||||||
|
{ \
|
||||||
|
typedef typename boost::iterator_value<I>::type V; \
|
||||||
|
new \
|
||||||
|
(static_cast<void*>(boost::addressof(*pos))) \
|
||||||
|
V(p, BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); /*may throw*/ \
|
||||||
|
} \
|
||||||
|
//
|
||||||
|
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
||||||
|
#include BOOST_PP_LOCAL_ITERATE()
|
||||||
|
|
||||||
|
#endif // !BOOST_NO_VARIADIC_TEMPLATES
|
||||||
|
#endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
|
||||||
|
|
||||||
|
// assign(I, V)
|
||||||
|
|
||||||
|
template <typename I, typename V>
|
||||||
|
inline
|
||||||
|
void assign_dispatch(I pos, V const& v,
|
||||||
|
boost::mpl::bool_<true> const& /*use_memcpy*/)
|
||||||
|
{
|
||||||
|
::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I, typename V>
|
||||||
|
inline
|
||||||
|
void assign_dispatch(I pos, V const& v,
|
||||||
|
boost::mpl::bool_<false> const& /*use_memcpy*/)
|
||||||
|
{
|
||||||
|
*pos = v; // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I, typename V>
|
||||||
|
inline
|
||||||
|
void assign(I pos, V const& v)
|
||||||
|
{
|
||||||
|
typedef typename
|
||||||
|
::boost::mpl::and_<
|
||||||
|
is_corresponding_value<I, V>,
|
||||||
|
::boost::has_trivial_assign<V>
|
||||||
|
>::type
|
||||||
|
use_memcpy;
|
||||||
|
|
||||||
|
assign_dispatch(pos, v, use_memcpy()); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I, typename V>
|
||||||
|
inline
|
||||||
|
void assign(I pos, BOOST_RV_REF(V) v)
|
||||||
|
{
|
||||||
|
*pos = boost::move(v); // may throw
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// uninitialized_copy_s
|
||||||
|
|
||||||
|
template <typename I, typename F>
|
||||||
|
inline std::size_t uninitialized_copy_s(I first, I last, F dest, std::size_t max_count)
|
||||||
|
{
|
||||||
|
std::size_t count = 0;
|
||||||
|
F it = dest;
|
||||||
|
|
||||||
|
BOOST_TRY
|
||||||
|
{
|
||||||
|
for ( ; first != last ; ++it, ++first, ++count )
|
||||||
|
{
|
||||||
|
if ( max_count <= count )
|
||||||
|
return (std::numeric_limits<std::size_t>::max)();
|
||||||
|
|
||||||
|
// dummy 0 as DisableTrivialInit
|
||||||
|
construct(0, it, *first); // may throw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BOOST_CATCH(...)
|
||||||
|
{
|
||||||
|
destroy(dest, it);
|
||||||
|
BOOST_RETHROW;
|
||||||
|
}
|
||||||
|
BOOST_CATCH_END
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// scoped_destructor
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class scoped_destructor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
scoped_destructor(T * ptr) : m_ptr(ptr) {}
|
||||||
|
|
||||||
|
~scoped_destructor()
|
||||||
|
{
|
||||||
|
if(m_ptr)
|
||||||
|
destroy(m_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void release() { m_ptr = 0; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
T * m_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
}}} // namespace boost::container::varray_detail
|
||||||
|
|
||||||
|
#endif // BOOST_CONTAINER_DETAIL_VARRAY_UTIL_HPP
|
994
bench/varray.hpp
Normal file
994
bench/varray.hpp
Normal file
@@ -0,0 +1,994 @@
|
|||||||
|
// Boost.Container varray
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
|
||||||
|
// Copyright (c) 2011-2013 Andrew Hundt.
|
||||||
|
//
|
||||||
|
// Use, modification and distribution is subject to the Boost Software License,
|
||||||
|
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#ifndef BOOST_CONTAINER_VARRAY_HPP
|
||||||
|
#define BOOST_CONTAINER_VARRAY_HPP
|
||||||
|
|
||||||
|
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/container/detail/config_begin.hpp>
|
||||||
|
|
||||||
|
#include "detail/varray.hpp"
|
||||||
|
|
||||||
|
namespace boost { namespace container {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup varray_non_member varray non-member functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A variable-size array container with fixed capacity.
|
||||||
|
*
|
||||||
|
* varray is a sequence container like boost::container::vector with contiguous storage that can
|
||||||
|
* change in size, along with the static allocation, low overhead, and fixed capacity of boost::array.
|
||||||
|
*
|
||||||
|
* A varray is a sequence that supports random access to elements, constant time insertion and
|
||||||
|
* removal of elements at the end, and linear time insertion and removal of elements at the beginning or
|
||||||
|
* in the middle. The number of elements in a varray may vary dynamically up to a fixed capacity
|
||||||
|
* because elements are stored within the object itself similarly to an array. However, objects are
|
||||||
|
* initialized as they are inserted into varray unlike C arrays or std::array which must construct
|
||||||
|
* all elements on instantiation. The behavior of varray enables the use of statically allocated
|
||||||
|
* elements in cases with complex object lifetime requirements that would otherwise not be trivially
|
||||||
|
* possible.
|
||||||
|
*
|
||||||
|
* @par Error Handling
|
||||||
|
* Insertion beyond the capacity and out of bounds errors result in undefined behavior.
|
||||||
|
* The reason for this is because unlike vectors, varray does not perform allocation.
|
||||||
|
*
|
||||||
|
* @tparam Value The type of element that will be stored.
|
||||||
|
* @tparam Capacity The maximum number of elements varray can store, fixed at compile time.
|
||||||
|
*/
|
||||||
|
template <typename Value, std::size_t Capacity>
|
||||||
|
class varray
|
||||||
|
: public container_detail::varray<Value, Capacity>
|
||||||
|
{
|
||||||
|
typedef container_detail::varray<Value, Capacity> base_t;
|
||||||
|
|
||||||
|
BOOST_COPYABLE_AND_MOVABLE(varray)
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! @brief The type of elements stored in the container.
|
||||||
|
typedef typename base_t::value_type value_type;
|
||||||
|
//! @brief The unsigned integral type used by the container.
|
||||||
|
typedef typename base_t::size_type size_type;
|
||||||
|
//! @brief The pointers difference type.
|
||||||
|
typedef typename base_t::difference_type difference_type;
|
||||||
|
//! @brief The pointer type.
|
||||||
|
typedef typename base_t::pointer pointer;
|
||||||
|
//! @brief The const pointer type.
|
||||||
|
typedef typename base_t::const_pointer const_pointer;
|
||||||
|
//! @brief The value reference type.
|
||||||
|
typedef typename base_t::reference reference;
|
||||||
|
//! @brief The value const reference type.
|
||||||
|
typedef typename base_t::const_reference const_reference;
|
||||||
|
//! @brief The iterator type.
|
||||||
|
typedef typename base_t::iterator iterator;
|
||||||
|
//! @brief The const iterator type.
|
||||||
|
typedef typename base_t::const_iterator const_iterator;
|
||||||
|
//! @brief The reverse iterator type.
|
||||||
|
typedef typename base_t::reverse_iterator reverse_iterator;
|
||||||
|
//! @brief The const reverse iterator.
|
||||||
|
typedef typename base_t::const_reverse_iterator const_reverse_iterator;
|
||||||
|
|
||||||
|
//! @brief Constructs an empty varray.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
varray()
|
||||||
|
: base_t()
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! @pre <tt>count <= capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Constructs a varray containing count default constructed 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).
|
||||||
|
explicit varray(size_type count)
|
||||||
|
: base_t(count)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! @pre <tt>count <= capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Constructs a varray containing count copies of value.
|
||||||
|
//!
|
||||||
|
//! @param count The number of copies of a values that will be contained in the container.
|
||||||
|
//! @param value The value which will be used to copy construct values.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's copy constructor throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
varray(size_type count, value_type const& value)
|
||||||
|
: base_t(count, value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! @pre
|
||||||
|
//! @li <tt>distance(first, last) <= capacity()</tt>
|
||||||
|
//! @li Iterator must meet the \c ForwardTraversalIterator concept.
|
||||||
|
//!
|
||||||
|
//! @brief Constructs a varray containing copy of a range <tt>[first, last)</tt>.
|
||||||
|
//!
|
||||||
|
//! @param first The iterator to the first element in range.
|
||||||
|
//! @param last The iterator to the one after the last element in range.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's constructor taking a dereferenced Iterator throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template <typename Iterator>
|
||||||
|
varray(Iterator first, Iterator last)
|
||||||
|
: base_t(first, last)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! @brief Constructs a copy of other varray.
|
||||||
|
//!
|
||||||
|
//! @param other The varray which content will be copied to this one.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's copy constructor throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
varray(varray const& other)
|
||||||
|
: base_t(other)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! @pre <tt>other.size() <= capacity()</tt>.
|
||||||
|
//!
|
||||||
|
//! @brief Constructs a copy of other varray.
|
||||||
|
//!
|
||||||
|
//! @param other The varray which content will be copied to this one.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's copy constructor throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template <std::size_t C>
|
||||||
|
varray(varray<value_type, C> const& other) : base_t(other) {}
|
||||||
|
|
||||||
|
//! @brief Copy assigns Values stored in the other varray to this one.
|
||||||
|
//!
|
||||||
|
//! @param other The varray which content will be copied to this one.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's copy constructor or copy assignment throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
varray & operator=(BOOST_COPY_ASSIGN_REF(varray) other)
|
||||||
|
{
|
||||||
|
base_t::operator=(static_cast<base_t const&>(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @pre <tt>other.size() <= capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Copy assigns Values stored in the other varray to this one.
|
||||||
|
//!
|
||||||
|
//! @param other The varray which content will be copied to this one.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's copy constructor or copy assignment throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template <std::size_t C>
|
||||||
|
// TEMPORARY WORKAROUND
|
||||||
|
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
||||||
|
varray & operator=(::boost::rv< varray<value_type, C> > const& other)
|
||||||
|
#else
|
||||||
|
varray & operator=(varray<value_type, C> const& other)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
base_t::operator=(static_cast<varray<value_type, C> const&>(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Move constructor. Moves Values stored in the other varray to this one.
|
||||||
|
//!
|
||||||
|
//! @param other The varray which content will be moved to this one.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
|
||||||
|
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
varray(BOOST_RV_REF(varray) other)
|
||||||
|
: base_t(boost::move(static_cast<base_t&>(other)))
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! @pre <tt>other.size() <= capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Move constructor. Moves Values stored in the other varray to this one.
|
||||||
|
//!
|
||||||
|
//! @param other The varray which content will be moved to this one.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
|
||||||
|
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template <std::size_t C>
|
||||||
|
varray(BOOST_RV_REF_2_TEMPL_ARGS(varray, value_type, C) other)
|
||||||
|
: base_t(boost::move(static_cast<container_detail::varray<value_type, C>&>(other)))
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! @brief Move assignment. Moves Values stored in the other varray to this one.
|
||||||
|
//!
|
||||||
|
//! @param other The varray which content will be moved to this one.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
|
||||||
|
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
varray & operator=(BOOST_RV_REF(varray) other)
|
||||||
|
{
|
||||||
|
base_t::operator=(boost::move(static_cast<base_t&>(other)));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @pre <tt>other.size() <= capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Move assignment. Moves Values stored in the other varray to this one.
|
||||||
|
//!
|
||||||
|
//! @param other The varray which content will be moved to this one.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
|
||||||
|
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template <std::size_t C>
|
||||||
|
varray & operator=(BOOST_RV_REF_2_TEMPL_ARGS(varray, value_type, C) other)
|
||||||
|
{
|
||||||
|
base_t::operator=(boost::move(static_cast<container_detail::varray<value_type, C>&>(other)));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
|
|
||||||
|
//! @brief Destructor. Destroys Values stored in this container.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
~varray();
|
||||||
|
|
||||||
|
//! @brief Swaps contents of the other varray and this one.
|
||||||
|
//!
|
||||||
|
//! @param other The varray which content will be swapped with this one's content.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
|
||||||
|
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
void swap(varray & other);
|
||||||
|
|
||||||
|
//! @pre <tt>other.size() <= capacity() && size() <= other.capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Swaps contents of the other varray and this one.
|
||||||
|
//!
|
||||||
|
//! @param other The varray which content will be swapped with this one's content.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
|
||||||
|
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template <std::size_t C>
|
||||||
|
void swap(varray<value_type, C> & other);
|
||||||
|
|
||||||
|
//! @pre <tt>count <= capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Inserts or erases elements at the end such that
|
||||||
|
//! the size becomes count. New elements are default constructed.
|
||||||
|
//!
|
||||||
|
//! @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).
|
||||||
|
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 copy constructed from value.
|
||||||
|
//!
|
||||||
|
//! @param count The number of elements which will be stored in the container.
|
||||||
|
//! @param value The value used to copy construct the new element.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's copy constructor throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
void resize(size_type count, value_type const& value);
|
||||||
|
|
||||||
|
//! @pre <tt>count <= capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief This call has no effect because the Capacity of this container is constant.
|
||||||
|
//!
|
||||||
|
//! @param count The number of elements which the container should be able to contain.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
void reserve(size_type count);
|
||||||
|
|
||||||
|
//! @pre <tt>size() < capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Adds a copy of value at the end.
|
||||||
|
//!
|
||||||
|
//! @param value The value used to copy construct the new element.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's copy constructor throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
void push_back(value_type const& value);
|
||||||
|
|
||||||
|
//! @pre <tt>size() < capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Moves value to the end.
|
||||||
|
//!
|
||||||
|
//! @param value The value to move construct the new element.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's move constructor throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
void push_back(BOOST_RV_REF(value_type) value);
|
||||||
|
|
||||||
|
//! @pre <tt>!empty()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Destroys last value and decreases the size.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing by default.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
void pop_back();
|
||||||
|
|
||||||
|
//! @pre
|
||||||
|
//! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
|
||||||
|
//! @li <tt>size() < capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Inserts a copy of element at position.
|
||||||
|
//!
|
||||||
|
//! @param position The position at which the new value will be inserted.
|
||||||
|
//! @param value The value used to copy construct the new element.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! @li If Value's copy constructor or copy assignment throws
|
||||||
|
//! @li If Value's move constructor or move assignment throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant or linear.
|
||||||
|
iterator insert(iterator position, value_type const& value);
|
||||||
|
|
||||||
|
//! @pre
|
||||||
|
//! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
|
||||||
|
//! @li <tt>size() < capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Inserts a move-constructed element at position.
|
||||||
|
//!
|
||||||
|
//! @param position The position at which the new value will be inserted.
|
||||||
|
//! @param value The value used to move construct the new element.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's move constructor or move assignment throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant or linear.
|
||||||
|
iterator insert(iterator position, BOOST_RV_REF(value_type) value);
|
||||||
|
|
||||||
|
//! @pre
|
||||||
|
//! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
|
||||||
|
//! @li <tt>size() + count <= capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Inserts a count copies of value at position.
|
||||||
|
//!
|
||||||
|
//! @param position The position at which new elements will be inserted.
|
||||||
|
//! @param count The number of new elements which will be inserted.
|
||||||
|
//! @param value The value used to copy construct new elements.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! @li If Value's copy constructor or copy assignment throws.
|
||||||
|
//! @li If Value's move constructor or move assignment throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
iterator insert(iterator position, size_type count, value_type const& value);
|
||||||
|
|
||||||
|
//! @pre
|
||||||
|
//! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
|
||||||
|
//! @li <tt>distance(first, last) <= capacity()</tt>
|
||||||
|
//! @li \c Iterator must meet the \c ForwardTraversalIterator concept.
|
||||||
|
//!
|
||||||
|
//! @brief Inserts a copy of a range <tt>[first, last)</tt> at position.
|
||||||
|
//!
|
||||||
|
//! @param position The position at which new elements will be inserted.
|
||||||
|
//! @param first The iterator to the first element of a range used to construct new elements.
|
||||||
|
//! @param last The iterator to the one after the last element of a range used to construct new elements.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! @li If Value's constructor and assignment taking a dereferenced \c Iterator.
|
||||||
|
//! @li If Value's move constructor or move assignment throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template <typename Iterator>
|
||||||
|
iterator insert(iterator position, Iterator first, Iterator last);
|
||||||
|
|
||||||
|
//! @pre \c position must be a valid iterator of \c *this in range <tt>[begin(), end())</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Erases Value from position.
|
||||||
|
//!
|
||||||
|
//! @param position The position of the element which will be erased from the container.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's move assignment throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
iterator erase(iterator position);
|
||||||
|
|
||||||
|
//! @pre
|
||||||
|
//! @li \c first and \c last must define a valid range
|
||||||
|
//! @li iterators must be in range <tt>[begin(), end()]</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Erases Values from a range <tt>[first, last)</tt>.
|
||||||
|
//!
|
||||||
|
//! @param first The position of the first element of a range which will be erased from the container.
|
||||||
|
//! @param last The position of the one after the last element of a range which will be erased from the container.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's move assignment throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
iterator erase(iterator first, iterator last);
|
||||||
|
|
||||||
|
//! @pre <tt>distance(first, last) <= capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Assigns a range <tt>[first, last)</tt> of Values to this container.
|
||||||
|
//!
|
||||||
|
//! @param first The iterator to the first element of a range used to construct new content of this container.
|
||||||
|
//! @param last The iterator to the one after the last element of a range used to construct new content of this container.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's copy constructor or copy assignment throws,
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template <typename Iterator>
|
||||||
|
void assign(Iterator first, Iterator last);
|
||||||
|
|
||||||
|
//! @pre <tt>count <= capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Assigns a count copies of value to this container.
|
||||||
|
//!
|
||||||
|
//! @param count The new number of elements which will be container in the container.
|
||||||
|
//! @param value The value which will be used to copy construct the new content.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's copy constructor or copy assignment throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
void assign(size_type count, value_type const& value);
|
||||||
|
|
||||||
|
//! @pre <tt>size() < capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Inserts a Value constructed with
|
||||||
|
//! \c std::forward<Args>(args)... in the end of the container.
|
||||||
|
//!
|
||||||
|
//! @param args The arguments of the constructor of the new element which will be created at the end of the container.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If in-place constructor throws or Value's move constructor throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
template<class ...Args>
|
||||||
|
void emplace_back(Args &&...args);
|
||||||
|
|
||||||
|
//! @pre
|
||||||
|
//! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>
|
||||||
|
//! @li <tt>size() < capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Inserts a Value constructed with
|
||||||
|
//! \c std::forward<Args>(args)... before position
|
||||||
|
//!
|
||||||
|
//! @param position The position at which new elements will be inserted.
|
||||||
|
//! @param args The arguments of the constructor of the new element.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If in-place constructor throws or if Value's move constructor or move assignment throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant or linear.
|
||||||
|
template<class ...Args>
|
||||||
|
iterator emplace(iterator position, Args &&...args);
|
||||||
|
|
||||||
|
//! @brief Removes all elements from the container.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
//! @pre <tt>i < size()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Returns reference to the i-th element.
|
||||||
|
//!
|
||||||
|
//! @param i The element's index.
|
||||||
|
//!
|
||||||
|
//! @return reference to the i-th element
|
||||||
|
//! from the beginning of the container.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! \c std::out_of_range exception by default.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
reference at(size_type i);
|
||||||
|
|
||||||
|
//! @pre <tt>i < size()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Returns const reference to the i-th element.
|
||||||
|
//!
|
||||||
|
//! @param i The element's index.
|
||||||
|
//!
|
||||||
|
//! @return const reference to the i-th element
|
||||||
|
//! from the beginning of the container.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! \c std::out_of_range exception by default.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
const_reference at(size_type i) const;
|
||||||
|
|
||||||
|
//! @pre <tt>i < size()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Returns reference to the i-th element.
|
||||||
|
//!
|
||||||
|
//! @param i The element's index.
|
||||||
|
//!
|
||||||
|
//! @return reference to the i-th element
|
||||||
|
//! from the beginning of the container.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing by default.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
reference operator[](size_type i);
|
||||||
|
|
||||||
|
//! @pre <tt>i < size()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Returns const reference to the i-th element.
|
||||||
|
//!
|
||||||
|
//! @param i The element's index.
|
||||||
|
//!
|
||||||
|
//! @return const reference to the i-th element
|
||||||
|
//! from the beginning of the container.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing by default.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
const_reference operator[](size_type i) const;
|
||||||
|
|
||||||
|
//! @pre \c !empty()
|
||||||
|
//!
|
||||||
|
//! @brief Returns reference to the first element.
|
||||||
|
//!
|
||||||
|
//! @return reference to the first element
|
||||||
|
//! from the beginning of the container.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing by default.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
reference front();
|
||||||
|
|
||||||
|
//! @pre \c !empty()
|
||||||
|
//!
|
||||||
|
//! @brief Returns const reference to the first element.
|
||||||
|
//!
|
||||||
|
//! @return const reference to the first element
|
||||||
|
//! from the beginning of the container.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing by default.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
const_reference front() const;
|
||||||
|
|
||||||
|
//! @pre \c !empty()
|
||||||
|
//!
|
||||||
|
//! @brief Returns reference to the last element.
|
||||||
|
//!
|
||||||
|
//! @return reference to the last element
|
||||||
|
//! from the beginning of the container.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing by default.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
reference back();
|
||||||
|
|
||||||
|
//! @pre \c !empty()
|
||||||
|
//!
|
||||||
|
//! @brief Returns const reference to the first element.
|
||||||
|
//!
|
||||||
|
//! @return const reference to the last element
|
||||||
|
//! from the beginning of the container.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing by default.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
const_reference back() const;
|
||||||
|
|
||||||
|
//! @brief Pointer such that <tt>[data(), data() + size())</tt> is a valid range.
|
||||||
|
//! For a non-empty vector <tt>data() == &front()</tt>.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
Value * data();
|
||||||
|
|
||||||
|
//! @brief Const pointer such that <tt>[data(), data() + size())</tt> is a valid range.
|
||||||
|
//! For a non-empty vector <tt>data() == &front()</tt>.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
const Value * data() const;
|
||||||
|
|
||||||
|
//! @brief Returns iterator to the first element.
|
||||||
|
//!
|
||||||
|
//! @return iterator to the first element contained in the vector.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
iterator begin();
|
||||||
|
|
||||||
|
//! @brief Returns const iterator to the first element.
|
||||||
|
//!
|
||||||
|
//! @return const_iterator to the first element contained in the vector.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
const_iterator begin() const;
|
||||||
|
|
||||||
|
//! @brief Returns const iterator to the first element.
|
||||||
|
//!
|
||||||
|
//! @return const_iterator to the first element contained in the vector.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
const_iterator cbegin() const;
|
||||||
|
|
||||||
|
//! @brief Returns iterator to the one after the last element.
|
||||||
|
//!
|
||||||
|
//! @return iterator pointing to the one after the last element contained in the vector.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
iterator end();
|
||||||
|
|
||||||
|
//! @brief Returns const iterator to the one after the last element.
|
||||||
|
//!
|
||||||
|
//! @return const_iterator pointing to the one after the last element contained in the vector.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
const_iterator end() const;
|
||||||
|
|
||||||
|
//! @brief Returns const iterator to the one after the last element.
|
||||||
|
//!
|
||||||
|
//! @return const_iterator pointing to the one after the last element contained in the vector.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
const_iterator cend() const;
|
||||||
|
|
||||||
|
//! @brief Returns reverse iterator to the first element of the reversed container.
|
||||||
|
//!
|
||||||
|
//! @return reverse_iterator pointing to the beginning
|
||||||
|
//! of the reversed varray.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
reverse_iterator rbegin();
|
||||||
|
|
||||||
|
//! @brief Returns const reverse iterator to the first element of the reversed container.
|
||||||
|
//!
|
||||||
|
//! @return const_reverse_iterator pointing to the beginning
|
||||||
|
//! of the reversed varray.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
const_reverse_iterator rbegin() const;
|
||||||
|
|
||||||
|
//! @brief Returns const reverse iterator to the first element of the reversed container.
|
||||||
|
//!
|
||||||
|
//! @return const_reverse_iterator pointing to the beginning
|
||||||
|
//! of the reversed varray.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
const_reverse_iterator crbegin() const;
|
||||||
|
|
||||||
|
//! @brief Returns reverse iterator to the one after the last element of the reversed container.
|
||||||
|
//!
|
||||||
|
//! @return reverse_iterator pointing to the one after the last element
|
||||||
|
//! of the reversed varray.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
reverse_iterator rend();
|
||||||
|
|
||||||
|
//! @brief Returns const reverse iterator to the one after the last element of the reversed container.
|
||||||
|
//!
|
||||||
|
//! @return const_reverse_iterator pointing to the one after the last element
|
||||||
|
//! of the reversed varray.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
const_reverse_iterator rend() const;
|
||||||
|
|
||||||
|
//! @brief Returns const reverse iterator to the one after the last element of the reversed container.
|
||||||
|
//!
|
||||||
|
//! @return const_reverse_iterator pointing to the one after the last element
|
||||||
|
//! of the reversed varray.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
const_reverse_iterator crend() const;
|
||||||
|
|
||||||
|
//! @brief Returns container's capacity.
|
||||||
|
//!
|
||||||
|
//! @return container's capacity.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
static size_type capacity();
|
||||||
|
|
||||||
|
//! @brief Returns container's capacity.
|
||||||
|
//!
|
||||||
|
//! @return container's capacity.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
static size_type max_size();
|
||||||
|
|
||||||
|
//! @brief Returns the number of stored elements.
|
||||||
|
//!
|
||||||
|
//! @return Number of elements contained in the container.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
size_type size() const;
|
||||||
|
|
||||||
|
//! @brief Queries if the container contains elements.
|
||||||
|
//!
|
||||||
|
//! @return true if the number of elements contained in the
|
||||||
|
//! container is equal to 0.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! Nothing.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Constant O(1).
|
||||||
|
bool empty() const;
|
||||||
|
|
||||||
|
#endif // BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
|
|
||||||
|
//! @brief Checks if contents of two varrays are equal.
|
||||||
|
//!
|
||||||
|
//! @ingroup varray_non_member
|
||||||
|
//!
|
||||||
|
//! @param x The first varray.
|
||||||
|
//! @param y The second varray.
|
||||||
|
//!
|
||||||
|
//! @return \c true if containers have the same size and elements in both containers are equal.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template<typename V, std::size_t C1, std::size_t C2>
|
||||||
|
bool operator== (varray<V, C1> const& x, varray<V, C2> const& y);
|
||||||
|
|
||||||
|
//! @brief Checks if contents of two varrays are not equal.
|
||||||
|
//!
|
||||||
|
//! @ingroup varray_non_member
|
||||||
|
//!
|
||||||
|
//! @param x The first varray.
|
||||||
|
//! @param y The second varray.
|
||||||
|
//!
|
||||||
|
//! @return \c true if containers have different size or elements in both containers are not equal.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template<typename V, std::size_t C1, std::size_t C2>
|
||||||
|
bool operator!= (varray<V, C1> const& x, varray<V, C2> const& y);
|
||||||
|
|
||||||
|
//! @brief Lexicographically compares varrays.
|
||||||
|
//!
|
||||||
|
//! @ingroup varray_non_member
|
||||||
|
//!
|
||||||
|
//! @param x The first varray.
|
||||||
|
//! @param y The second varray.
|
||||||
|
//!
|
||||||
|
//! @return \c true if x compares lexicographically less than y.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template<typename V, std::size_t C1, std::size_t C2>
|
||||||
|
bool operator< (varray<V, C1> const& x, varray<V, C2> const& y);
|
||||||
|
|
||||||
|
//! @brief Lexicographically compares varrays.
|
||||||
|
//!
|
||||||
|
//! @ingroup varray_non_member
|
||||||
|
//!
|
||||||
|
//! @param x The first varray.
|
||||||
|
//! @param y The second varray.
|
||||||
|
//!
|
||||||
|
//! @return \c true if y compares lexicographically less than x.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template<typename V, std::size_t C1, std::size_t C2>
|
||||||
|
bool operator> (varray<V, C1> const& x, varray<V, C2> const& y);
|
||||||
|
|
||||||
|
//! @brief Lexicographically compares varrays.
|
||||||
|
//!
|
||||||
|
//! @ingroup varray_non_member
|
||||||
|
//!
|
||||||
|
//! @param x The first varray.
|
||||||
|
//! @param y The second varray.
|
||||||
|
//!
|
||||||
|
//! @return \c true if y don't compare lexicographically less than x.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template<typename V, std::size_t C1, std::size_t C2>
|
||||||
|
bool operator<= (varray<V, C1> const& x, varray<V, C2> const& y);
|
||||||
|
|
||||||
|
//! @brief Lexicographically compares varrays.
|
||||||
|
//!
|
||||||
|
//! @ingroup varray_non_member
|
||||||
|
//!
|
||||||
|
//! @param x The first varray.
|
||||||
|
//! @param y The second varray.
|
||||||
|
//!
|
||||||
|
//! @return \c true if x don't compare lexicographically less than y.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template<typename V, std::size_t C1, std::size_t C2>
|
||||||
|
bool operator>= (varray<V, C1> const& x, varray<V, C2> const& y);
|
||||||
|
|
||||||
|
//! @brief Swaps contents of two varrays.
|
||||||
|
//!
|
||||||
|
//! This function calls varray::swap().
|
||||||
|
//!
|
||||||
|
//! @ingroup varray_non_member
|
||||||
|
//!
|
||||||
|
//! @param x The first varray.
|
||||||
|
//! @param y The second varray.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template<typename V, std::size_t C1, std::size_t C2>
|
||||||
|
inline void swap(varray<V, C1> & x, varray<V, C2> & y);
|
||||||
|
|
||||||
|
#endif // BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
|
|
||||||
|
}} // namespace boost::container
|
||||||
|
|
||||||
|
#include <boost/container/detail/config_end.hpp>
|
||||||
|
|
||||||
|
#endif // BOOST_CONTAINER_VARRAY_HPP
|
@@ -663,7 +663,8 @@ use [*Boost.Container]? There are several reasons for that:
|
|||||||
|
|
||||||
* Support for `BOOST_NO_EXCEPTIONS` [@https://svn.boost.org/trac/boost/ticket/7227 #7227].
|
* Support for `BOOST_NO_EXCEPTIONS` [@https://svn.boost.org/trac/boost/ticket/7227 #7227].
|
||||||
* Fixed bugs [@https://svn.boost.org/trac/boost/ticket/7921 #7921],
|
* Fixed bugs [@https://svn.boost.org/trac/boost/ticket/7921 #7921],
|
||||||
[@https://svn.boost.org/trac/boost/ticket/7969 #7969].
|
[@https://svn.boost.org/trac/boost/ticket/7969 #7969],
|
||||||
|
[@https://svn.boost.org/trac/boost/ticket/8118 #8118].
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
@@ -250,7 +250,19 @@ struct allocator_traits
|
|||||||
|
|
||||||
//! <b>Returns</b>: `a.select_on_container_copy_construction()` if that expression is well-formed;
|
//! <b>Returns</b>: `a.select_on_container_copy_construction()` if that expression is well-formed;
|
||||||
//! otherwise, a.
|
//! otherwise, a.
|
||||||
static Alloc select_on_container_copy_construction(const Alloc &a)
|
static
|
||||||
|
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
|
typename container_detail::if_c
|
||||||
|
< boost::container::container_detail::
|
||||||
|
has_member_function_callable_with_select_on_container_copy_construction
|
||||||
|
<const Alloc>::value
|
||||||
|
, Alloc
|
||||||
|
, const Alloc &
|
||||||
|
>::type
|
||||||
|
#else
|
||||||
|
Alloc
|
||||||
|
#endif
|
||||||
|
select_on_container_copy_construction(const Alloc &a)
|
||||||
{
|
{
|
||||||
const bool value = boost::container::container_detail::
|
const bool value = boost::container::container_detail::
|
||||||
has_member_function_callable_with_select_on_container_copy_construction
|
has_member_function_callable_with_select_on_container_copy_construction
|
||||||
@@ -295,7 +307,7 @@ struct allocator_traits
|
|||||||
static Alloc priv_select_on_container_copy_construction(boost::true_type, const Alloc &a)
|
static Alloc priv_select_on_container_copy_construction(boost::true_type, const Alloc &a)
|
||||||
{ return a.select_on_container_copy_construction(); }
|
{ return a.select_on_container_copy_construction(); }
|
||||||
|
|
||||||
static Alloc priv_select_on_container_copy_construction(boost::false_type, const Alloc &a)
|
static const Alloc &priv_select_on_container_copy_construction(boost::false_type, const Alloc &a)
|
||||||
{ return a; }
|
{ return a; }
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
@@ -89,10 +89,10 @@ struct insert_n_copies_proxy
|
|||||||
: a_(a), v_(v)
|
: a_(a), v_(v)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void uninitialized_copy_n_and_update(Iterator p, size_type n)
|
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
|
||||||
{ boost::container::uninitialized_fill_alloc_n(this->a_, v_, n, p); }
|
{ boost::container::uninitialized_fill_alloc_n(this->a_, v_, n, p); }
|
||||||
|
|
||||||
void copy_n_and_update(Iterator p, size_type n)
|
void copy_n_and_update(Iterator p, size_type n) const
|
||||||
{ std::fill_n(p, n, v_); }
|
{ std::fill_n(p, n, v_); }
|
||||||
|
|
||||||
A &a_;
|
A &a_;
|
||||||
@@ -111,10 +111,10 @@ struct insert_default_constructed_n_proxy
|
|||||||
: a_(a)
|
: a_(a)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void uninitialized_copy_n_and_update(Iterator p, size_type n)
|
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_default_alloc_n(this->a_, n, p); }
|
||||||
|
|
||||||
void copy_n_and_update(Iterator, size_type)
|
void copy_n_and_update(Iterator, size_type) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(false);
|
BOOST_ASSERT(false);
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@ struct insert_copy_proxy
|
|||||||
: a_(a), v_(v)
|
: a_(a), v_(v)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void uninitialized_copy_n_and_update(Iterator p, size_type n)
|
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(n == 1); (void)n;
|
BOOST_ASSERT(n == 1); (void)n;
|
||||||
alloc_traits::construct( this->a_
|
alloc_traits::construct( this->a_
|
||||||
@@ -143,7 +143,7 @@ struct insert_copy_proxy
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_n_and_update(Iterator p, size_type n)
|
void copy_n_and_update(Iterator p, size_type n) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(n == 1); (void)n;
|
BOOST_ASSERT(n == 1); (void)n;
|
||||||
*p =v_;
|
*p =v_;
|
||||||
@@ -165,7 +165,7 @@ struct insert_move_proxy
|
|||||||
: a_(a), v_(v)
|
: a_(a), v_(v)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void uninitialized_copy_n_and_update(Iterator p, size_type n)
|
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(n == 1); (void)n;
|
BOOST_ASSERT(n == 1); (void)n;
|
||||||
alloc_traits::construct( this->a_
|
alloc_traits::construct( this->a_
|
||||||
@@ -174,7 +174,7 @@ struct insert_move_proxy
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_n_and_update(Iterator p, size_type n)
|
void copy_n_and_update(Iterator p, size_type n) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(n == 1); (void)n;
|
BOOST_ASSERT(n == 1); (void)n;
|
||||||
*p = ::boost::move(v_);
|
*p = ::boost::move(v_);
|
||||||
|
@@ -57,20 +57,29 @@ class static_storage_allocator
|
|||||||
public:
|
public:
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
|
|
||||||
T* internal_storage() const
|
static_storage_allocator() BOOST_CONTAINER_NOEXCEPT
|
||||||
|
{}
|
||||||
|
|
||||||
|
static_storage_allocator(const static_storage_allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||||
|
{}
|
||||||
|
|
||||||
|
static_storage_allocator & operator=(const static_storage_allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||||
|
{}
|
||||||
|
|
||||||
|
T* internal_storage() const BOOST_CONTAINER_NOEXCEPT
|
||||||
{ return const_cast<T*>(static_cast<const T*>(static_cast<const void*>(&storage))); }
|
{ return const_cast<T*>(static_cast<const T*>(static_cast<const void*>(&storage))); }
|
||||||
|
|
||||||
T* internal_storage()
|
T* internal_storage() BOOST_CONTAINER_NOEXCEPT
|
||||||
{ return static_cast<T*>(static_cast<void*>(&storage)); }
|
{ return static_cast<T*>(static_cast<void*>(&storage)); }
|
||||||
|
|
||||||
static const std::size_t internal_capacity = N;
|
static const std::size_t internal_capacity = N;
|
||||||
|
|
||||||
typedef boost::container::container_detail::version_type<static_storage_allocator, 0> version;
|
typedef boost::container::container_detail::version_type<static_storage_allocator, 0> version;
|
||||||
|
|
||||||
friend bool operator==(const static_storage_allocator &, const static_storage_allocator &)
|
friend bool operator==(const static_storage_allocator &, const static_storage_allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
friend bool operator!=(const static_storage_allocator &, const static_storage_allocator &)
|
friend bool operator!=(const static_storage_allocator &, const static_storage_allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||||
{ return true; }
|
{ return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -123,7 +132,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
static_vector()
|
static_vector() BOOST_CONTAINER_NOEXCEPT
|
||||||
: base_t()
|
: base_t()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -386,7 +395,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Linear O(N).
|
//! Linear O(N).
|
||||||
void reserve(size_type count);
|
void reserve(size_type count) BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @pre <tt>size() < capacity()</tt>
|
//! @pre <tt>size() < capacity()</tt>
|
||||||
//!
|
//!
|
||||||
@@ -594,7 +603,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
void clear();
|
void clear() BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @pre <tt>i < size()</tt>
|
//! @pre <tt>i < size()</tt>
|
||||||
//!
|
//!
|
||||||
@@ -724,7 +733,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
Value * data();
|
Value * data() BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Const pointer such that <tt>[data(), data() + size())</tt> is a valid range.
|
//! @brief Const pointer such that <tt>[data(), data() + size())</tt> is a valid range.
|
||||||
//! For a non-empty vector <tt>data() == &front()</tt>.
|
//! For a non-empty vector <tt>data() == &front()</tt>.
|
||||||
@@ -734,7 +743,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
const Value * data() const;
|
const Value * data() const BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Returns iterator to the first element.
|
//! @brief Returns iterator to the first element.
|
||||||
//!
|
//!
|
||||||
@@ -745,7 +754,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
iterator begin();
|
iterator begin() BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Returns const iterator to the first element.
|
//! @brief Returns const iterator to the first element.
|
||||||
//!
|
//!
|
||||||
@@ -756,7 +765,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
const_iterator begin() const;
|
const_iterator begin() const BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Returns const iterator to the first element.
|
//! @brief Returns const iterator to the first element.
|
||||||
//!
|
//!
|
||||||
@@ -767,7 +776,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
const_iterator cbegin() const;
|
const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Returns iterator to the one after the last element.
|
//! @brief Returns iterator to the one after the last element.
|
||||||
//!
|
//!
|
||||||
@@ -778,7 +787,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
iterator end();
|
iterator end() BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Returns const iterator to the one after the last element.
|
//! @brief Returns const iterator to the one after the last element.
|
||||||
//!
|
//!
|
||||||
@@ -789,7 +798,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
const_iterator end() const;
|
const_iterator end() const BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Returns const iterator to the one after the last element.
|
//! @brief Returns const iterator to the one after the last element.
|
||||||
//!
|
//!
|
||||||
@@ -800,7 +809,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
const_iterator cend() const;
|
const_iterator cend() const BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Returns reverse iterator to the first element of the reversed container.
|
//! @brief Returns reverse iterator to the first element of the reversed container.
|
||||||
//!
|
//!
|
||||||
@@ -812,7 +821,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
reverse_iterator rbegin();
|
reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Returns const reverse iterator to the first element of the reversed container.
|
//! @brief Returns const reverse iterator to the first element of the reversed container.
|
||||||
//!
|
//!
|
||||||
@@ -824,7 +833,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
const_reverse_iterator rbegin() const;
|
const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Returns const reverse iterator to the first element of the reversed container.
|
//! @brief Returns const reverse iterator to the first element of the reversed container.
|
||||||
//!
|
//!
|
||||||
@@ -836,7 +845,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
const_reverse_iterator crbegin() const;
|
const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Returns reverse iterator to the one after the last element of the reversed container.
|
//! @brief Returns reverse iterator to the one after the last element of the reversed container.
|
||||||
//!
|
//!
|
||||||
@@ -848,7 +857,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
reverse_iterator rend();
|
reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Returns const reverse iterator to the one after the last element of the reversed container.
|
//! @brief Returns const reverse iterator to the one after the last element of the reversed container.
|
||||||
//!
|
//!
|
||||||
@@ -860,7 +869,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
const_reverse_iterator rend() const;
|
const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Returns const reverse iterator to the one after the last element of the reversed container.
|
//! @brief Returns const reverse iterator to the one after the last element of the reversed container.
|
||||||
//!
|
//!
|
||||||
@@ -872,7 +881,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
const_reverse_iterator crend() const;
|
const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Returns container's capacity.
|
//! @brief Returns container's capacity.
|
||||||
//!
|
//!
|
||||||
@@ -883,7 +892,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
static size_type capacity();
|
static size_type capacity() BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Returns container's capacity.
|
//! @brief Returns container's capacity.
|
||||||
//!
|
//!
|
||||||
@@ -894,7 +903,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
static size_type max_size();
|
static size_type max_size() BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Returns the number of stored elements.
|
//! @brief Returns the number of stored elements.
|
||||||
//!
|
//!
|
||||||
@@ -905,7 +914,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
size_type size() const;
|
size_type size() const BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
|
||||||
//! @brief Queries if the container contains elements.
|
//! @brief Queries if the container contains elements.
|
||||||
//!
|
//!
|
||||||
@@ -917,7 +926,13 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Constant O(1).
|
//! Constant O(1).
|
||||||
bool empty() const;
|
bool empty() const BOOST_CONTAINER_NOEXCEPT;
|
||||||
|
#else
|
||||||
|
|
||||||
|
friend void swap(static_vector &x, static_vector &y)
|
||||||
|
{
|
||||||
|
x.swap(y);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // BOOST_CONTAINER_DOXYGEN_INVOKED
|
#endif // BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
|
|
||||||
@@ -1026,7 +1041,8 @@ inline void swap(static_vector<V, C1> & x, static_vector<V, C2> & y);
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
template<typename V, std::size_t C1, std::size_t C2>
|
template<typename V, std::size_t C1, std::size_t C2>
|
||||||
inline void swap(static_vector<V, C1> & x, static_vector<V, C2> & y)
|
inline void swap(static_vector<V, C1> & x, static_vector<V, C2> & y
|
||||||
|
, typename container_detail::enable_if_c< C1 != C2>::type * = 0)
|
||||||
{
|
{
|
||||||
x.swap(y);
|
x.swap(y);
|
||||||
}
|
}
|
||||||
|
@@ -89,7 +89,11 @@ class vector_const_iterator
|
|||||||
|
|
||||||
//Constructors
|
//Constructors
|
||||||
vector_const_iterator() BOOST_CONTAINER_NOEXCEPT
|
vector_const_iterator() BOOST_CONTAINER_NOEXCEPT
|
||||||
|
#ifndef NDEBUG
|
||||||
: m_ptr()
|
: m_ptr()
|
||||||
|
#else
|
||||||
|
// No value initialization of m_ptr() to speed up things a bit:
|
||||||
|
#endif
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//Pointer like operators
|
//Pointer like operators
|
||||||
@@ -107,13 +111,13 @@ class vector_const_iterator
|
|||||||
{ ++m_ptr; return *this; }
|
{ ++m_ptr; return *this; }
|
||||||
|
|
||||||
vector_const_iterator operator++(int) BOOST_CONTAINER_NOEXCEPT
|
vector_const_iterator operator++(int) BOOST_CONTAINER_NOEXCEPT
|
||||||
{ Pointer tmp = m_ptr; ++*this; return vector_const_iterator(tmp); }
|
{ return vector_const_iterator(m_ptr++); }
|
||||||
|
|
||||||
vector_const_iterator& operator--() BOOST_CONTAINER_NOEXCEPT
|
vector_const_iterator& operator--() BOOST_CONTAINER_NOEXCEPT
|
||||||
{ --m_ptr; return *this; }
|
{ --m_ptr; return *this; }
|
||||||
|
|
||||||
vector_const_iterator operator--(int) BOOST_CONTAINER_NOEXCEPT
|
vector_const_iterator operator--(int) BOOST_CONTAINER_NOEXCEPT
|
||||||
{ Pointer tmp = m_ptr; --*this; return vector_const_iterator(tmp); }
|
{ return vector_const_iterator(m_ptr--); }
|
||||||
|
|
||||||
//Arithmetic
|
//Arithmetic
|
||||||
vector_const_iterator& operator+=(difference_type off) BOOST_CONTAINER_NOEXCEPT
|
vector_const_iterator& operator+=(difference_type off) BOOST_CONTAINER_NOEXCEPT
|
||||||
@@ -125,11 +129,11 @@ class vector_const_iterator
|
|||||||
friend vector_const_iterator operator+(const vector_const_iterator &x, difference_type off) BOOST_CONTAINER_NOEXCEPT
|
friend vector_const_iterator operator+(const vector_const_iterator &x, difference_type off) BOOST_CONTAINER_NOEXCEPT
|
||||||
{ return vector_const_iterator(x.m_ptr+off); }
|
{ return vector_const_iterator(x.m_ptr+off); }
|
||||||
|
|
||||||
friend vector_const_iterator operator+(difference_type off, const vector_const_iterator& right) BOOST_CONTAINER_NOEXCEPT
|
friend vector_const_iterator operator+(difference_type off, vector_const_iterator right) BOOST_CONTAINER_NOEXCEPT
|
||||||
{ return vector_const_iterator(off + right.m_ptr); }
|
{ right.m_ptr += off; return right; }
|
||||||
|
|
||||||
friend vector_const_iterator operator-(const vector_const_iterator &x, difference_type off) BOOST_CONTAINER_NOEXCEPT
|
friend vector_const_iterator operator-(vector_const_iterator left, difference_type off) BOOST_CONTAINER_NOEXCEPT
|
||||||
{ return vector_const_iterator(x.m_ptr-off); }
|
{ left.m_ptr += off; return left; }
|
||||||
|
|
||||||
friend difference_type operator-(const vector_const_iterator &left, const vector_const_iterator& right) BOOST_CONTAINER_NOEXCEPT
|
friend difference_type operator-(const vector_const_iterator &left, const vector_const_iterator& right) BOOST_CONTAINER_NOEXCEPT
|
||||||
{ return left.m_ptr - right.m_ptr; }
|
{ return left.m_ptr - right.m_ptr; }
|
||||||
@@ -159,9 +163,10 @@ template <class Pointer>
|
|||||||
class vector_iterator
|
class vector_iterator
|
||||||
: public vector_const_iterator<Pointer>
|
: public vector_const_iterator<Pointer>
|
||||||
{
|
{
|
||||||
|
typedef vector_const_iterator<Pointer> base_t;
|
||||||
public:
|
public:
|
||||||
explicit vector_iterator(Pointer ptr) BOOST_CONTAINER_NOEXCEPT
|
explicit vector_iterator(Pointer ptr) BOOST_CONTAINER_NOEXCEPT
|
||||||
: vector_const_iterator<Pointer>(ptr)
|
: base_t(ptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -173,6 +178,7 @@ class vector_iterator
|
|||||||
|
|
||||||
//Constructors
|
//Constructors
|
||||||
vector_iterator() BOOST_CONTAINER_NOEXCEPT
|
vector_iterator() BOOST_CONTAINER_NOEXCEPT
|
||||||
|
: base_t()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//Pointer like operators
|
//Pointer like operators
|
||||||
@@ -180,7 +186,7 @@ class vector_iterator
|
|||||||
{ return *this->m_ptr; }
|
{ return *this->m_ptr; }
|
||||||
|
|
||||||
value_type* operator->() const BOOST_CONTAINER_NOEXCEPT
|
value_type* operator->() const BOOST_CONTAINER_NOEXCEPT
|
||||||
{ return container_detail::to_raw_pointer(this->m_ptr); }
|
{ return container_detail::to_raw_pointer(this->m_ptr); }
|
||||||
|
|
||||||
reference operator[](difference_type off) const BOOST_CONTAINER_NOEXCEPT
|
reference operator[](difference_type off) const BOOST_CONTAINER_NOEXCEPT
|
||||||
{ return this->m_ptr[off]; }
|
{ return this->m_ptr[off]; }
|
||||||
@@ -190,13 +196,13 @@ class vector_iterator
|
|||||||
{ ++this->m_ptr; return *this; }
|
{ ++this->m_ptr; return *this; }
|
||||||
|
|
||||||
vector_iterator operator++(int) BOOST_CONTAINER_NOEXCEPT
|
vector_iterator operator++(int) BOOST_CONTAINER_NOEXCEPT
|
||||||
{ pointer tmp = this->m_ptr; ++*this; return vector_iterator(tmp); }
|
{ return vector_iterator(this->m_ptr++); }
|
||||||
|
|
||||||
vector_iterator& operator--() BOOST_CONTAINER_NOEXCEPT
|
vector_iterator& operator--() BOOST_CONTAINER_NOEXCEPT
|
||||||
{ --this->m_ptr; return *this; }
|
{ --this->m_ptr; return *this; }
|
||||||
|
|
||||||
vector_iterator operator--(int) BOOST_CONTAINER_NOEXCEPT
|
vector_iterator operator--(int) BOOST_CONTAINER_NOEXCEPT
|
||||||
{ vector_iterator tmp = *this; --*this; return vector_iterator(tmp); }
|
{ return vector_iterator(this->m_ptr--); }
|
||||||
|
|
||||||
// Arithmetic
|
// Arithmetic
|
||||||
vector_iterator& operator+=(difference_type off) BOOST_CONTAINER_NOEXCEPT
|
vector_iterator& operator+=(difference_type off) BOOST_CONTAINER_NOEXCEPT
|
||||||
@@ -205,14 +211,14 @@ class vector_iterator
|
|||||||
vector_iterator& operator-=(difference_type off) BOOST_CONTAINER_NOEXCEPT
|
vector_iterator& operator-=(difference_type off) BOOST_CONTAINER_NOEXCEPT
|
||||||
{ this->m_ptr -= off; return *this; }
|
{ this->m_ptr -= off; return *this; }
|
||||||
|
|
||||||
friend vector_iterator operator+(const vector_iterator &x, difference_type off) BOOST_CONTAINER_NOEXCEPT
|
friend vector_iterator operator+(vector_iterator left, difference_type off) BOOST_CONTAINER_NOEXCEPT
|
||||||
{ return vector_iterator(x.m_ptr+off); }
|
{ left.m_ptr += off; return left; }
|
||||||
|
|
||||||
friend vector_iterator operator+(difference_type off, const vector_iterator& right) BOOST_CONTAINER_NOEXCEPT
|
friend vector_iterator operator+(difference_type off, vector_iterator right) BOOST_CONTAINER_NOEXCEPT
|
||||||
{ return vector_iterator(off + right.m_ptr); }
|
{ right.m_ptr += off; return right; }
|
||||||
|
|
||||||
friend vector_iterator operator-(const vector_iterator &x, difference_type off) BOOST_CONTAINER_NOEXCEPT
|
friend vector_iterator operator-(vector_iterator left, difference_type off) BOOST_CONTAINER_NOEXCEPT
|
||||||
{ return vector_iterator(x.m_ptr-off); }
|
{ left.m_ptr -= off; return left; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class Allocator>
|
template <class T, class Allocator>
|
||||||
@@ -271,35 +277,38 @@ struct vector_alloc_holder
|
|||||||
//Constructor, does not throw
|
//Constructor, does not throw
|
||||||
vector_alloc_holder()
|
vector_alloc_holder()
|
||||||
BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor<Allocator>::value)
|
BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor<Allocator>::value)
|
||||||
: Allocator(), m_start(), m_size(0), m_capacity(0)
|
: Allocator(), m_start(), m_size(), m_capacity()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//Constructor, does not throw
|
//Constructor, does not throw
|
||||||
template<class AllocConvertible>
|
template<class AllocConvertible>
|
||||||
explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_CONTAINER_NOEXCEPT
|
explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_CONTAINER_NOEXCEPT
|
||||||
: Allocator(boost::forward<AllocConvertible>(a)), m_start(), m_size(0), m_capacity(0)
|
: Allocator(boost::forward<AllocConvertible>(a)), m_start(), m_size(), m_capacity()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//Constructor, does not throw
|
//Constructor, does not throw
|
||||||
template<class AllocConvertible>
|
template<class AllocConvertible>
|
||||||
explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a, size_type cap)
|
explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a, size_type initial_size)
|
||||||
: Allocator(boost::forward<AllocConvertible>(a)), m_start(), m_size(), m_capacity()
|
: Allocator(boost::forward<AllocConvertible>(a))
|
||||||
|
, m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this
|
||||||
{
|
{
|
||||||
m_start = this->allocation_command
|
m_start = this->allocation_command(allocate_new, initial_size, initial_size, m_capacity, m_start).first;
|
||||||
(allocate_new, cap, cap, m_capacity, m_start).first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Constructor, does not throw
|
//Constructor, does not throw
|
||||||
explicit vector_alloc_holder(size_type cap)
|
explicit vector_alloc_holder(size_type initial_size)
|
||||||
: Allocator(), m_start(), m_size(), m_capacity()
|
: Allocator()
|
||||||
|
, m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this
|
||||||
{
|
{
|
||||||
m_start = this->allocation_command
|
m_start = this->allocation_command
|
||||||
(allocate_new, cap, cap, m_capacity, m_start).first;
|
(allocate_new, initial_size, initial_size, m_capacity, m_start).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_CONTAINER_NOEXCEPT
|
vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_CONTAINER_NOEXCEPT
|
||||||
: Allocator(boost::move(static_cast<Allocator&>(holder)))
|
: Allocator(boost::move(static_cast<Allocator&>(holder)))
|
||||||
, m_start(holder.m_start), m_size(holder.m_size), m_capacity(holder.m_capacity)
|
, m_start(holder.m_start)
|
||||||
|
, m_size(holder.m_size)
|
||||||
|
, m_capacity(holder.m_capacity)
|
||||||
{
|
{
|
||||||
holder.m_start = pointer();
|
holder.m_start = pointer();
|
||||||
holder.m_size = holder.m_capacity = 0;
|
holder.m_size = holder.m_capacity = 0;
|
||||||
@@ -311,6 +320,9 @@ struct vector_alloc_holder
|
|||||||
(allocate_new, cap, cap, m_capacity, m_start).first;
|
(allocate_new, cap, cap, m_capacity, m_start).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void first_allocation_same_allocator_type(size_type cap)
|
||||||
|
{ this->first_allocation(cap); }
|
||||||
|
|
||||||
//Destructor
|
//Destructor
|
||||||
~vector_alloc_holder() BOOST_CONTAINER_NOEXCEPT
|
~vector_alloc_holder() BOOST_CONTAINER_NOEXCEPT
|
||||||
{
|
{
|
||||||
@@ -347,6 +359,9 @@ struct vector_alloc_holder
|
|||||||
container_detail::do_swap(this->m_start, x.m_start);
|
container_detail::do_swap(this->m_start, x.m_start);
|
||||||
container_detail::do_swap(this->m_size, x.m_size);
|
container_detail::do_swap(this->m_size, x.m_size);
|
||||||
container_detail::do_swap(this->m_capacity, x.m_capacity);
|
container_detail::do_swap(this->m_capacity, x.m_capacity);
|
||||||
|
//And now the allocator
|
||||||
|
container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
|
||||||
|
container_detail::swap_alloc(this->alloc(), x.alloc(), flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void move_from_empty(vector_alloc_holder &x) BOOST_CONTAINER_NOEXCEPT
|
void move_from_empty(vector_alloc_holder &x) BOOST_CONTAINER_NOEXCEPT
|
||||||
@@ -400,43 +415,50 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
|
|||||||
//Constructor, does not throw
|
//Constructor, does not throw
|
||||||
vector_alloc_holder()
|
vector_alloc_holder()
|
||||||
BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor<Allocator>::value)
|
BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor<Allocator>::value)
|
||||||
: Allocator(), m_size(0)
|
: Allocator(), m_size()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//Constructor, does not throw
|
//Constructor, does not throw
|
||||||
template<class AllocConvertible>
|
template<class AllocConvertible>
|
||||||
explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_CONTAINER_NOEXCEPT
|
explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_CONTAINER_NOEXCEPT
|
||||||
: Allocator(boost::forward<AllocConvertible>(a)), m_size(0)
|
: Allocator(boost::forward<AllocConvertible>(a)), m_size()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//Constructor, does not throw
|
//Constructor, does not throw
|
||||||
template<class AllocConvertible>
|
template<class AllocConvertible>
|
||||||
explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a, size_type cap)
|
explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a, size_type initial_size)
|
||||||
: Allocator(boost::forward<AllocConvertible>(a)), m_size()
|
: Allocator(boost::forward<AllocConvertible>(a))
|
||||||
|
, m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this
|
||||||
{
|
{
|
||||||
this->first_allocation(cap);
|
this->first_allocation(initial_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Constructor, does not throw
|
//Constructor, does not throw
|
||||||
explicit vector_alloc_holder(size_type cap)
|
explicit vector_alloc_holder(size_type initial_size)
|
||||||
: Allocator(), m_size()
|
: Allocator()
|
||||||
|
, m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this
|
||||||
{
|
{
|
||||||
this->first_allocation(cap);
|
this->first_allocation(initial_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder)
|
vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder)
|
||||||
: Allocator(boost::move(static_cast<Allocator&>(holder)))
|
: Allocator(boost::move(static_cast<Allocator&>(holder)))
|
||||||
, m_size()
|
, m_size(holder.m_size) //Size is initialized here so vector should only call uninitialized_xxx after this
|
||||||
{
|
{
|
||||||
this->priv_move_construct_impl(holder);
|
::boost::container::uninitialized_move_alloc_n
|
||||||
|
(this->alloc(), container_detail::to_raw_pointer(holder.start()), m_size, this->start());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class OtherAllocator, class OtherAllocatorVersion>
|
template<class OtherAllocator, class OtherAllocatorVersion>
|
||||||
vector_alloc_holder(BOOST_RV_REF_BEG vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> BOOST_RV_REF_END holder)
|
vector_alloc_holder(BOOST_RV_REF_BEG vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> BOOST_RV_REF_END holder)
|
||||||
: Allocator()
|
: Allocator()
|
||||||
, m_size()
|
, m_size(holder.m_size) //Initialize it to m_size as first_allocation can only succeed or abort
|
||||||
{
|
{
|
||||||
this->priv_move_construct_impl(holder);
|
//Different allocator type so we must check we have enough storage
|
||||||
|
const size_type n = holder.m_size;
|
||||||
|
this->first_allocation(n);
|
||||||
|
::boost::container::uninitialized_move_alloc_n
|
||||||
|
(this->alloc(), container_detail::to_raw_pointer(holder.start()), n, this->start());
|
||||||
}
|
}
|
||||||
|
|
||||||
void first_allocation(size_type cap)
|
void first_allocation(size_type cap)
|
||||||
@@ -446,6 +468,9 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void first_allocation_same_allocator_type(size_type)
|
||||||
|
{}
|
||||||
|
|
||||||
//Destructor
|
//Destructor
|
||||||
~vector_alloc_holder() BOOST_CONTAINER_NOEXCEPT
|
~vector_alloc_holder() BOOST_CONTAINER_NOEXCEPT
|
||||||
{}
|
{}
|
||||||
@@ -458,7 +483,7 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
|
|||||||
template<class OtherAllocator, class OtherAllocatorVersion>
|
template<class OtherAllocator, class OtherAllocatorVersion>
|
||||||
void swap(vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> &x)
|
void swap(vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> &x)
|
||||||
{
|
{
|
||||||
if(this->m_size > x.capacity() || x.m_size > this->capacity()){
|
if(this->m_size > OtherAllocator::internal_capacity || x.m_size > Allocator::internal_capacity){
|
||||||
throw_bad_alloc();
|
throw_bad_alloc();
|
||||||
}
|
}
|
||||||
this->priv_swap_members_impl(x);
|
this->priv_swap_members_impl(x);
|
||||||
@@ -484,19 +509,6 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template<class OtherAllocator, class OtherAllocatorVersion>
|
|
||||||
void priv_move_construct_impl(vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> &holder)
|
|
||||||
{ //Containers with version 0 allocators can't be moved
|
|
||||||
const size_type n = holder.m_size;
|
|
||||||
this->first_allocation(n);
|
|
||||||
//Copy first new elements in pos
|
|
||||||
container_detail::move_insert_range_proxy<Allocator, const value_type*, value_type*> proxy
|
|
||||||
(this->alloc(), container_detail::to_raw_pointer(holder.start()));
|
|
||||||
proxy.uninitialized_copy_n_and_update
|
|
||||||
(container_detail::to_raw_pointer(this->start()), n);
|
|
||||||
this->m_size = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class OtherAllocator, class OtherAllocatorVersion>
|
template<class OtherAllocator, class OtherAllocatorVersion>
|
||||||
void priv_swap_members_impl(vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> &x)
|
void priv_swap_members_impl(vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> &x)
|
||||||
{
|
{
|
||||||
@@ -530,7 +542,10 @@ template <class T, class Allocator>
|
|||||||
#endif
|
#endif
|
||||||
class vector
|
class vector
|
||||||
{
|
{
|
||||||
container_detail::vector_alloc_holder<Allocator> m_holder;
|
typedef container_detail::integral_constant
|
||||||
|
<unsigned, boost::container::container_detail::version
|
||||||
|
<Allocator>::value > alloc_version;
|
||||||
|
boost::container::container_detail::vector_alloc_holder<Allocator, alloc_version> m_holder;
|
||||||
/// @cond
|
/// @cond
|
||||||
typedef container_detail::vector_alloc_holder<Allocator> base_t;
|
typedef container_detail::vector_alloc_holder<Allocator> base_t;
|
||||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||||
@@ -566,9 +581,6 @@ class vector
|
|||||||
typedef container_detail::integral_constant<unsigned, 0> allocator_v0;
|
typedef container_detail::integral_constant<unsigned, 0> allocator_v0;
|
||||||
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
|
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
|
||||||
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
|
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
|
||||||
typedef container_detail::integral_constant
|
|
||||||
<unsigned, boost::container::container_detail::version
|
|
||||||
<Allocator>::value > alloc_version;
|
|
||||||
|
|
||||||
typedef constant_iterator<T, difference_type> cvalue_iterator;
|
typedef constant_iterator<T, difference_type> cvalue_iterator;
|
||||||
/// @endcond
|
/// @endcond
|
||||||
@@ -609,8 +621,7 @@ class vector
|
|||||||
explicit vector(size_type n)
|
explicit vector(size_type n)
|
||||||
: m_holder(n)
|
: m_holder(n)
|
||||||
{
|
{
|
||||||
this->priv_first_allocation_fill
|
boost::container::uninitialized_default_alloc_n(this->m_holder.alloc(), n, container_detail::to_raw_pointer(this->m_holder.start()));
|
||||||
(container_detail::insert_default_constructed_n_proxy<Allocator, T*> (this->m_holder.alloc()), n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Constructs a vector
|
//! <b>Effects</b>: Constructs a vector
|
||||||
@@ -623,8 +634,8 @@ class vector
|
|||||||
vector(size_type n, const T& value)
|
vector(size_type n, const T& value)
|
||||||
: m_holder(n)
|
: m_holder(n)
|
||||||
{
|
{
|
||||||
this->priv_first_allocation_fill
|
boost::container::uninitialized_fill_alloc_n
|
||||||
(container_detail::insert_n_copies_proxy<Allocator, T*> (this->m_holder.alloc(), value), n);
|
(this->m_holder.alloc(), value, n, container_detail::to_raw_pointer(this->m_holder.start()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
|
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
|
||||||
@@ -637,8 +648,8 @@ class vector
|
|||||||
vector(size_type n, const T& value, const allocator_type& a)
|
vector(size_type n, const T& value, const allocator_type& a)
|
||||||
: m_holder(a, n)
|
: m_holder(a, n)
|
||||||
{
|
{
|
||||||
this->priv_first_allocation_fill
|
boost::container::uninitialized_fill_alloc_n
|
||||||
(container_detail::insert_n_copies_proxy<Allocator, T*> (this->m_holder.alloc(), value), n);
|
(this->m_holder.alloc(), value, n, container_detail::to_raw_pointer(this->m_holder.start()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Constructs a vector
|
//! <b>Effects</b>: Constructs a vector
|
||||||
@@ -676,9 +687,9 @@ class vector
|
|||||||
vector(const vector &x)
|
vector(const vector &x)
|
||||||
: m_holder(allocator_traits_type::select_on_container_copy_construction(x.m_holder.alloc()), x.size())
|
: m_holder(allocator_traits_type::select_on_container_copy_construction(x.m_holder.alloc()), x.size())
|
||||||
{
|
{
|
||||||
this->priv_first_allocation_fill
|
::boost::container::uninitialized_copy_or_move_alloc_n_source
|
||||||
(container_detail::insert_range_proxy<Allocator, const T*, T*>
|
( this->m_holder.alloc(), container_detail::to_raw_pointer(x.m_holder.start())
|
||||||
(this->m_holder.alloc(), container_detail::to_raw_pointer(x.m_holder.start())), x.size());
|
, x.size(), container_detail::to_raw_pointer(this->m_holder.start()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
|
//! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
|
||||||
@@ -717,9 +728,9 @@ class vector
|
|||||||
vector(const vector &x, const allocator_type &a)
|
vector(const vector &x, const allocator_type &a)
|
||||||
: m_holder(a, x.size())
|
: m_holder(a, x.size())
|
||||||
{
|
{
|
||||||
this->priv_first_allocation_fill
|
::boost::container::uninitialized_copy_or_move_alloc_n_source
|
||||||
(container_detail::insert_range_proxy<Allocator, const T*, T*>
|
( this->m_holder.alloc(), container_detail::to_raw_pointer(x.m_holder.start())
|
||||||
(this->m_holder.alloc(), container_detail::to_raw_pointer(x.m_holder.start())), x.size());
|
, x.size(), container_detail::to_raw_pointer(this->m_holder.start()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Move constructor using the specified allocator.
|
//! <b>Effects</b>: Move constructor using the specified allocator.
|
||||||
@@ -737,10 +748,11 @@ class vector
|
|||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
const size_type n = mx.size();
|
const size_type n = mx.size();
|
||||||
this->m_holder.first_allocation(n);
|
this->m_holder.first_allocation_same_allocator_type(n);
|
||||||
this->priv_first_allocation_fill
|
::boost::container::uninitialized_move_alloc_n_source
|
||||||
(container_detail::move_insert_range_proxy<Allocator, const T*, T*>
|
( this->m_holder.alloc(), container_detail::to_raw_pointer(mx.m_holder.start())
|
||||||
(this->m_holder.alloc(), container_detail::to_raw_pointer(mx.m_holder.start())), n);
|
, n, container_detail::to_raw_pointer(this->m_holder.start()));
|
||||||
|
this->m_holder.m_size = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -767,17 +779,7 @@ class vector
|
|||||||
vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x)
|
vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x)
|
||||||
{
|
{
|
||||||
if (&x != this){
|
if (&x != this){
|
||||||
allocator_type &this_alloc = this->m_holder.alloc();
|
this->priv_copy_assign(boost::move(x), alloc_version());
|
||||||
const allocator_type &x_alloc = x.m_holder.alloc();
|
|
||||||
container_detail::bool_<allocator_traits_type::
|
|
||||||
propagate_on_container_copy_assignment::value> flag;
|
|
||||||
if(flag && this_alloc != x_alloc){
|
|
||||||
this->clear();
|
|
||||||
this->shrink_to_fit();
|
|
||||||
}
|
|
||||||
container_detail::assign_alloc(this_alloc, x_alloc, flag);
|
|
||||||
this->assign( container_detail::to_raw_pointer(x.m_holder.start())
|
|
||||||
, container_detail::to_raw_pointer(x.m_holder.start() + x.m_holder.m_size));
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -794,25 +796,7 @@ class vector
|
|||||||
//iG BOOST_CONTAINER_NOEXCEPT_IF(!allocator_type::propagate_on_container_move_assignment::value || is_nothrow_move_assignable<allocator_type>::value);)
|
//iG BOOST_CONTAINER_NOEXCEPT_IF(!allocator_type::propagate_on_container_move_assignment::value || is_nothrow_move_assignable<allocator_type>::value);)
|
||||||
BOOST_CONTAINER_NOEXCEPT
|
BOOST_CONTAINER_NOEXCEPT
|
||||||
{
|
{
|
||||||
if (&x != this){
|
this->priv_move_assign(boost::move(x), alloc_version());
|
||||||
allocator_type &this_alloc = this->m_holder.alloc();
|
|
||||||
allocator_type &x_alloc = x.m_holder.alloc();
|
|
||||||
//If allocators are equal we can just swap pointers
|
|
||||||
if(this_alloc == x_alloc){
|
|
||||||
//Destroy objects but retain memory in case x reuses it in the future
|
|
||||||
this->clear();
|
|
||||||
this->m_holder.swap(x.m_holder);
|
|
||||||
//Move allocator if needed
|
|
||||||
container_detail::bool_<allocator_traits_type::
|
|
||||||
propagate_on_container_move_assignment::value> flag;
|
|
||||||
container_detail::move_alloc(this_alloc, x_alloc, flag);
|
|
||||||
}
|
|
||||||
//If unequal allocators, then do a one by one move
|
|
||||||
else{
|
|
||||||
this->assign( boost::make_move_iterator(container_detail::to_raw_pointer(x.m_holder.start()))
|
|
||||||
, boost::make_move_iterator(container_detail::to_raw_pointer(x.m_holder.start() + x.m_holder.m_size)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -829,8 +813,7 @@ class vector
|
|||||||
template<class OtherAllocator, class OtherAllocatorVersion>
|
template<class OtherAllocator, class OtherAllocatorVersion>
|
||||||
vector& operator=(BOOST_RV_REF_BEG vector<OtherAllocator, OtherAllocatorVersion> BOOST_RV_REF_END x)
|
vector& operator=(BOOST_RV_REF_BEG vector<OtherAllocator, OtherAllocatorVersion> BOOST_RV_REF_END x)
|
||||||
{
|
{
|
||||||
this->assign( boost::make_move_iterator(container_detail::to_raw_pointer(x.m_holder.start()))
|
this->priv_move_assign(boost::move(x), alloc_version());
|
||||||
, boost::make_move_iterator(container_detail::to_raw_pointer(x.m_holder.start() + x.m_holder.m_size)));
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1259,8 +1242,8 @@ class vector
|
|||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
typedef container_detail::insert_emplace_proxy<Allocator, T*, Args...> type;
|
typedef container_detail::insert_emplace_proxy<Allocator, T*, Args...> type;
|
||||||
this->priv_forward_range_insert_at_end
|
this->priv_forward_range_insert_no_capacity
|
||||||
(1, type(this->m_holder.alloc(), ::boost::forward<Args>(args)...), alloc_version());
|
(this->cend().get_ptr(), 1, type(this->m_holder.alloc(), ::boost::forward<Args>(args)...), alloc_version());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1300,7 +1283,8 @@ class vector
|
|||||||
container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
|
container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
|
||||||
<Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
|
<Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
|
||||||
(this->m_holder.alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
|
(this->m_holder.alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
|
||||||
this->priv_forward_range_insert_at_end(1, proxy, alloc_version()); \
|
this->priv_forward_range_insert_no_capacity \
|
||||||
|
(this->cend().get_ptr(), 1, proxy, alloc_version()); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -1482,9 +1466,6 @@ class vector
|
|||||||
{
|
{
|
||||||
//Just swap internals in case of !allocator_v0. Otherwise, deep swap
|
//Just swap internals in case of !allocator_v0. Otherwise, deep swap
|
||||||
this->m_holder.swap(x.m_holder);
|
this->m_holder.swap(x.m_holder);
|
||||||
//And now the allocator
|
|
||||||
container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
|
|
||||||
container_detail::swap_alloc(this->m_holder.alloc(), x.m_holder.alloc(), flag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
@@ -1531,6 +1512,125 @@ class vector
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
template<class OtherAllocator, class AllocVersion>
|
||||||
|
void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
|
||||||
|
, AllocVersion
|
||||||
|
, typename container_detail::enable_if_c
|
||||||
|
< container_detail::is_same<AllocVersion, allocator_v0>::value &&
|
||||||
|
!container_detail::is_same<OtherAllocator, allocator_type>::value
|
||||||
|
>::type * = 0)
|
||||||
|
{
|
||||||
|
if(this->capacity() < x.size()){
|
||||||
|
throw_bad_alloc();
|
||||||
|
}
|
||||||
|
this->priv_move_assign_impl(boost::move(x), AllocVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OtherAllocator, class AllocVersion>
|
||||||
|
void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
|
||||||
|
, AllocVersion
|
||||||
|
, typename container_detail::enable_if_c
|
||||||
|
< !container_detail::is_same<AllocVersion, allocator_v0>::value ||
|
||||||
|
container_detail::is_same<OtherAllocator, allocator_type>::value
|
||||||
|
>::type * = 0)
|
||||||
|
{
|
||||||
|
this->priv_move_assign_impl(boost::move(x), AllocVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OtherAllocator, class AllocVersion>
|
||||||
|
void priv_move_assign_impl(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
|
||||||
|
, AllocVersion
|
||||||
|
, typename container_detail::enable_if_c
|
||||||
|
< container_detail::is_same<AllocVersion, allocator_v0>::value
|
||||||
|
>::type * = 0)
|
||||||
|
{
|
||||||
|
T* const this_start = container_detail::to_raw_pointer(m_holder.start());
|
||||||
|
T* const other_start = container_detail::to_raw_pointer(x.m_holder.start());
|
||||||
|
const size_type this_sz = m_holder.m_size;
|
||||||
|
const size_type other_sz = static_cast<size_type>(x.m_holder.m_size);
|
||||||
|
if (this_sz < other_sz){
|
||||||
|
move_n(other_start, this_sz, this_start); // may throw
|
||||||
|
uninitialized_move_alloc_n( this->m_holder.alloc(), other_start + this_sz
|
||||||
|
, other_sz - this_sz, this_start + this_sz); // may throw
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
move_n(other_start, other_sz, this_start);
|
||||||
|
destroy_alloc_n(this->m_holder.alloc(), this_start + other_sz, this_sz - other_sz);
|
||||||
|
}
|
||||||
|
this->m_holder.m_size = other_sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OtherAllocator, class AllocVersion>
|
||||||
|
void priv_move_assign_impl(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
|
||||||
|
, AllocVersion
|
||||||
|
, typename container_detail::enable_if_c
|
||||||
|
< !container_detail::is_same<AllocVersion, allocator_v0>::value
|
||||||
|
>::type * = 0)
|
||||||
|
{
|
||||||
|
//for move constructor, no aliasing (&x != this) is assummed.
|
||||||
|
allocator_type &this_alloc = this->m_holder.alloc();
|
||||||
|
allocator_type &x_alloc = x.m_holder.alloc();
|
||||||
|
//If allocators are equal we can just swap pointers
|
||||||
|
if(this_alloc == x_alloc){
|
||||||
|
//Destroy objects but retain memory in case x reuses it in the future
|
||||||
|
this->clear();
|
||||||
|
this->m_holder.swap(x.m_holder);
|
||||||
|
//Move allocator if needed
|
||||||
|
container_detail::bool_<allocator_traits_type::
|
||||||
|
propagate_on_container_move_assignment::value> flag;
|
||||||
|
container_detail::move_alloc(this_alloc, x_alloc, flag);
|
||||||
|
}
|
||||||
|
//If unequal allocators, then do a one by one move
|
||||||
|
else{
|
||||||
|
//TO-DO: optimize this
|
||||||
|
this->assign( boost::make_move_iterator(container_detail::to_raw_pointer(x.m_holder.start()))
|
||||||
|
, boost::make_move_iterator(container_detail::to_raw_pointer(x.m_holder.start() + x.m_holder.m_size)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class AllocVersion>
|
||||||
|
void priv_copy_assign(const vector &x, AllocVersion
|
||||||
|
, typename container_detail::enable_if_c
|
||||||
|
< container_detail::is_same<AllocVersion, allocator_v0>::value
|
||||||
|
>::type * = 0)
|
||||||
|
{
|
||||||
|
T* const this_start = container_detail::to_raw_pointer(m_holder.start());
|
||||||
|
T* const other_start = container_detail::to_raw_pointer(x.m_holder.start());
|
||||||
|
const size_type this_sz = m_holder.m_size;
|
||||||
|
const size_type other_sz = static_cast<size_type>(x.m_holder.m_size);
|
||||||
|
if (this_sz < other_sz){
|
||||||
|
copy_or_move_n(other_start, this_sz, this_start); // may throw
|
||||||
|
uninitialized_copy_or_move_alloc_n( this->m_holder.alloc(), other_start + this_sz
|
||||||
|
, other_sz - this_sz, this_start + this_sz); // may throw
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
copy_or_move_n(other_start, other_sz, this_start);
|
||||||
|
destroy_alloc_n(this->m_holder.alloc(), this_start + other_sz, this_sz - other_sz);
|
||||||
|
}
|
||||||
|
this->m_holder.m_size = other_sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class AllocVersion>
|
||||||
|
void priv_copy_assign(const vector &x, AllocVersion
|
||||||
|
, typename container_detail::enable_if_c
|
||||||
|
< !container_detail::is_same<AllocVersion, allocator_v0>::value
|
||||||
|
>::type * = 0)
|
||||||
|
{
|
||||||
|
allocator_type &this_alloc = this->m_holder.alloc();
|
||||||
|
const allocator_type &x_alloc = x.m_holder.alloc();
|
||||||
|
container_detail::bool_<allocator_traits_type::
|
||||||
|
propagate_on_container_copy_assignment::value> flag;
|
||||||
|
if(flag && this_alloc != x_alloc){
|
||||||
|
this->clear();
|
||||||
|
this->shrink_to_fit();
|
||||||
|
}
|
||||||
|
container_detail::assign_alloc(this_alloc, x_alloc, flag);
|
||||||
|
this->assign( container_detail::to_raw_pointer(x.m_holder.start())
|
||||||
|
, container_detail::to_raw_pointer(x.m_holder.start() + x.m_holder.m_size));
|
||||||
|
}
|
||||||
|
|
||||||
void priv_reserve(size_type, allocator_v0)
|
void priv_reserve(size_type, allocator_v0)
|
||||||
{
|
{
|
||||||
throw_bad_alloc();
|
throw_bad_alloc();
|
||||||
@@ -1540,20 +1640,17 @@ class vector
|
|||||||
{
|
{
|
||||||
//There is not enough memory, allocate a new buffer
|
//There is not enough memory, allocate a new buffer
|
||||||
pointer p = this->m_holder.allocate(new_cap);
|
pointer p = this->m_holder.allocate(new_cap);
|
||||||
|
|
||||||
//We will reuse insert code, so create a dummy input iterator
|
|
||||||
container_detail::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*>
|
|
||||||
proxy(this->m_holder.alloc(), ::boost::make_move_iterator((T *)0));
|
|
||||||
//Backwards (and possibly forward) expansion
|
//Backwards (and possibly forward) expansion
|
||||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||||
++this->num_alloc;
|
++this->num_alloc;
|
||||||
#endif
|
#endif
|
||||||
this->priv_range_insert_new_allocation
|
T * const raw_beg = container_detail::to_raw_pointer(this->m_holder.start());
|
||||||
( container_detail::to_raw_pointer(p)
|
const size_type sz = m_holder.m_size;
|
||||||
, new_cap
|
::boost::container::uninitialized_move_alloc_n_source
|
||||||
, container_detail::to_raw_pointer(this->m_holder.start())
|
( this->m_holder.alloc(), raw_beg, sz, container_detail::to_raw_pointer(p) );
|
||||||
, 0
|
destroy_alloc_n(this->m_holder.alloc(), raw_beg, sz);
|
||||||
, proxy);
|
this->m_holder.start(p);
|
||||||
|
this->m_holder.capacity(new_cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void priv_reserve(size_type new_cap, allocator_v2)
|
void priv_reserve(size_type new_cap, allocator_v2)
|
||||||
@@ -1575,14 +1672,13 @@ class vector
|
|||||||
#endif
|
#endif
|
||||||
this->m_holder.capacity(real_cap);
|
this->m_holder.capacity(real_cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
//If there is no forward expansion, move objects
|
//If there is no forward expansion, move objects
|
||||||
else{
|
else{
|
||||||
//We will reuse insert code, so create a dummy input iterator
|
|
||||||
container_detail::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*>
|
|
||||||
proxy(this->m_holder.alloc(), ::boost::make_move_iterator((T *)0));
|
|
||||||
//Backwards (and possibly forward) expansion
|
//Backwards (and possibly forward) expansion
|
||||||
if(ret.second){
|
if(ret.second){
|
||||||
|
//We will reuse insert code, so create a dummy input iterator
|
||||||
|
container_detail::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*>
|
||||||
|
proxy(this->m_holder.alloc(), ::boost::make_move_iterator((T *)0));
|
||||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||||
++this->num_expand_bwd;
|
++this->num_expand_bwd;
|
||||||
#endif
|
#endif
|
||||||
@@ -1595,26 +1691,28 @@ class vector
|
|||||||
}
|
}
|
||||||
//New buffer
|
//New buffer
|
||||||
else{
|
else{
|
||||||
|
//Backwards (and possibly forward) expansion
|
||||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||||
++this->num_alloc;
|
++this->num_alloc;
|
||||||
#endif
|
#endif
|
||||||
this->priv_range_insert_new_allocation
|
T * const raw_beg = container_detail::to_raw_pointer(this->m_holder.start());
|
||||||
( container_detail::to_raw_pointer(ret.first)
|
const size_type sz = m_holder.m_size;
|
||||||
, real_cap
|
::boost::container::uninitialized_move_alloc_n_source
|
||||||
, container_detail::to_raw_pointer(this->m_holder.start())
|
( this->m_holder.alloc(), raw_beg, sz, container_detail::to_raw_pointer(ret.first) );
|
||||||
, 0
|
destroy_alloc_n(this->m_holder.alloc(), raw_beg, sz);
|
||||||
, proxy);
|
this->m_holder.start(ret.first);
|
||||||
|
this->m_holder.capacity(real_cap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Proxy>
|
template<class Proxy>
|
||||||
void priv_first_allocation_fill(Proxy proxy, size_type n)
|
void priv_uninitialized_fill(Proxy proxy, size_type n) const
|
||||||
{
|
{
|
||||||
//Copy first new elements in pos
|
//Copy first new elements in pos
|
||||||
proxy.uninitialized_copy_n_and_update
|
proxy.uninitialized_copy_n_and_update
|
||||||
(container_detail::to_raw_pointer(this->m_holder.start()), n);
|
(container_detail::to_raw_pointer(this->m_holder.start()), n);
|
||||||
this->m_holder.m_size = n;
|
//m_holder.size was already initialized to n in vector_alloc_holder's constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
void priv_destroy(value_type* p) BOOST_CONTAINER_NOEXCEPT
|
void priv_destroy(value_type* p) BOOST_CONTAINER_NOEXCEPT
|
||||||
@@ -1644,19 +1742,35 @@ class vector
|
|||||||
, ::boost::forward<U>(x)), alloc_version());
|
, ::boost::forward<U>(x)), alloc_version());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class U>
|
void priv_push_back(const T &x)
|
||||||
void priv_push_back(BOOST_FWD_REF(U) x)
|
|
||||||
{
|
{
|
||||||
if (this->m_holder.m_size < this->m_holder.capacity()){
|
if (this->m_holder.m_size < this->m_holder.capacity()){
|
||||||
//There is more memory, just construct a new object at the end
|
//There is more memory, just construct a new object at the end
|
||||||
allocator_traits_type::construct
|
allocator_traits_type::construct
|
||||||
( this->m_holder.alloc()
|
( this->m_holder.alloc()
|
||||||
, container_detail::to_raw_pointer(this->m_holder.start() + this->m_holder.m_size)
|
, container_detail::to_raw_pointer(this->m_holder.start() + this->m_holder.m_size)
|
||||||
, ::boost::forward<U>(x) );
|
, x );
|
||||||
++this->m_holder.m_size;
|
++this->m_holder.m_size;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
this->priv_insert(this->cend(), ::boost::forward<U>(x));
|
container_detail::insert_copy_proxy<Allocator, T*> proxy(this->m_holder.alloc(), x);
|
||||||
|
this->priv_forward_range_insert_no_capacity(this->cend().get_ptr(), 1, proxy, alloc_version());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void priv_push_back(BOOST_RV_REF(T) x)
|
||||||
|
{
|
||||||
|
if (this->m_holder.m_size < this->m_holder.capacity()){
|
||||||
|
//There is more memory, just construct a new object at the end
|
||||||
|
allocator_traits_type::construct
|
||||||
|
( this->m_holder.alloc()
|
||||||
|
, container_detail::to_raw_pointer(this->m_holder.start() + this->m_holder.m_size)
|
||||||
|
, ::boost::move(x) );
|
||||||
|
++this->m_holder.m_size;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
container_detail::insert_move_proxy<Allocator, T*> proxy(this->m_holder.alloc(), x);
|
||||||
|
this->priv_forward_range_insert_no_capacity(this->cend().get_ptr(), 1, proxy, alloc_version());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1712,23 +1826,28 @@ class vector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class InsertionProxy>
|
||||||
|
iterator priv_forward_range_insert_no_capacity
|
||||||
|
(const pointer &pos, const size_type, const InsertionProxy , allocator_v0)
|
||||||
|
{
|
||||||
|
throw_bad_alloc();
|
||||||
|
return iterator(pos);
|
||||||
|
}
|
||||||
|
|
||||||
template <class InsertionProxy>
|
template <class InsertionProxy>
|
||||||
iterator priv_forward_range_insert
|
iterator priv_forward_range_insert
|
||||||
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v0)
|
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v0)
|
||||||
{
|
{
|
||||||
//Check if we have enough memory or try to expand current memory
|
//Check if we have enough memory or try to expand current memory
|
||||||
const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
|
const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
|
||||||
const size_type n_pos = pos - this->m_holder.start();
|
|
||||||
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
|
||||||
|
|
||||||
if (n <= remaining){
|
if (n > remaining){
|
||||||
this->priv_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
//This will trigger an error
|
//This will trigger an error
|
||||||
throw_bad_alloc();
|
throw_bad_alloc();
|
||||||
}
|
}
|
||||||
|
const size_type n_pos = pos - this->m_holder.start();
|
||||||
|
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
||||||
|
this->priv_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
|
||||||
return iterator(this->m_holder.start() + n_pos);
|
return iterator(this->m_holder.start() + n_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1739,40 +1858,49 @@ class vector
|
|||||||
//Check if we have enough memory or try to expand current memory
|
//Check if we have enough memory or try to expand current memory
|
||||||
const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
|
const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
|
||||||
|
|
||||||
if (n <= remaining){
|
if (n > remaining){
|
||||||
this->priv_range_insert_at_end_expand_forward(n, insert_range_proxy);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
//This will trigger an error
|
//This will trigger an error
|
||||||
throw_bad_alloc();
|
throw_bad_alloc();
|
||||||
}
|
}
|
||||||
|
this->priv_range_insert_at_end_expand_forward(n, insert_range_proxy);
|
||||||
return this->end();
|
return this->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class InsertionProxy>
|
||||||
|
iterator priv_forward_range_insert_no_capacity
|
||||||
|
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v1)
|
||||||
|
{
|
||||||
|
//Check if we have enough memory or try to expand current memory
|
||||||
|
const size_type n_pos = pos - this->m_holder.start();
|
||||||
|
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
||||||
|
|
||||||
|
const size_type new_cap = this->m_holder.next_capacity(n);
|
||||||
|
T * new_buf = container_detail::to_raw_pointer(this->m_holder.alloc().allocate(new_cap));
|
||||||
|
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||||
|
++this->num_alloc;
|
||||||
|
#endif
|
||||||
|
this->priv_range_insert_new_allocation
|
||||||
|
( new_buf, new_cap, raw_pos, n, insert_range_proxy);
|
||||||
|
return iterator(this->m_holder.start() + n_pos);
|
||||||
|
}
|
||||||
|
|
||||||
template <class InsertionProxy>
|
template <class InsertionProxy>
|
||||||
iterator priv_forward_range_insert
|
iterator priv_forward_range_insert
|
||||||
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v1)
|
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v1)
|
||||||
{
|
{
|
||||||
//Check if we have enough memory or try to expand current memory
|
//Check if we have enough memory or try to expand current memory
|
||||||
const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
|
const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
|
||||||
const size_type n_pos = pos - this->m_holder.start();
|
|
||||||
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
||||||
|
|
||||||
if (n <= remaining){
|
if (n <= remaining){
|
||||||
|
const size_type n_pos = pos - this->m_holder.start();
|
||||||
this->priv_range_insert_expand_forward
|
this->priv_range_insert_expand_forward
|
||||||
(raw_pos, n, insert_range_proxy);
|
(raw_pos, n, insert_range_proxy);
|
||||||
|
return iterator(this->m_holder.start() + n_pos);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
const size_type new_cap = this->m_holder.next_capacity(n);
|
return this->priv_forward_range_insert_no_capacity(pos, n, insert_range_proxy, alloc_version());
|
||||||
T * new_buf = container_detail::to_raw_pointer(this->m_holder.alloc().allocate(new_cap));
|
|
||||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
|
||||||
++this->num_alloc;
|
|
||||||
#endif
|
|
||||||
this->priv_range_insert_new_allocation
|
|
||||||
( new_buf, new_cap, raw_pos, n, insert_range_proxy);
|
|
||||||
}
|
}
|
||||||
return iterator(this->m_holder.start() + n_pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class InsertionProxy>
|
template <class InsertionProxy>
|
||||||
@@ -1782,61 +1910,73 @@ class vector
|
|||||||
return this->priv_forward_range_insert(this->cend().get_ptr(), n, insert_range_proxy, allocator_v1());
|
return this->priv_forward_range_insert(this->cend().get_ptr(), n, insert_range_proxy, allocator_v1());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class InsertionProxy>
|
||||||
|
iterator priv_forward_range_insert_no_capacity
|
||||||
|
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v2)
|
||||||
|
{
|
||||||
|
//Check if we have enough memory or try to expand current memory
|
||||||
|
const size_type n_pos = pos - this->m_holder.start();
|
||||||
|
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
||||||
|
|
||||||
|
size_type real_cap = 0;
|
||||||
|
//There is not enough memory, allocate a new
|
||||||
|
//buffer or expand the old one.
|
||||||
|
std::pair<pointer, bool> ret = (this->m_holder.allocation_command
|
||||||
|
(allocate_new | expand_fwd | expand_bwd,
|
||||||
|
this->m_holder.m_size + n, this->m_holder.next_capacity(n), real_cap, this->m_holder.start()));
|
||||||
|
|
||||||
|
//Buffer reallocated
|
||||||
|
if(ret.second){
|
||||||
|
//Forward expansion, delay insertion
|
||||||
|
if(this->m_holder.start() == ret.first){
|
||||||
|
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||||
|
++this->num_expand_fwd;
|
||||||
|
#endif
|
||||||
|
this->m_holder.capacity(real_cap);
|
||||||
|
//Expand forward
|
||||||
|
this->priv_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
|
||||||
|
}
|
||||||
|
//Backwards (and possibly forward) expansion
|
||||||
|
else{
|
||||||
|
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||||
|
++this->num_expand_bwd;
|
||||||
|
#endif
|
||||||
|
this->priv_range_insert_expand_backwards
|
||||||
|
( container_detail::to_raw_pointer(ret.first)
|
||||||
|
, real_cap, raw_pos, n, insert_range_proxy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//New buffer
|
||||||
|
else{
|
||||||
|
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||||
|
++this->num_alloc;
|
||||||
|
#endif
|
||||||
|
this->priv_range_insert_new_allocation
|
||||||
|
( container_detail::to_raw_pointer(ret.first)
|
||||||
|
, real_cap, raw_pos, n, insert_range_proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
return iterator(this->m_holder.start() + n_pos);
|
||||||
|
}
|
||||||
|
|
||||||
template <class InsertionProxy>
|
template <class InsertionProxy>
|
||||||
iterator priv_forward_range_insert
|
iterator priv_forward_range_insert
|
||||||
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v2)
|
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v2)
|
||||||
{
|
{
|
||||||
//Check if we have enough memory or try to expand current memory
|
//Check if we have enough memory or try to expand current memory
|
||||||
const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
|
const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
|
||||||
const size_type n_pos = pos - this->m_holder.start();
|
|
||||||
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
|
||||||
|
|
||||||
bool same_buffer_start = n <= remaining;
|
bool same_buffer_start = n <= remaining;
|
||||||
if (!same_buffer_start){
|
if (!same_buffer_start){
|
||||||
size_type real_cap = 0;
|
return priv_forward_range_insert_no_capacity(pos, n, insert_range_proxy, alloc_version());
|
||||||
//There is not enough memory, allocate a new
|
|
||||||
//buffer or expand the old one.
|
|
||||||
std::pair<pointer, bool> ret = (this->m_holder.allocation_command
|
|
||||||
(allocate_new | expand_fwd | expand_bwd,
|
|
||||||
this->m_holder.m_size + n, this->m_holder.next_capacity(n), real_cap, this->m_holder.start()));
|
|
||||||
|
|
||||||
//Buffer reallocated
|
|
||||||
if(ret.second){
|
|
||||||
//Forward expansion, delay insertion
|
|
||||||
if(this->m_holder.start() == ret.first){
|
|
||||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
|
||||||
++this->num_expand_fwd;
|
|
||||||
#endif
|
|
||||||
this->m_holder.capacity(real_cap);
|
|
||||||
//Expand forward
|
|
||||||
this->priv_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
|
|
||||||
}
|
|
||||||
//Backwards (and possibly forward) expansion
|
|
||||||
else{
|
|
||||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
|
||||||
++this->num_expand_bwd;
|
|
||||||
#endif
|
|
||||||
this->priv_range_insert_expand_backwards
|
|
||||||
( container_detail::to_raw_pointer(ret.first)
|
|
||||||
, real_cap, raw_pos, n, insert_range_proxy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//New buffer
|
|
||||||
else{
|
|
||||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
|
||||||
++this->num_alloc;
|
|
||||||
#endif
|
|
||||||
this->priv_range_insert_new_allocation
|
|
||||||
( container_detail::to_raw_pointer(ret.first)
|
|
||||||
, real_cap, raw_pos, n, insert_range_proxy);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
//Expand forward
|
//Expand forward
|
||||||
|
const size_type n_pos = pos - this->m_holder.start();
|
||||||
|
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
||||||
this->priv_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
|
this->priv_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
|
||||||
|
return iterator(this->m_holder.start() + n_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
return iterator(this->m_holder.start() + n_pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class InsertionProxy>
|
template <class InsertionProxy>
|
||||||
@@ -1979,7 +2119,8 @@ class vector
|
|||||||
//Case B:
|
//Case B:
|
||||||
else if((first_pos + shift_count) >= limit_pos){
|
else if((first_pos + shift_count) >= limit_pos){
|
||||||
//All uninitialized_moved
|
//All uninitialized_moved
|
||||||
::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), first_ptr, last_ptr, first_ptr + shift_count);
|
::boost::container::uninitialized_move_alloc
|
||||||
|
(this->m_holder.alloc(), first_ptr, last_ptr, first_ptr + shift_count);
|
||||||
hole_size = last_pos + shift_count - limit_pos;
|
hole_size = last_pos + shift_count - limit_pos;
|
||||||
}
|
}
|
||||||
//Case C:
|
//Case C:
|
||||||
|
@@ -59,6 +59,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "throw_exception_test", "thr
|
|||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "static_vector_test", "static_vector_test.vcproj", "{58E1C1C3-096A-84FE-4FA2-D6BA79201C02}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_static_vector", "bench_static_vector.vcproj", "{58E1C1C3-096A-84FE-4FA2-D6BA79201C02}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfiguration) = preSolution
|
GlobalSection(SolutionConfiguration) = preSolution
|
||||||
Debug = Debug
|
Debug = Debug
|
||||||
@@ -127,6 +135,14 @@ Global
|
|||||||
{5A8D91E0-FA57-284F-84FE-D3A6BA792002}.Debug.Build.0 = Debug|Win32
|
{5A8D91E0-FA57-284F-84FE-D3A6BA792002}.Debug.Build.0 = Debug|Win32
|
||||||
{5A8D91E0-FA57-284F-84FE-D3A6BA792002}.Release.ActiveCfg = Release|Win32
|
{5A8D91E0-FA57-284F-84FE-D3A6BA792002}.Release.ActiveCfg = Release|Win32
|
||||||
{5A8D91E0-FA57-284F-84FE-D3A6BA792002}.Release.Build.0 = Release|Win32
|
{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
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
@@ -172,6 +172,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\test\set_test.hpp">
|
RelativePath="..\..\test\set_test.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\test\static_vector_test.hpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\test\util.hpp">
|
RelativePath="..\..\test\util.hpp">
|
||||||
</File>
|
</File>
|
||||||
@@ -221,6 +224,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\boost\container\stable_vector.hpp">
|
RelativePath="..\..\..\..\boost\container\stable_vector.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\..\boost\container\static_vector.hpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\boost\container\string.hpp">
|
RelativePath="..\..\..\..\boost\container\string.hpp">
|
||||||
</File>
|
</File>
|
||||||
@@ -325,6 +331,26 @@
|
|||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="bench"
|
||||||
|
Filter="">
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\bench\varray.hpp">
|
||||||
|
</File>
|
||||||
|
<Filter
|
||||||
|
Name="detail"
|
||||||
|
Filter="">
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\bench\detail\varray.hpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\bench\detail\varray_concept.hpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\bench\detail\varray_util.hpp">
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Filter>
|
||||||
</Files>
|
</Files>
|
||||||
<Globals>
|
<Globals>
|
||||||
</Globals>
|
</Globals>
|
||||||
|
@@ -21,7 +21,7 @@ rule test_all
|
|||||||
|
|
||||||
for local fileb in [ glob *.cpp ]
|
for local fileb in [ glob *.cpp ]
|
||||||
{
|
{
|
||||||
all_rules += [ run $(fileb)
|
all_rules += [ run $(fileb) /boost/timer//boost_timer /boost/system//boost_system /boost/thread//boost_thread
|
||||||
: # additional args
|
: # additional args
|
||||||
: # test-files
|
: # test-files
|
||||||
: # requirements
|
: # requirements
|
||||||
|
@@ -1,92 +0,0 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// (C) Copyright Ion Gaztanaga 2009.
|
|
||||||
// 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/move for documentation.
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
#ifndef BOOST_MOVE_TEST_MOVABLE_HPP
|
|
||||||
#define BOOST_MOVE_TEST_MOVABLE_HPP
|
|
||||||
|
|
||||||
//[movable_definition
|
|
||||||
//header file "movable.hpp"
|
|
||||||
#include <boost/move/move.hpp>
|
|
||||||
|
|
||||||
//A movable class
|
|
||||||
class movable
|
|
||||||
{
|
|
||||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(movable)
|
|
||||||
int value_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
movable() : value_(1){}
|
|
||||||
|
|
||||||
//Move constructor and assignment
|
|
||||||
movable(BOOST_RV_REF(movable) m)
|
|
||||||
{ value_ = m.value_; m.value_ = 0; }
|
|
||||||
|
|
||||||
movable & operator=(BOOST_RV_REF(movable) m)
|
|
||||||
{ value_ = m.value_; m.value_ = 0; return *this; }
|
|
||||||
|
|
||||||
bool moved() const //Observer
|
|
||||||
{ return value_ == 0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class copy_movable
|
|
||||||
{
|
|
||||||
BOOST_COPYABLE_AND_MOVABLE(copy_movable)
|
|
||||||
int value_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
copy_movable(int value = 1) : value_(value){}
|
|
||||||
|
|
||||||
//Move constructor and assignment
|
|
||||||
copy_movable(BOOST_RV_REF(copy_movable) m)
|
|
||||||
{ value_ = m.value_; m.value_ = 0; }
|
|
||||||
|
|
||||||
copy_movable(const copy_movable &m)
|
|
||||||
{ value_ = m.value_; }
|
|
||||||
|
|
||||||
copy_movable & operator=(BOOST_RV_REF(copy_movable) m)
|
|
||||||
{ value_ = m.value_; m.value_ = 0; return *this; }
|
|
||||||
|
|
||||||
copy_movable & operator=(BOOST_COPY_ASSIGN_REF(copy_movable) m)
|
|
||||||
{ value_ = m.value_; return *this; }
|
|
||||||
|
|
||||||
bool moved() const //Observer
|
|
||||||
{ return value_ == 0; }
|
|
||||||
|
|
||||||
bool operator==(const copy_movable& m) const
|
|
||||||
{ return value_ == m.value_; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct copy_movable_wrapper
|
|
||||||
{
|
|
||||||
copy_movable cm;
|
|
||||||
};
|
|
||||||
|
|
||||||
copy_movable produce()
|
|
||||||
{ return copy_movable(); }
|
|
||||||
|
|
||||||
namespace boost{
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct has_nothrow_move<movable>
|
|
||||||
{
|
|
||||||
static const bool value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct has_nothrow_move<copy_movable>
|
|
||||||
{
|
|
||||||
static const bool value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
} //namespace boost{
|
|
||||||
//]
|
|
||||||
|
|
||||||
#endif //BOOST_MOVE_TEST_MOVABLE_HPP
|
|
@@ -53,23 +53,26 @@ class movable_int
|
|||||||
movable_int & operator= (int i)
|
movable_int & operator= (int i)
|
||||||
{ this->m_int = i; return *this; }
|
{ this->m_int = i; return *this; }
|
||||||
|
|
||||||
bool operator ==(const movable_int &mi) const
|
~movable_int()
|
||||||
{ return this->m_int == mi.m_int; }
|
{ this->m_int = 0; }
|
||||||
|
|
||||||
bool operator !=(const movable_int &mi) const
|
friend bool operator ==(const movable_int &l, const movable_int &r)
|
||||||
{ return this->m_int != mi.m_int; }
|
{ return l.m_int == r.m_int; }
|
||||||
|
|
||||||
bool operator <(const movable_int &mi) const
|
friend bool operator !=(const movable_int &l, const movable_int &r)
|
||||||
{ return this->m_int < mi.m_int; }
|
{ return l.m_int != r.m_int; }
|
||||||
|
|
||||||
bool operator <=(const movable_int &mi) const
|
friend bool operator <(const movable_int &l, const movable_int &r)
|
||||||
{ return this->m_int <= mi.m_int; }
|
{ return l.m_int < r.m_int; }
|
||||||
|
|
||||||
bool operator >=(const movable_int &mi) const
|
friend bool operator <=(const movable_int &l, const movable_int &r)
|
||||||
{ return this->m_int >= mi.m_int; }
|
{ return l.m_int <= r.m_int; }
|
||||||
|
|
||||||
bool operator >(const movable_int &mi) const
|
friend bool operator >=(const movable_int &l, const movable_int &r)
|
||||||
{ return this->m_int > mi.m_int; }
|
{ return l.m_int >= r.m_int; }
|
||||||
|
|
||||||
|
friend bool operator >(const movable_int &l, const movable_int &r)
|
||||||
|
{ return l.m_int > r.m_int; }
|
||||||
|
|
||||||
int get_int() const
|
int get_int() const
|
||||||
{ return m_int; }
|
{ return m_int; }
|
||||||
@@ -84,6 +87,9 @@ class movable_int
|
|||||||
int m_int;
|
int m_int;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline movable_int produce_movable_int()
|
||||||
|
{ return movable_int(); }
|
||||||
|
|
||||||
template<class E, class T>
|
template<class E, class T>
|
||||||
std::basic_ostream<E, T> & operator<<
|
std::basic_ostream<E, T> & operator<<
|
||||||
(std::basic_ostream<E, T> & os, movable_int const & p)
|
(std::basic_ostream<E, T> & os, movable_int const & p)
|
||||||
@@ -93,7 +99,6 @@ std::basic_ostream<E, T> & operator<<
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct is_copyable<movable_int>
|
struct is_copyable<movable_int>
|
||||||
{
|
{
|
||||||
@@ -121,6 +126,9 @@ class movable_and_copyable_int
|
|||||||
: m_int(mmi.m_int)
|
: m_int(mmi.m_int)
|
||||||
{ mmi.m_int = 0; }
|
{ mmi.m_int = 0; }
|
||||||
|
|
||||||
|
~movable_and_copyable_int()
|
||||||
|
{ this->m_int = 0; }
|
||||||
|
|
||||||
movable_and_copyable_int &operator= (BOOST_COPY_ASSIGN_REF(movable_and_copyable_int) mi)
|
movable_and_copyable_int &operator= (BOOST_COPY_ASSIGN_REF(movable_and_copyable_int) mi)
|
||||||
{ this->m_int = mi.m_int; return *this; }
|
{ this->m_int = mi.m_int; return *this; }
|
||||||
|
|
||||||
@@ -130,23 +138,23 @@ class movable_and_copyable_int
|
|||||||
movable_and_copyable_int & operator= (int i)
|
movable_and_copyable_int & operator= (int i)
|
||||||
{ this->m_int = i; return *this; }
|
{ this->m_int = i; return *this; }
|
||||||
|
|
||||||
bool operator ==(const movable_and_copyable_int &mi) const
|
friend bool operator ==(const movable_and_copyable_int &l, const movable_and_copyable_int &r)
|
||||||
{ return this->m_int == mi.m_int; }
|
{ return l.m_int == r.m_int; }
|
||||||
|
|
||||||
bool operator !=(const movable_and_copyable_int &mi) const
|
friend bool operator !=(const movable_and_copyable_int &l, const movable_and_copyable_int &r)
|
||||||
{ return this->m_int != mi.m_int; }
|
{ return l.m_int != r.m_int; }
|
||||||
|
|
||||||
bool operator <(const movable_and_copyable_int &mi) const
|
friend bool operator <(const movable_and_copyable_int &l, const movable_and_copyable_int &r)
|
||||||
{ return this->m_int < mi.m_int; }
|
{ return l.m_int < r.m_int; }
|
||||||
|
|
||||||
bool operator <=(const movable_and_copyable_int &mi) const
|
friend bool operator <=(const movable_and_copyable_int &l, const movable_and_copyable_int &r)
|
||||||
{ return this->m_int <= mi.m_int; }
|
{ return l.m_int <= r.m_int; }
|
||||||
|
|
||||||
bool operator >=(const movable_and_copyable_int &mi) const
|
friend bool operator >=(const movable_and_copyable_int &l, const movable_and_copyable_int &r)
|
||||||
{ return this->m_int >= mi.m_int; }
|
{ return l.m_int >= r.m_int; }
|
||||||
|
|
||||||
bool operator >(const movable_and_copyable_int &mi) const
|
friend bool operator >(const movable_and_copyable_int &l, const movable_and_copyable_int &r)
|
||||||
{ return this->m_int > mi.m_int; }
|
{ return l.m_int > r.m_int; }
|
||||||
|
|
||||||
int get_int() const
|
int get_int() const
|
||||||
{ return m_int; }
|
{ return m_int; }
|
||||||
@@ -161,6 +169,9 @@ class movable_and_copyable_int
|
|||||||
int m_int;
|
int m_int;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline movable_and_copyable_int produce_movable_and_copyable_int()
|
||||||
|
{ return movable_and_copyable_int(); }
|
||||||
|
|
||||||
template<class E, class T>
|
template<class E, class T>
|
||||||
std::basic_ostream<E, T> & operator<<
|
std::basic_ostream<E, T> & operator<<
|
||||||
(std::basic_ostream<E, T> & os, movable_and_copyable_int const & p)
|
(std::basic_ostream<E, T> & os, movable_and_copyable_int const & p)
|
||||||
@@ -194,23 +205,29 @@ class copyable_int
|
|||||||
copyable_int & operator= (int i)
|
copyable_int & operator= (int i)
|
||||||
{ this->m_int = i; return *this; }
|
{ this->m_int = i; return *this; }
|
||||||
|
|
||||||
bool operator ==(const copyable_int &mi) const
|
copyable_int & operator= (const copyable_int &ci)
|
||||||
{ return this->m_int == mi.m_int; }
|
{ this->m_int = ci.m_int; return *this; }
|
||||||
|
|
||||||
bool operator !=(const copyable_int &mi) const
|
~copyable_int()
|
||||||
{ return this->m_int != mi.m_int; }
|
{ this->m_int = 0; }
|
||||||
|
|
||||||
bool operator <(const copyable_int &mi) const
|
friend bool operator ==(const copyable_int &l, const copyable_int &r)
|
||||||
{ return this->m_int < mi.m_int; }
|
{ return l.m_int == r.m_int; }
|
||||||
|
|
||||||
bool operator <=(const copyable_int &mi) const
|
friend bool operator !=(const copyable_int &l, const copyable_int &r)
|
||||||
{ return this->m_int <= mi.m_int; }
|
{ return l.m_int != r.m_int; }
|
||||||
|
|
||||||
bool operator >=(const copyable_int &mi) const
|
friend bool operator <(const copyable_int &l, const copyable_int &r)
|
||||||
{ return this->m_int >= mi.m_int; }
|
{ return l.m_int < r.m_int; }
|
||||||
|
|
||||||
bool operator >(const copyable_int &mi) const
|
friend bool operator <=(const copyable_int &l, const copyable_int &r)
|
||||||
{ return this->m_int > mi.m_int; }
|
{ return l.m_int <= r.m_int; }
|
||||||
|
|
||||||
|
friend bool operator >=(const copyable_int &l, const copyable_int &r)
|
||||||
|
{ return l.m_int >= r.m_int; }
|
||||||
|
|
||||||
|
friend bool operator >(const copyable_int &l, const copyable_int &r)
|
||||||
|
{ return l.m_int > r.m_int; }
|
||||||
|
|
||||||
int get_int() const
|
int get_int() const
|
||||||
{ return m_int; }
|
{ return m_int; }
|
||||||
@@ -225,6 +242,9 @@ class copyable_int
|
|||||||
int m_int;
|
int m_int;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline copyable_int produce_copyable_int()
|
||||||
|
{ return copyable_int(); }
|
||||||
|
|
||||||
template<class E, class T>
|
template<class E, class T>
|
||||||
std::basic_ostream<E, T> & operator<<
|
std::basic_ostream<E, T> & operator<<
|
||||||
(std::basic_ostream<E, T> & os, copyable_int const & p)
|
(std::basic_ostream<E, T> & os, copyable_int const & p)
|
||||||
@@ -254,6 +274,9 @@ class non_copymovable_int
|
|||||||
: m_int(a)
|
: m_int(a)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
~non_copymovable_int()
|
||||||
|
{ m_int = 0; }
|
||||||
|
|
||||||
bool operator ==(const non_copymovable_int &mi) const
|
bool operator ==(const non_copymovable_int &mi) const
|
||||||
{ return this->m_int == mi.m_int; }
|
{ return this->m_int == mi.m_int; }
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@
|
|||||||
#include <boost/container/static_vector.hpp>
|
#include <boost/container/static_vector.hpp>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include "movable.hpp"
|
#include "movable_int.hpp"
|
||||||
|
|
||||||
using namespace boost::container;
|
using namespace boost::container;
|
||||||
|
|
||||||
|
@@ -216,7 +216,12 @@ int vector_test()
|
|||||||
stdvector->push_back(int(1));
|
stdvector->push_back(int(1));
|
||||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
|
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
|
||||||
}
|
}
|
||||||
{ //push_back with enough capacity
|
|
||||||
|
{ //test back()
|
||||||
|
const IntType test_this(1);
|
||||||
|
if(test_this != boostvector->back()) return 1;
|
||||||
|
}
|
||||||
|
{ //pop_back with enough capacity
|
||||||
boostvector->pop_back();
|
boostvector->pop_back();
|
||||||
boostvector->pop_back();
|
boostvector->pop_back();
|
||||||
stdvector->pop_back();
|
stdvector->pop_back();
|
||||||
|
Reference in New Issue
Block a user