From f25c767a2bc47eb4c8168ab4d3076fe4708b631f Mon Sep 17 00:00:00 2001 From: Mitsuru Kariya Date: Tue, 28 May 2019 19:26:19 +0900 Subject: [PATCH 1/3] Fix has_trivial_destructor_after_move Most template type parameters 'Allocator' were modified their default type to void since 1.70.0. These modifications cause has_trivial_destructor_after_move to compile error or yield wrong result. So, fix them by changing specializations of has_trivial_destructor_after_move. --- include/boost/container/deque.hpp | 5 +- include/boost/container/detail/flat_tree.hpp | 10 +-- include/boost/container/detail/tree.hpp | 5 +- include/boost/container/flat_map.hpp | 16 ++-- include/boost/container/flat_set.hpp | 12 +-- include/boost/container/list.hpp | 5 +- include/boost/container/map.hpp | 20 ++--- include/boost/container/set.hpp | 14 ++-- include/boost/container/slist.hpp | 5 +- include/boost/container/stable_vector.hpp | 5 +- include/boost/container/string.hpp | 6 +- include/boost/container/vector.hpp | 6 +- test/deque_test.cpp | 28 +++++++ test/flat_map_test.cpp | 77 ++++++++++++++++++++ test/flat_set_test.cpp | 73 +++++++++++++++++++ test/flat_tree_test.cpp | 32 ++++++++ test/list_test.cpp | 28 +++++++ test/map_test.cpp | 54 ++++++++++++++ test/set_test.cpp | 44 +++++++++++ test/slist_test.cpp | 28 +++++++ test/small_vector_test.cpp | 20 +++++ test/stable_vector_test.cpp | 28 +++++++ test/string_test.cpp | 28 +++++++ test/tree_test.cpp | 36 +++++++++ test/vector_test.cpp | 28 +++++++ 25 files changed, 555 insertions(+), 58 deletions(-) diff --git a/include/boost/container/deque.hpp b/include/boost/container/deque.hpp index be88845..ae91106 100644 --- a/include/boost/container/deque.hpp +++ b/include/boost/container/deque.hpp @@ -2295,8 +2295,9 @@ namespace boost { template struct has_trivial_destructor_after_move > { - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && + typedef typename boost::container::deque::allocator_type allocator_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && ::boost::has_trivial_destructor_after_move::value; }; diff --git a/include/boost/container/detail/flat_tree.hpp b/include/boost/container/detail/flat_tree.hpp index 4d86f9e..5d96a21 100644 --- a/include/boost/container/detail/flat_tree.hpp +++ b/include/boost/container/detail/flat_tree.hpp @@ -1622,11 +1622,11 @@ template struct has_trivial_destructor_after_move > { - typedef typename boost::container::dtl::select_container_type::type container_type; - typedef typename container_type::allocator_type allocator_t; - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value; + typedef boost::container::dtl::flat_tree 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::value && + ::boost::has_trivial_destructor_after_move::value; }; } //namespace boost { diff --git a/include/boost/container/detail/tree.hpp b/include/boost/container/detail/tree.hpp index 42e3564..23fbfde 100644 --- a/include/boost/container/detail/tree.hpp +++ b/include/boost/container/detail/tree.hpp @@ -1516,8 +1516,9 @@ struct has_trivial_destructor_after_move > { - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && + typedef typename ::boost::container::dtl::tree::allocator_type allocator_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && ::boost::has_trivial_destructor_after_move::value && ::boost::has_trivial_destructor_after_move::value; }; diff --git a/include/boost/container/flat_map.hpp b/include/boost/container/flat_map.hpp index 2b52e14..366f073 100644 --- a/include/boost/container/flat_map.hpp +++ b/include/boost/container/flat_map.hpp @@ -1651,10 +1651,10 @@ flat_map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, A template struct has_trivial_destructor_after_move > { - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value; + typedef ::boost::container::dtl::pair value_t; + typedef typename ::boost::container::dtl::container_or_allocator_rebind::type alloc_or_cont_t; + typedef ::boost::container::dtl::flat_tree, Compare, alloc_or_cont_t> tree; + static const bool value = ::boost::has_trivial_destructor_after_move::value; }; namespace container { @@ -2961,10 +2961,10 @@ namespace boost { template struct has_trivial_destructor_after_move< boost::container::flat_multimap > { - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value; + typedef ::boost::container::dtl::pair value_t; + typedef typename ::boost::container::dtl::container_or_allocator_rebind::type alloc_or_cont_t; + typedef ::boost::container::dtl::flat_tree, Compare, alloc_or_cont_t> tree; + static const bool value = ::boost::has_trivial_destructor_after_move::value; }; } //namespace boost { diff --git a/include/boost/container/flat_set.hpp b/include/boost/container/flat_set.hpp index 080beb5..5dae0f9 100644 --- a/include/boost/container/flat_set.hpp +++ b/include/boost/container/flat_set.hpp @@ -1192,10 +1192,8 @@ flat_set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, A template struct has_trivial_destructor_after_move > { - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value; + typedef ::boost::container::dtl::flat_tree, Compare, AllocatorOrContainer> tree; + static const bool value = ::boost::has_trivial_destructor_after_move::value; }; namespace container { @@ -1926,10 +1924,8 @@ flat_multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, All template struct has_trivial_destructor_after_move > { - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value; + typedef ::boost::container::dtl::flat_tree, Compare, AllocatorOrContainer> tree; + static const bool value = ::boost::has_trivial_destructor_after_move::value; }; namespace container { diff --git a/include/boost/container/list.hpp b/include/boost/container/list.hpp index a17a906..f9ff663 100644 --- a/include/boost/container/list.hpp +++ b/include/boost/container/list.hpp @@ -1522,8 +1522,9 @@ list(InputIterator, InputIterator, ValueAllocator const&) -> template struct has_trivial_destructor_after_move > { - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && + typedef typename boost::container::list::allocator_type allocator_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && ::boost::has_trivial_destructor_after_move::value; }; diff --git a/include/boost/container/map.hpp b/include/boost/container/map.hpp index d0c8fc9..447f4ad 100644 --- a/include/boost/container/map.hpp +++ b/include/boost/container/map.hpp @@ -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 -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value; + typedef ::boost::container::dtl::tree, int, Compare, Allocator, Options> tree; + static const bool value = ::boost::has_trivial_destructor_after_move::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 -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value; + typedef ::boost::container::dtl::tree, int, Compare, Allocator, Options> tree; + static const bool value = ::boost::has_trivial_destructor_after_move::value; }; namespace container { diff --git a/include/boost/container/set.hpp b/include/boost/container/set.hpp index 44bad8c..ca6334f 100644 --- a/include/boost/container/set.hpp +++ b/include/boost/container/set.hpp @@ -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 +template struct has_trivial_destructor_after_move > { - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value; + typedef ::boost::container::dtl::tree tree; + static const bool value = ::boost::has_trivial_destructor_after_move::value; }; namespace container { @@ -1693,10 +1691,8 @@ multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocato template struct has_trivial_destructor_after_move > { - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value; + typedef ::boost::container::dtl::tree tree; + static const bool value = ::boost::has_trivial_destructor_after_move::value; }; namespace container { diff --git a/include/boost/container/slist.hpp b/include/boost/container/slist.hpp index a9c29f8..d10cf57 100644 --- a/include/boost/container/slist.hpp +++ b/include/boost/container/slist.hpp @@ -1696,8 +1696,9 @@ namespace boost { template struct has_trivial_destructor_after_move > { - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && + typedef typename boost::container::slist::allocator_type allocator_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && ::boost::has_trivial_destructor_after_move::value; }; diff --git a/include/boost/container/stable_vector.hpp b/include/boost/container/stable_vector.hpp index 87525f9..7d0c9b3 100644 --- a/include/boost/container/stable_vector.hpp +++ b/include/boost/container/stable_vector.hpp @@ -2183,8 +2183,9 @@ stable_vector(InputIterator, InputIterator, Allocator const&) -> template struct has_trivial_destructor_after_move > { - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && + typedef typename boost::container::stable_vector::allocator_type allocator_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && ::boost::has_trivial_destructor_after_move::value; }; diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp index 0943637..46ca567 100644 --- a/include/boost/container/string.hpp +++ b/include/boost/container/string.hpp @@ -3490,9 +3490,9 @@ namespace boost { template struct has_trivial_destructor_after_move > { - typedef typename ::boost::container::allocator_traits - ::allocator_type>::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && + typedef typename boost::container::basic_string::allocator_type allocator_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && ::boost::has_trivial_destructor_after_move::value; }; diff --git a/include/boost/container/vector.hpp b/include/boost/container/vector.hpp index d7886d5..099a878 100644 --- a/include/boost/container/vector.hpp +++ b/include/boost/container/vector.hpp @@ -3413,9 +3413,9 @@ namespace boost { template struct has_trivial_destructor_after_move > { - typedef typename ::boost::container::allocator_traits - ::type>::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && + typedef typename boost::container::vector::allocator_type allocator_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && ::boost::has_trivial_destructor_after_move::value; }; diff --git a/test/deque_test.cpp b/test/deque_test.cpp index 01c47e0..22b87f4 100644 --- a/test/deque_test.cpp +++ b/test/deque_test.cpp @@ -412,6 +412,34 @@ int main () } } + //////////////////////////////////// + // has_trivial_destructor_after_move testing + //////////////////////////////////// + // default allocator + { + typedef boost::container::deque cont; + typedef cont::allocator_type allocator_type; + typedef boost::container::allocator_traits::pointer pointer; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl; + return 1; + } + } + // std::allocator + { + typedef boost::container::deque > cont; + typedef cont::allocator_type allocator_type; + typedef boost::container::allocator_traits::pointer pointer; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl; + return 1; + } + } + return 0; } diff --git a/test/flat_map_test.cpp b/test/flat_map_test.cpp index 9497ee2..9595775 100644 --- a/test/flat_map_test.cpp +++ b/test/flat_map_test.cpp @@ -8,6 +8,9 @@ // ////////////////////////////////////////////////////////////////////////////// #include + +#include + #include #include #include @@ -715,6 +718,80 @@ int main() } } + //////////////////////////////////// + // has_trivial_destructor_after_move testing + //////////////////////////////////// + { + typedef boost::container::dtl::pair value_t; + typedef boost::container::dtl::select1st key_of_value_t; + // flat_map, default + { + typedef boost::container::new_allocator alloc_or_cont_t; + typedef boost::container::flat_map cont; + typedef boost::container::dtl::flat_tree, alloc_or_cont_t> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(flat_map, default) test failed" << std::endl; + return 1; + } + } + // flat_map, vector + { + typedef boost::container::vector alloc_or_cont_t; + typedef boost::container::flat_map, alloc_or_cont_t> cont; + typedef boost::container::dtl::flat_tree, alloc_or_cont_t> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(flat_map, vector) test failed" << std::endl; + return 1; + } + } + // flat_map, std::vector + { + typedef std::vector alloc_or_cont_t; + typedef boost::container::flat_map, alloc_or_cont_t> cont; + typedef boost::container::dtl::flat_tree, alloc_or_cont_t> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::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 alloc_or_cont_t; + typedef boost::container::flat_multimap cont; + typedef boost::container::dtl::flat_tree, alloc_or_cont_t> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(flat_multimap, default) test failed" << std::endl; + return 1; + } + } + // flat_multimap, vector + { + typedef boost::container::vector alloc_or_cont_t; + typedef boost::container::flat_multimap, alloc_or_cont_t> cont; + typedef boost::container::dtl::flat_tree, alloc_or_cont_t> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(flat_multimap, vector) test failed" << std::endl; + return 1; + } + } + // flat_multimap, std::vector + { + typedef std::vector alloc_or_cont_t; + typedef boost::container::flat_multimap, alloc_or_cont_t> cont; + typedef boost::container::dtl::flat_tree, alloc_or_cont_t> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(flat_multimap, std::vector) test failed" << std::endl; + return 1; + } + } + } + return 0; } diff --git a/test/flat_set_test.cpp b/test/flat_set_test.cpp index 7e561f7..0ffb839 100644 --- a/test/flat_set_test.cpp +++ b/test/flat_set_test.cpp @@ -10,7 +10,9 @@ #include +#include #include +#include #include #include @@ -813,6 +815,77 @@ int main() } } + //////////////////////////////////// + // has_trivial_destructor_after_move testing + //////////////////////////////////// + { + typedef boost::container::dtl::identity key_of_value_t; + // flat_set, default + { + typedef boost::container::flat_set cont; + typedef boost::container::dtl::flat_tree, void> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(flat_set, default) test failed" << std::endl; + return 1; + } + } + // flat_set, vector + { + typedef boost::container::vector alloc_or_cont_t; + typedef boost::container::flat_set, alloc_or_cont_t> cont; + typedef boost::container::dtl::flat_tree, alloc_or_cont_t> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(flat_set, vector) test failed" << std::endl; + return 1; + } + } + // flat_set, std::vector + { + typedef std::vector alloc_or_cont_t; + typedef boost::container::flat_set, alloc_or_cont_t> cont; + typedef boost::container::dtl::flat_tree, alloc_or_cont_t> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::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 cont; + typedef boost::container::dtl::flat_tree, void> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(flat_multiset, default) test failed" << std::endl; + return 1; + } + } + // flat_multiset, vector + { + typedef boost::container::vector alloc_or_cont_t; + typedef boost::container::flat_multiset, alloc_or_cont_t> cont; + typedef boost::container::dtl::flat_tree, alloc_or_cont_t> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(flat_multiset, vector) test failed" << std::endl; + return 1; + } + } + // flat_multiset, std::vector + { + typedef std::vector alloc_or_cont_t; + typedef boost::container::flat_multiset, alloc_or_cont_t> cont; + typedef boost::container::dtl::flat_tree, alloc_or_cont_t> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(flat_multiset, std::vector) test failed" << std::endl; + return 1; + } + } + } + return 0; } diff --git a/test/flat_tree_test.cpp b/test/flat_tree_test.cpp index b70fb4a..e94c089 100644 --- a/test/flat_tree_test.cpp +++ b/test/flat_tree_test.cpp @@ -12,6 +12,8 @@ #include #include +#include + #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, + std::less, void> tree; + typedef tree::container_type container_type; + typedef tree::key_compare key_compare; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl; + return 1; + } + } + // std::allocator + { + typedef boost::container::dtl::flat_tree, + std::less, std::allocator > tree; + typedef tree::container_type container_type; + typedef tree::key_compare key_compare; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl; + return 1; + } + } + return 0; } diff --git a/test/list_test.cpp b/test/list_test.cpp index 5006a7d..c4f9f41 100644 --- a/test/list_test.cpp +++ b/test/list_test.cpp @@ -252,6 +252,34 @@ int main () } #endif + //////////////////////////////////// + // has_trivial_destructor_after_move testing + //////////////////////////////////// + // default allocator + { + typedef boost::container::list cont; + typedef cont::allocator_type allocator_type; + typedef boost::container::allocator_traits::pointer pointer; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl; + return 1; + } + } + // std::allocator + { + typedef boost::container::list > cont; + typedef cont::allocator_type allocator_type; + typedef boost::container::allocator_traits::pointer pointer; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl; + return 1; + } + } + return 0; } diff --git a/test/map_test.cpp b/test/map_test.cpp index b73f569..7448303 100644 --- a/test/map_test.cpp +++ b/test/map_test.cpp @@ -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 value_type; + // + // map + // + // default allocator + { + typedef boost::container::map cont; + typedef boost::container::dtl::tree, void, void> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(map, default allocator) test failed" << std::endl; + return 1; + } + } + // std::allocator + { + typedef boost::container::map, std::allocator > cont; + typedef boost::container::dtl::tree, std::allocator, void> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::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 cont; + typedef boost::container::dtl::tree, void, void> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(multimap, default allocator) test failed" << std::endl; + return 1; + } + } + // std::allocator + { + typedef boost::container::multimap, std::allocator > cont; + typedef boost::container::dtl::tree, std::allocator, void> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(multimap, std::allocator) test failed" << std::endl; + return 1; + } + } + } + return 0; } diff --git a/test/set_test.cpp b/test/set_test.cpp index 39ab1b7..a7d0b47 100644 --- a/test/set_test.cpp +++ b/test/set_test.cpp @@ -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 cont; + typedef boost::container::dtl::tree, void, void> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(set, default allocator) test failed" << std::endl; + return 1; + } + } + // set, std::allocator + { + typedef boost::container::set, std::allocator > cont; + typedef boost::container::dtl::tree, std::allocator, void> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(set, std::allocator) test failed" << std::endl; + return 1; + } + } + // multiset, default allocator + { + typedef boost::container::multiset cont; + typedef boost::container::dtl::tree, void, void> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(multiset, default allocator) test failed" << std::endl; + return 1; + } + } + // multiset, std::allocator + { + typedef boost::container::multiset, std::allocator > cont; + typedef boost::container::dtl::tree, std::allocator, void> tree; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(multiset, std::allocator) test failed" << std::endl; + return 1; + } + } + return 0; } diff --git a/test/slist_test.cpp b/test/slist_test.cpp index 4e09837..0894344 100644 --- a/test/slist_test.cpp +++ b/test/slist_test.cpp @@ -255,6 +255,34 @@ int main () } #endif + //////////////////////////////////// + // has_trivial_destructor_after_move testing + //////////////////////////////////// + // default allocator + { + typedef boost::container::slist cont; + typedef cont::allocator_type allocator_type; + typedef boost::container::allocator_traits::pointer pointer; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl; + return 1; + } + } + // std::allocator + { + typedef boost::container::slist > cont; + typedef cont::allocator_type allocator_type; + typedef boost::container::allocator_traits::pointer pointer; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl; + return 1; + } + } + return 0; } diff --git a/test/small_vector_test.cpp b/test/small_vector_test.cpp index e3b7600..315d64d 100644 --- a/test/small_vector_test.cpp +++ b/test/small_vector_test.cpp @@ -212,5 +212,25 @@ int main() } } + //////////////////////////////////// + // has_trivial_destructor_after_move testing + //////////////////////////////////// + // default allocator + { + typedef boost::container::small_vector cont; + if (boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl; + return 1; + } + } + // std::allocator + { + typedef boost::container::small_vector > cont; + if (boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl; + return 1; + } + } + return 0; } diff --git a/test/stable_vector_test.cpp b/test/stable_vector_test.cpp index fd76330..e0fb586 100644 --- a/test/stable_vector_test.cpp +++ b/test/stable_vector_test.cpp @@ -193,6 +193,34 @@ int main() } #endif + //////////////////////////////////// + // has_trivial_destructor_after_move testing + //////////////////////////////////// + // default allocator + { + typedef boost::container::stable_vector cont; + typedef cont::allocator_type allocator_type; + typedef boost::container::allocator_traits::pointer pointer; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl; + return 1; + } + } + // std::allocator + { + typedef boost::container::stable_vector > cont; + typedef cont::allocator_type allocator_type; + typedef boost::container::allocator_traits::pointer pointer; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl; + return 1; + } + } + return 0; } diff --git a/test/string_test.cpp b/test/string_test.cpp index 2dfb2a4..b2d17f6 100644 --- a/test/string_test.cpp +++ b/test/string_test.cpp @@ -562,6 +562,34 @@ int main() return 1; } + //////////////////////////////////// + // has_trivial_destructor_after_move testing + //////////////////////////////////// + // default allocator + { + typedef boost::container::basic_string cont; + typedef cont::allocator_type allocator_type; + typedef boost::container::allocator_traits::pointer pointer; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl; + return 1; + } + } + // std::allocator + { + typedef boost::container::basic_string, std::allocator > cont; + typedef cont::allocator_type allocator_type; + typedef boost::container::allocator_traits::pointer pointer; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl; + return 1; + } + } + return boost::report_errors(); } diff --git a/test/tree_test.cpp b/test/tree_test.cpp index c1a1c3d..e075596 100644 --- a/test/tree_test.cpp +++ b/test/tree_test.cpp @@ -9,6 +9,10 @@ ////////////////////////////////////////////////////////////////////////////// #include #include +#include +#include + +#include #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, void, void> tree; + typedef tree::allocator_type allocator_type; + typedef boost::container::allocator_traits::pointer pointer; + typedef tree::key_compare key_compare; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl; + return 1; + } + } + // std::allocator + { + typedef boost::container::dtl::tree, std::allocator, void> tree; + typedef tree::allocator_type allocator_type; + typedef boost::container::allocator_traits::pointer pointer; + typedef tree::key_compare key_compare; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl; + return 1; + } + } + return 0; } diff --git a/test/vector_test.cpp b/test/vector_test.cpp index 2420563..c9b82cc 100644 --- a/test/vector_test.cpp +++ b/test/vector_test.cpp @@ -332,5 +332,33 @@ int main() return 1; } + //////////////////////////////////// + // has_trivial_destructor_after_move testing + //////////////////////////////////// + // default allocator + { + typedef boost::container::vector cont; + typedef cont::allocator_type allocator_type; + typedef boost::container::allocator_traits::pointer pointer; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl; + return 1; + } + } + // std::allocator + { + typedef boost::container::vector > cont; + typedef cont::allocator_type allocator_type; + typedef boost::container::allocator_traits::pointer pointer; + if (boost::has_trivial_destructor_after_move::value != + boost::has_trivial_destructor_after_move::value && + boost::has_trivial_destructor_after_move::value) { + std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl; + return 1; + } + } + return 0; } From e866c15fae3fe51419f165ac6fa2ebe0cc814895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sat, 8 Jun 2019 12:48:03 +0200 Subject: [PATCH 2/3] Update changelog with #122 ("Fix has_trivial_destructor_after_move") --- doc/container.qbk | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/container.qbk b/doc/container.qbk index c9db3ae..a6e19a8 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -1332,6 +1332,7 @@ 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"]]. * [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. From 7b62f360b77cf7a95b52fb1cbea6c02a7f6df77f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sat, 8 Jun 2019 13:01:24 +0200 Subject: [PATCH 3/3] Add missing tests for small vector and static vector --- test/small_vector_options_test.cpp | 110 ++++++++++++++++++++++++ test/static_vector_options_test.cpp | 124 ++++++++++++++++++++++++++++ 2 files changed, 234 insertions(+) create mode 100644 test/small_vector_options_test.cpp create mode 100644 test/static_vector_options_test.cpp diff --git a/test/small_vector_options_test.cpp b/test/small_vector_options_test.cpp new file mode 100644 index 0000000..73e4855 --- /dev/null +++ b/test/small_vector_options_test.cpp @@ -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 +#include +#include +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::value); + #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + using options_t = small_vector_options_t< inplace_alignment >; + #else + typedef small_vector_options + < inplace_alignment >::type options_t; + #endif + + small_vector v; + v.resize(v.capacity()); + BOOST_ASSERT((reinterpret_cast(&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 v; + v.resize(v.capacity()); + BOOST_ASSERT((reinterpret_cast(&v[0]) % dtl::alignment_of::value) == 0); + } +} + +void test_growth_factor_50() +{ + #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + using options_t = small_vector_options_t< growth_factor >; + #else + typedef small_vector_options + < growth_factor >::type options_t; + #endif + + small_vector, 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 >; + #else + typedef small_vector_options + < growth_factor >::type options_t; + #endif + + small_vector, 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 >; + #else + typedef small_vector_options + < growth_factor >::type options_t; + #endif + + small_vector, 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(); +} diff --git a/test/static_vector_options_test.cpp b/test/static_vector_options_test.cpp new file mode 100644 index 0000000..e8965d5 --- /dev/null +++ b/test/static_vector_options_test.cpp @@ -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 +#include +#include //for bad_alloc +#include +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::value); + #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + using options_t = static_vector_options_t< inplace_alignment >; + #else + typedef static_vector_options + < inplace_alignment >::type options_t; + #endif + + static_vector v; + v.resize(v.capacity()); + BOOST_ASSERT((reinterpret_cast(&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 v; + v.resize(v.capacity()); + BOOST_ASSERT((reinterpret_cast(&v[0]) % dtl::alignment_of::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 >; + #else + typedef static_vector_options + < throw_on_overflow >::type options_t; + #endif + + static_vector 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 >; + #else + typedef static_vector_options< throw_on_overflow >::type options_t; + #endif + + static_vector 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(); +}