Merge pull request #1 from boostorg/develop

pull from upstream
This commit is contained in:
Tobias Loew
2019-09-12 11:47:32 +02:00
committed by GitHub
30 changed files with 976 additions and 65 deletions

View File

@@ -1332,6 +1332,8 @@ use [*Boost.Container]? There are several reasons for that:
* [@https://github.com/boostorg/container/issues/116 GitHub #116: ['"MSVC + boost 1.70 compilation error when windows.h is already included (detail/thread_mutex.hpp)"]].
* [@https://github.com/boostorg/container/issues/117 GitHub #117: ['"flat_map/map::insert_or_assign with hint has wrong return types"]].
* [@https://github.com/boostorg/container/issues/118 GitHub #118: ['"Non-unique inplace_set_difference used in in flat_tree_merge_unique and iterator invalidation in insert_unique"]].
* [@https://github.com/boostorg/container/issues/122 GitHub #122: ['"Fix has_trivial_destructor_after_move"]].
* [@https://github.com/boostorg/container/issues/123 GitHub #123: ['"With heterogeneous lookup, `equal_range` can result in a range with length greater than 1"]].
* [classref boost::container::deque deque] can now have options, using [classref boost::container::deque_options deque_options].
The block size/bytes can be be specified.

View File

@@ -0,0 +1,47 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
//[doc_custom_small_vector
#include <boost/container/small_vector.hpp>
#include <boost/static_assert.hpp>
//Make sure assertions are active
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <cassert>
int main ()
{
using namespace boost::container;
//This option specifies the desired alignment for the internal value_type
typedef small_vector_options< inplace_alignment<16u> >::type alignment_16_option_t;
//Check 16 byte alignment option
small_vector<int, 10, void, alignment_16_option_t > sv;
assert(((std::size_t)sv.data() % 16u) == 0);
//This option specifies that a vector will increase its capacity 50%
//each time the previous capacity was exhausted.
typedef small_vector_options< growth_factor<growth_factor_50> >::type growth_50_option_t;
//Fill the vector until full capacity is reached
small_vector<int, 10, void, growth_50_option_t > growth_50_vector(10, 0);
const std::size_t old_cap = growth_50_vector.capacity();
growth_50_vector.resize(old_cap);
//Now insert an additional item and check the new buffer is 50% bigger
growth_50_vector.push_back(1);
assert(growth_50_vector.capacity() == old_cap*3/2);
return 0;
}
//]

View File

@@ -0,0 +1,39 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
//[doc_custom_static_vector
#include <boost/container/static_vector.hpp>
#include <boost/static_assert.hpp>
//Make sure assertions are active
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <cassert>
int main ()
{
using namespace boost::container;
//This option specifies the desired alignment for value_type
typedef static_vector_options< inplace_alignment<16u> >::type alignment_16_option_t;
//Check 16 byte alignment option
static_vector<int, 10, alignment_16_option_t > sv;
assert(((std::size_t)sv.data() % 16u) == 0);
//This static_vector won't throw on overflow, for maximum performance
typedef static_vector_options< throw_on_overflow<false> >::type no_throw_options_t;
//Create static_vector with no throw on overflow
static_vector<int, 10, no_throw_options_t > sv2;
return 0;
}
//]

View File

@@ -2295,8 +2295,9 @@ namespace boost {
template <class T, class Allocator, class Options>
struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator, Options> >
{
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
typedef typename boost::container::deque<T, Allocator, Options>::allocator_type allocator_type;
typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value;
};

View File

@@ -1605,7 +1605,7 @@ class flat_tree
const Compare &key_cmp = this->m_data.get_comp();
KeyOfValue key_extract;
RanIt lb(this->priv_lower_bound(first, last, k)), ub(lb);
if(lb != last && static_cast<difference_type>(!key_cmp(k, key_extract(*lb)))){
if(lb != last && !key_cmp(k, key_extract(*lb))){
++ub;
}
return std::pair<RanIt, RanIt>(lb, ub);
@@ -1622,11 +1622,11 @@ template <class T, class KeyOfValue,
class Compare, class AllocatorOrContainer>
struct has_trivial_destructor_after_move<boost::container::dtl::flat_tree<T, KeyOfValue, Compare, AllocatorOrContainer> >
{
typedef typename boost::container::dtl::select_container_type<T, AllocatorOrContainer>::type container_type;
typedef typename container_type::allocator_type allocator_t;
typedef typename ::boost::container::allocator_traits<allocator_t>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<allocator_t>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value;
typedef boost::container::dtl::flat_tree<T, KeyOfValue, Compare, AllocatorOrContainer> flat_tree;
typedef typename flat_tree::container_type container_type;
typedef typename flat_tree::key_compare key_compare;
static const bool value = ::boost::has_trivial_destructor_after_move<container_type>::value &&
::boost::has_trivial_destructor_after_move<key_compare>::value;
};
} //namespace boost {

View File

@@ -1516,8 +1516,9 @@ struct has_trivial_destructor_after_move
<T, KeyOfValue, Compare, Allocator, Options>
>
{
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
typedef typename ::boost::container::dtl::tree<T, KeyOfValue, Compare, Allocator, Options>::allocator_type allocator_type;
typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
};

View File

@@ -1353,7 +1353,9 @@ class flat_map
//! <b>Complexity</b>: log(size())+count(k)
template<class K>
BOOST_CONTAINER_FORCEINLINE size_type count(const K& x) const
{ return static_cast<size_type>(m_flat_tree.find(x) != m_flat_tree.end()); }
//Don't use find() != end optimization here as transparent comparators with key K might
//return a different range than key_type (which can only return a single element range)
{ return m_flat_tree.count(x); }
//! <b>Returns</b>: Returns true if there is an element with key
//! equivalent to key in the container, otherwise false.
@@ -1465,7 +1467,9 @@ class flat_map
//! <b>Complexity</b>: Logarithmic.
template<class K>
BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const K& x)
{ return dtl::force_copy<std::pair<iterator,iterator> >(m_flat_tree.lower_bound_range(x)); }
//Don't use lower_bound_range optimization here as transparent comparators with key K might
//return a different range than key_type (which can only return a single element range)
{ return dtl::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Requires</b>: This overload is available only if
//! key_compare::is_transparent exists.
@@ -1475,7 +1479,9 @@ class flat_map
//! <b>Complexity</b>: Logarithmic.
template<class K>
BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const K& x) const
{ return dtl::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.lower_bound_range(x)); }
//Don't use lower_bound_range optimization here as transparent comparators with key K might
//return a different range than key_type (which can only return a single element range)
{ return dtl::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Extracts the internal sequence container.
//!
@@ -1651,10 +1657,10 @@ flat_map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, A
template <class Key, class T, class Compare, class AllocatorOrContainer>
struct has_trivial_destructor_after_move<boost::container::flat_map<Key, T, Compare, AllocatorOrContainer> >
{
typedef typename ::boost::container::allocator_traits<AllocatorOrContainer>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<AllocatorOrContainer>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
typedef ::boost::container::dtl::pair<Key, T> value_t;
typedef typename ::boost::container::dtl::container_or_allocator_rebind<AllocatorOrContainer, value_t>::type alloc_or_cont_t;
typedef ::boost::container::dtl::flat_tree<value_t,::boost::container::dtl::select1st<Key>, Compare, alloc_or_cont_t> tree;
static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value;
};
namespace container {
@@ -2961,10 +2967,10 @@ namespace boost {
template <class Key, class T, class Compare, class AllocatorOrContainer>
struct has_trivial_destructor_after_move< boost::container::flat_multimap<Key, T, Compare, AllocatorOrContainer> >
{
typedef typename ::boost::container::allocator_traits<AllocatorOrContainer>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<AllocatorOrContainer>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
typedef ::boost::container::dtl::pair<Key, T> value_t;
typedef typename ::boost::container::dtl::container_or_allocator_rebind<AllocatorOrContainer, value_t>::type alloc_or_cont_t;
typedef ::boost::container::dtl::flat_tree<value_t,::boost::container::dtl::select1st<Key>, Compare, alloc_or_cont_t> tree;
static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value;
};
} //namespace boost {

View File

@@ -925,7 +925,9 @@ class flat_set
//! <b>Complexity</b>: log(size())+count(k)
template<typename K>
BOOST_CONTAINER_FORCEINLINE size_type count(const K& x) const
{ return static_cast<size_type>(this->tree_t::find(x) != this->tree_t::cend()); }
//Don't use find() != end optimization here as transparent comparators with key K might
//return a different range than key_type (which can only return a single element range)
{ return this->tree_t::count(x); }
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1031,7 +1033,9 @@ class flat_set
//! <b>Complexity</b>: Logarithmic
template<typename K>
std::pair<iterator,iterator> equal_range(const K& x)
{ return this->tree_t::lower_bound_range(x); }
//Don't use lower_bound_range optimization here as transparent comparators with key K might
//return a different range than key_type (which can only return a single element range)
{ return this->tree_t::equal_range(x); }
//! <b>Requires</b>: This overload is available only if
//! key_compare::is_transparent exists.
@@ -1041,7 +1045,9 @@ class flat_set
//! <b>Complexity</b>: Logarithmic
template<typename K>
std::pair<const_iterator,const_iterator> equal_range(const K& x) const
{ return this->tree_t::lower_bound_range(x); }
//Don't use lower_bound_range optimization here as transparent comparators with key K might
//return a different range than key_type (which can only return a single element range)
{ return this->tree_t::equal_range(x); }
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1192,10 +1198,8 @@ flat_set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, A
template <class Key, class Compare, class AllocatorOrContainer>
struct has_trivial_destructor_after_move<boost::container::flat_set<Key, Compare, AllocatorOrContainer> >
{
typedef typename ::boost::container::allocator_traits<AllocatorOrContainer>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<AllocatorOrContainer>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
typedef ::boost::container::dtl::flat_tree<Key, ::boost::container::dtl::identity<Key>, Compare, AllocatorOrContainer> tree;
static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value;
};
namespace container {
@@ -1926,10 +1930,8 @@ flat_multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, All
template <class Key, class Compare, class AllocatorOrContainer>
struct has_trivial_destructor_after_move<boost::container::flat_multiset<Key, Compare, AllocatorOrContainer> >
{
typedef typename ::boost::container::allocator_traits<AllocatorOrContainer>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<AllocatorOrContainer>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
typedef ::boost::container::dtl::flat_tree<Key, ::boost::container::dtl::identity<Key>, Compare, AllocatorOrContainer> tree;
static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value;
};
namespace container {

View File

@@ -1522,8 +1522,9 @@ list(InputIterator, InputIterator, ValueAllocator const&) ->
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::list<T, Allocator> >
{
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
typedef typename boost::container::list<T, Allocator>::allocator_type allocator_type;
typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value;
};

View File

@@ -1366,13 +1366,11 @@ map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Alloca
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class Key, class T, class Compare, class Allocator>
struct has_trivial_destructor_after_move<boost::container::map<Key, T, Compare, Allocator> >
template <class Key, class T, class Compare, class Allocator, class Options>
struct has_trivial_destructor_after_move<boost::container::map<Key, T, Compare, Allocator, Options> >
{
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
typedef ::boost::container::dtl::tree<std::pair<const Key, T>, int, Compare, Allocator, Options> tree;
static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value;
};
namespace container {
@@ -2292,13 +2290,11 @@ multimap(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocato
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class Key, class T, class Compare, class Allocator>
struct has_trivial_destructor_after_move<boost::container::multimap<Key, T, Compare, Allocator> >
template <class Key, class T, class Compare, class Allocator, class Options>
struct has_trivial_destructor_after_move<boost::container::multimap<Key, T, Compare, Allocator, Options> >
{
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
typedef ::boost::container::dtl::tree<std::pair<const Key, T>, int, Compare, Allocator, Options> tree;
static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value;
};
namespace container {

View File

@@ -1024,13 +1024,11 @@ set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Alloca
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class Key, class Compare, class Options, class Allocator>
template <class Key, class Compare, class Allocator, class Options>
struct has_trivial_destructor_after_move<boost::container::set<Key, Compare, Allocator, Options> >
{
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
typedef ::boost::container::dtl::tree<Key, void, Compare, Allocator, Options> tree;
static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value;
};
namespace container {
@@ -1693,10 +1691,8 @@ multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocato
template <class Key, class Compare, class Allocator, class Options>
struct has_trivial_destructor_after_move<boost::container::multiset<Key, Compare, Allocator, Options> >
{
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
typedef ::boost::container::dtl::tree<Key, void, Compare, Allocator, Options> tree;
static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value;
};
namespace container {

View File

@@ -1696,8 +1696,9 @@ namespace boost {
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::slist<T, Allocator> >
{
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
typedef typename boost::container::slist<T, Allocator>::allocator_type allocator_type;
typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value;
};

View File

@@ -2183,8 +2183,9 @@ stable_vector(InputIterator, InputIterator, Allocator const&) ->
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::stable_vector<T, Allocator> >
{
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
typedef typename boost::container::stable_vector<T, Allocator>::allocator_type allocator_type;
typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value;
};

View File

@@ -3490,9 +3490,9 @@ namespace boost {
template <class C, class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, Allocator> >
{
typedef typename ::boost::container::allocator_traits
<typename boost::container::basic_string<C, T, Allocator>::allocator_type>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
typedef typename boost::container::basic_string<C, T, Allocator>::allocator_type allocator_type;
typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value;
};

View File

@@ -3413,9 +3413,9 @@ namespace boost {
template <class T, class Allocator, class Options>
struct has_trivial_destructor_after_move<boost::container::vector<T, Allocator, Options> >
{
typedef typename ::boost::container::allocator_traits
<typename boost::container::real_allocator<T, Allocator>::type>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
typedef typename boost::container::vector<T, Allocator, Options>::allocator_type allocator_type;
typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value;
};

View File

@@ -412,6 +412,34 @@ int main ()
}
}
////////////////////////////////////
// has_trivial_destructor_after_move testing
////////////////////////////////////
// default allocator
{
typedef boost::container::deque<int> cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
return 1;
}
}
// std::allocator
{
typedef boost::container::deque<int, std::allocator<int> > cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
return 1;
}
}
return 0;
}

View File

@@ -8,6 +8,9 @@
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <vector>
#include <boost/container/flat_map.hpp>
#include <boost/container/allocator.hpp>
#include <boost/container/detail/container_or_allocator_rebind.hpp>
@@ -22,6 +25,7 @@
#include "../../intrusive/test/iterator_test.hpp"
#include <map>
#include <utility>
using namespace boost::container;
@@ -557,6 +561,42 @@ bool test_heterogeneous_lookups()
return true;
}
// An ordered sequence of std:pair is also ordered by std::pair::first.
struct with_lookup_by_first
{
typedef void is_transparent;
inline bool operator()(std::pair<int, int> a, std::pair<int, int> b) const
{
return a < b;
}
inline bool operator()(std::pair<int, int> a, int first) const
{
return a.first < first;
}
inline bool operator()(int first, std::pair<int, int> b) const
{
return first < b.first;
}
};
bool test_heterogeneous_lookup_by_partial_key()
{
typedef flat_map<std::pair<int, int>,int, with_lookup_by_first> map_t;
map_t map1;
map1[std::pair<int, int>(0, 1)] = 3;
map1[std::pair<int, int>(0, 2)] = 3;
std::pair<map_t::iterator, map_t::iterator> const first_0_range = map1.equal_range(0);
if(2 != (first_0_range.second - first_0_range.first))
return false;
if(2 != map1.count(0))
return false;
return true;
}
}}} //namespace boost::container::test
int main()
@@ -617,6 +657,9 @@ int main()
if (!test_heterogeneous_lookups())
return 1;
if (!test_heterogeneous_lookup_by_partial_key())
return 1;
////////////////////////////////////
// Testing allocator implementations
////////////////////////////////////
@@ -715,6 +758,80 @@ int main()
}
}
////////////////////////////////////
// has_trivial_destructor_after_move testing
////////////////////////////////////
{
typedef boost::container::dtl::pair<int, int> value_t;
typedef boost::container::dtl::select1st<int> key_of_value_t;
// flat_map, default
{
typedef boost::container::new_allocator<value_t> alloc_or_cont_t;
typedef boost::container::flat_map<int, int> cont;
typedef boost::container::dtl::flat_tree<value_t, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(flat_map, default) test failed" << std::endl;
return 1;
}
}
// flat_map, vector
{
typedef boost::container::vector<value_t> alloc_or_cont_t;
typedef boost::container::flat_map<int, int, std::less<int>, alloc_or_cont_t> cont;
typedef boost::container::dtl::flat_tree<value_t, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(flat_map, vector) test failed" << std::endl;
return 1;
}
}
// flat_map, std::vector
{
typedef std::vector<value_t> alloc_or_cont_t;
typedef boost::container::flat_map<int, int, std::less<int>, alloc_or_cont_t> cont;
typedef boost::container::dtl::flat_tree<value_t, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(flat_map, std::vector) test failed" << std::endl;
return 1;
}
}
// flat_multimap, default
{
typedef boost::container::new_allocator<value_t> alloc_or_cont_t;
typedef boost::container::flat_multimap<int, int> cont;
typedef boost::container::dtl::flat_tree<value_t, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(flat_multimap, default) test failed" << std::endl;
return 1;
}
}
// flat_multimap, vector
{
typedef boost::container::vector<value_t> alloc_or_cont_t;
typedef boost::container::flat_multimap<int, int, std::less<int>, alloc_or_cont_t> cont;
typedef boost::container::dtl::flat_tree<value_t, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(flat_multimap, vector) test failed" << std::endl;
return 1;
}
}
// flat_multimap, std::vector
{
typedef std::vector<value_t> alloc_or_cont_t;
typedef boost::container::flat_multimap<int, int, std::less<int>, alloc_or_cont_t> cont;
typedef boost::container::dtl::flat_tree<value_t, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(flat_multimap, std::vector) test failed" << std::endl;
return 1;
}
}
}
return 0;
}

View File

@@ -10,7 +10,10 @@
#include <boost/container/detail/config_begin.hpp>
#include <iostream>
#include <set>
#include <utility>
#include <vector>
#include <boost/container/flat_set.hpp>
#include <boost/container/detail/container_or_allocator_rebind.hpp>
@@ -574,6 +577,41 @@ bool test_heterogeneous_lookups()
return true;
}
// An ordered sequence of std:pair is also ordered by std::pair::first.
struct with_lookup_by_first
{
typedef void is_transparent;
inline bool operator()(std::pair<int, int> a, std::pair<int, int> b) const
{
return a < b;
}
inline bool operator()(std::pair<int, int> a, int first) const
{
return a.first < first;
}
inline bool operator()(int first, std::pair<int, int> b) const
{
return first < b.first;
}
};
bool test_heterogeneous_lookup_by_partial_key()
{
typedef flat_set<std::pair<int, int>, with_lookup_by_first> set_t;
set_t set1;
set1.insert(std::pair<int, int>(0, 1));
set1.insert(std::pair<int, int>(0, 2));
std::pair<set_t::iterator, set_t::iterator> const first_0_range = set1.equal_range(0);
if(2 != (first_0_range.second - first_0_range.first))
return false;
if(2 != set1.count(0))
return false;
return true;
}
}}}
template<class VoidAllocatorOrContainer>
@@ -715,6 +753,10 @@ int main()
return 1;
}
if(!test_heterogeneous_lookup_by_partial_key()){
return 1;
}
////////////////////////////////////
// Testing allocator implementations
////////////////////////////////////
@@ -813,6 +855,77 @@ int main()
}
}
////////////////////////////////////
// has_trivial_destructor_after_move testing
////////////////////////////////////
{
typedef boost::container::dtl::identity<int> key_of_value_t;
// flat_set, default
{
typedef boost::container::flat_set<int> cont;
typedef boost::container::dtl::flat_tree<int, key_of_value_t, std::less<int>, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(flat_set, default) test failed" << std::endl;
return 1;
}
}
// flat_set, vector
{
typedef boost::container::vector<int> alloc_or_cont_t;
typedef boost::container::flat_set<int, std::less<int>, alloc_or_cont_t> cont;
typedef boost::container::dtl::flat_tree<int, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(flat_set, vector) test failed" << std::endl;
return 1;
}
}
// flat_set, std::vector
{
typedef std::vector<int> alloc_or_cont_t;
typedef boost::container::flat_set<int, std::less<int>, alloc_or_cont_t> cont;
typedef boost::container::dtl::flat_tree<int, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(flat_set, std::vector) test failed" << std::endl;
return 1;
}
}
// flat_multiset, default
{
typedef boost::container::flat_multiset<int> cont;
typedef boost::container::dtl::flat_tree<int, key_of_value_t, std::less<int>, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(flat_multiset, default) test failed" << std::endl;
return 1;
}
}
// flat_multiset, vector
{
typedef boost::container::vector<int> alloc_or_cont_t;
typedef boost::container::flat_multiset<int, std::less<int>, alloc_or_cont_t> cont;
typedef boost::container::dtl::flat_tree<int, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(flat_multiset, vector) test failed" << std::endl;
return 1;
}
}
// flat_multiset, std::vector
{
typedef std::vector<int> alloc_or_cont_t;
typedef boost::container::flat_multiset<int, std::less<int>, alloc_or_cont_t> cont;
typedef boost::container::dtl::flat_tree<int, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(flat_multiset, std::vector) test failed" << std::endl;
return 1;
}
}
}
return 0;
}

View File

@@ -12,6 +12,8 @@
#include <boost/container/stable_vector.hpp>
#include <boost/container/static_vector.hpp>
#include <iostream>
#include "movable_int.hpp"
#include "dummy_test_allocator.hpp"
@@ -120,5 +122,35 @@ template class flat_tree
int main ()
{
////////////////////////////////////
// has_trivial_destructor_after_move testing
////////////////////////////////////
// default
{
typedef boost::container::dtl::flat_tree<int, boost::container::dtl::identity<int>,
std::less<int>, void> tree;
typedef tree::container_type container_type;
typedef tree::key_compare key_compare;
if (boost::has_trivial_destructor_after_move<tree>::value !=
boost::has_trivial_destructor_after_move<container_type>::value &&
boost::has_trivial_destructor_after_move<key_compare>::value) {
std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
return 1;
}
}
// std::allocator
{
typedef boost::container::dtl::flat_tree<int, boost::container::dtl::identity<int>,
std::less<int>, std::allocator<int> > tree;
typedef tree::container_type container_type;
typedef tree::key_compare key_compare;
if (boost::has_trivial_destructor_after_move<tree>::value !=
boost::has_trivial_destructor_after_move<container_type>::value &&
boost::has_trivial_destructor_after_move<key_compare>::value) {
std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
return 1;
}
}
return 0;
}

View File

@@ -252,6 +252,34 @@ int main ()
}
#endif
////////////////////////////////////
// has_trivial_destructor_after_move testing
////////////////////////////////////
// default allocator
{
typedef boost::container::list<int> cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
return 1;
}
}
// std::allocator
{
typedef boost::container::list<int, std::allocator<int> > cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
return 1;
}
}
return 0;
}

View File

@@ -633,6 +633,60 @@ int main ()
BOOST_STATIC_ASSERT(sizeof(rbmmap_size_optimized_yes) < sizeof(rbmap_size_optimized_no));
BOOST_STATIC_ASSERT(sizeof(avlmap_size_optimized_yes) < sizeof(avlmmap_size_optimized_no));
////////////////////////////////////
// has_trivial_destructor_after_move testing
////////////////////////////////////
{
typedef std::pair<const int, int> value_type;
//
// map
//
// default allocator
{
typedef boost::container::map<int, int> cont;
typedef boost::container::dtl::tree<value_type, int, std::less<int>, void, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(map, default allocator) test failed" << std::endl;
return 1;
}
}
// std::allocator
{
typedef boost::container::map<int, int, std::less<int>, std::allocator<value_type> > cont;
typedef boost::container::dtl::tree<value_type, int, std::less<int>, std::allocator<value_type>, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(map, std::allocator) test failed" << std::endl;
return 1;
}
}
//
// multimap
//
// default allocator
{
// default allocator
typedef boost::container::multimap<int, int> cont;
typedef boost::container::dtl::tree<value_type, int, std::less<int>, void, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(multimap, default allocator) test failed" << std::endl;
return 1;
}
}
// std::allocator
{
typedef boost::container::multimap<int, int, std::less<int>, std::allocator<value_type> > cont;
typedef boost::container::dtl::tree<value_type, int, std::less<int>, std::allocator<value_type>, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(multimap, std::allocator) test failed" << std::endl;
return 1;
}
}
}
return 0;
}

View File

@@ -605,6 +605,50 @@ int main ()
if(!node_type_test())
return 1;
////////////////////////////////////
// has_trivial_destructor_after_move testing
////////////////////////////////////
// set, default allocator
{
typedef boost::container::set<int> cont;
typedef boost::container::dtl::tree<int, void, std::less<int>, void, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(set, default allocator) test failed" << std::endl;
return 1;
}
}
// set, std::allocator
{
typedef boost::container::set<int, std::less<int>, std::allocator<int> > cont;
typedef boost::container::dtl::tree<int, void, std::less<int>, std::allocator<int>, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(set, std::allocator) test failed" << std::endl;
return 1;
}
}
// multiset, default allocator
{
typedef boost::container::multiset<int> cont;
typedef boost::container::dtl::tree<int, void, std::less<int>, void, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(multiset, default allocator) test failed" << std::endl;
return 1;
}
}
// multiset, std::allocator
{
typedef boost::container::multiset<int, std::less<int>, std::allocator<int> > cont;
typedef boost::container::dtl::tree<int, void, std::less<int>, std::allocator<int>, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(multiset, std::allocator) test failed" << std::endl;
return 1;
}
}
return 0;
}

View File

@@ -255,6 +255,34 @@ int main ()
}
#endif
////////////////////////////////////
// has_trivial_destructor_after_move testing
////////////////////////////////////
// default allocator
{
typedef boost::container::slist<int> cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
return 1;
}
}
// std::allocator
{
typedef boost::container::slist<int, std::allocator<int> > cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
return 1;
}
}
return 0;
}

View File

@@ -0,0 +1,110 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/small_vector.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/assert.hpp>
using namespace boost::container;
const std::size_t Capacity = 10u;
void test_alignment()
{
{ //extended alignment
const std::size_t extended_alignment = sizeof(int)*4u;
BOOST_STATIC_ASSERT(extended_alignment > dtl::alignment_of<int>::value);
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = small_vector_options_t< inplace_alignment<extended_alignment> >;
#else
typedef small_vector_options
< inplace_alignment<extended_alignment> >::type options_t;
#endif
small_vector<int, Capacity, void, options_t> v;
v.resize(v.capacity());
BOOST_ASSERT((reinterpret_cast<std::size_t>(&v[0]) % extended_alignment) == 0);
}
{ //default alignment
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = small_vector_options_t< inplace_alignment<0> >;
#else
typedef small_vector_options< inplace_alignment<0> >::type options_t;
#endif
small_vector<int, Capacity, void, options_t> v;
v.resize(v.capacity());
BOOST_ASSERT((reinterpret_cast<std::size_t>(&v[0]) % dtl::alignment_of<int>::value) == 0);
}
}
void test_growth_factor_50()
{
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = small_vector_options_t< growth_factor<growth_factor_50> >;
#else
typedef small_vector_options
< growth_factor<growth_factor_50> >::type options_t;
#endif
small_vector<int, Capacity, new_allocator<int>, options_t> v;
v.resize(5);
v.resize(v.capacity());
std::size_t old_capacity = v.capacity();
v.push_back(0);
std::size_t new_capacity = v.capacity();
BOOST_TEST(new_capacity == old_capacity + old_capacity/2);
}
void test_growth_factor_60()
{
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = small_vector_options_t< growth_factor<growth_factor_60> >;
#else
typedef small_vector_options
< growth_factor<growth_factor_60> >::type options_t;
#endif
small_vector<int, Capacity, new_allocator<int>, options_t> v;
v.resize(5);
v.resize(v.capacity());
std::size_t old_capacity = v.capacity();
v.push_back(0);
std::size_t new_capacity = v.capacity();
BOOST_TEST(new_capacity == old_capacity + 3*old_capacity/5);
}
void test_growth_factor_100()
{
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = small_vector_options_t< growth_factor<growth_factor_100> >;
#else
typedef small_vector_options
< growth_factor<growth_factor_100> >::type options_t;
#endif
small_vector<int, Capacity, new_allocator<int>, options_t> v;
v.resize(5);
v.resize(v.capacity());
std::size_t old_capacity = v.capacity();
v.push_back(0);
std::size_t new_capacity = v.capacity();
BOOST_TEST(new_capacity == 2*old_capacity);
}
int main()
{
test_alignment();
test_growth_factor_50();
test_growth_factor_60();
test_growth_factor_100();
return ::boost::report_errors();
}

View File

@@ -212,5 +212,25 @@ int main()
}
}
////////////////////////////////////
// has_trivial_destructor_after_move testing
////////////////////////////////////
// default allocator
{
typedef boost::container::small_vector<int, 0> cont;
if (boost::has_trivial_destructor_after_move<cont>::value) {
std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
return 1;
}
}
// std::allocator
{
typedef boost::container::small_vector<int, 0, std::allocator<int> > cont;
if (boost::has_trivial_destructor_after_move<cont>::value) {
std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
return 1;
}
}
return 0;
}

View File

@@ -193,6 +193,34 @@ int main()
}
#endif
////////////////////////////////////
// has_trivial_destructor_after_move testing
////////////////////////////////////
// default allocator
{
typedef boost::container::stable_vector<int> cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
return 1;
}
}
// std::allocator
{
typedef boost::container::stable_vector<int, std::allocator<int> > cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
return 1;
}
}
return 0;
}

View File

@@ -0,0 +1,124 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#define BOOST_ENABLE_ASSERT_HANDLER
#include <boost/container/static_vector.hpp>
#include <boost/core/lightweight_test.hpp>
#include <new> //for bad_alloc
#include <boost/assert.hpp>
using namespace boost::container;
//User-defined assertion to test throw_on_overflow
struct throw_on_overflow_off
{};
namespace boost {
void assertion_failed(char const *, char const *, char const *, long)
{
throw throw_on_overflow_off();
}
void assertion_failed_msg(char const *, char const *, char const *, char const *, long )
{
throw throw_on_overflow_off();
}
}
void test_alignment()
{
const std::size_t Capacity = 10u;
{ //extended alignment
const std::size_t extended_alignment = sizeof(int)*4u;
BOOST_STATIC_ASSERT(extended_alignment > dtl::alignment_of<int>::value);
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = static_vector_options_t< inplace_alignment<extended_alignment> >;
#else
typedef static_vector_options
< inplace_alignment<extended_alignment> >::type options_t;
#endif
static_vector<int, Capacity, options_t> v;
v.resize(v.capacity());
BOOST_ASSERT((reinterpret_cast<std::size_t>(&v[0]) % extended_alignment) == 0);
}
{ //default alignment
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = static_vector_options_t< inplace_alignment<0> >;
#else
typedef static_vector_options< inplace_alignment<0> >::type options_t;
#endif
static_vector<int, Capacity, options_t> v;
v.resize(v.capacity());
BOOST_ASSERT((reinterpret_cast<std::size_t>(&v[0]) % dtl::alignment_of<int>::value) == 0);
}
}
void test_throw_on_overflow()
{
#if !defined(BOOST_NO_EXCEPTIONS)
const std::size_t Capacity = 10u;
{ //throw_on_overflow == true, expect bad_alloc
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = static_vector_options_t< throw_on_overflow<true> >;
#else
typedef static_vector_options
< throw_on_overflow<true> >::type options_t;
#endif
static_vector<int, Capacity, options_t> v;
v.resize(Capacity);
bool expected_type_thrown = false;
try{
v.push_back(0);
}
catch(std::bad_alloc&)
{
expected_type_thrown = true;
}
catch(...)
{}
BOOST_TEST(expected_type_thrown == true);
BOOST_TEST(v.capacity() == Capacity);
}
{ //throw_on_overflow == false, test it through BOOST_ASSERT
//even in release mode (BOOST_ENABLE_ASSERT_HANDLER), and throwing
//a special type in that assertion.
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = static_vector_options_t< throw_on_overflow<false> >;
#else
typedef static_vector_options< throw_on_overflow<false> >::type options_t;
#endif
static_vector<int, Capacity, options_t> v;
v.resize(Capacity);
bool expected_type_thrown = false;
try{
v.push_back(0);
}
catch(throw_on_overflow_off)
{
expected_type_thrown = true;
}
catch(...)
{}
BOOST_TEST(expected_type_thrown == true);
BOOST_TEST(v.capacity() == Capacity);
}
#endif
}
int main()
{
test_alignment();
test_throw_on_overflow();
return ::boost::report_errors();
}

View File

@@ -562,6 +562,34 @@ int main()
return 1;
}
////////////////////////////////////
// has_trivial_destructor_after_move testing
////////////////////////////////////
// default allocator
{
typedef boost::container::basic_string<char> cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
return 1;
}
}
// std::allocator
{
typedef boost::container::basic_string<char, std::char_traits<char>, std::allocator<char> > cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
return 1;
}
}
return boost::report_errors();
}

View File

@@ -9,6 +9,10 @@
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/tree.hpp>
#include <boost/container/adaptive_pool.hpp>
#include <boost/container/new_allocator.hpp>
#include <boost/move/traits.hpp>
#include <iostream>
#include "movable_int.hpp"
#include "dummy_test_allocator.hpp"
@@ -79,5 +83,37 @@ template class tree
int main ()
{
////////////////////////////////////
// has_trivial_destructor_after_move testing
////////////////////////////////////
// default
{
typedef boost::container::dtl::tree<int, void, std::less<int>, void, void> tree;
typedef tree::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
typedef tree::key_compare key_compare;
if (boost::has_trivial_destructor_after_move<tree>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value &&
boost::has_trivial_destructor_after_move<key_compare>::value) {
std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
return 1;
}
}
// std::allocator
{
typedef boost::container::dtl::tree<int, void, std::less<int>, std::allocator<int>, void> tree;
typedef tree::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
typedef tree::key_compare key_compare;
if (boost::has_trivial_destructor_after_move<tree>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value &&
boost::has_trivial_destructor_after_move<key_compare>::value) {
std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
return 1;
}
}
return 0;
}

View File

@@ -332,5 +332,33 @@ int main()
return 1;
}
////////////////////////////////////
// has_trivial_destructor_after_move testing
////////////////////////////////////
// default allocator
{
typedef boost::container::vector<int> cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
return 1;
}
}
// std::allocator
{
typedef boost::container::vector<int, std::allocator<int> > cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
return 1;
}
}
return 0;
}