diff --git a/include/boost/container/deque.hpp b/include/boost/container/deque.hpp index f04ba49..35cea2f 100644 --- a/include/boost/container/deque.hpp +++ b/include/boost/container/deque.hpp @@ -2238,7 +2238,7 @@ class deque : protected deque_base #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD template deque(InputIterator, InputIterator) -> deque::value_type>; template diff --git a/include/boost/container/detail/iterator.hpp b/include/boost/container/detail/iterator.hpp index 2ceaf26..844f3fd 100644 --- a/include/boost/container/detail/iterator.hpp +++ b/include/boost/container/detail/iterator.hpp @@ -23,6 +23,7 @@ #include #include +#include namespace boost { namespace container { @@ -63,6 +64,18 @@ class back_emplacer back_emplacer& operator++(int){ return *this; } }; +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + +template +using it_based_non_const_first_type_t = typename dtl::remove_const::value_type::first_type>::type; + +template +using it_based_second_type_t = typename iterator_traits::value_type::second_type; + +template +using it_based_value_type_t = typename iterator_traits::value_type; + +#endif } //namespace container { } //namespace boost { diff --git a/include/boost/container/detail/mpl.hpp b/include/boost/container/detail/mpl.hpp index 5249dbf..4706c58 100644 --- a/include/boost/container/detail/mpl.hpp +++ b/include/boost/container/detail/mpl.hpp @@ -61,6 +61,7 @@ using boost::move_detail::enable_if_and; using boost::move_detail::disable_if_and; using boost::move_detail::enable_if_or; using boost::move_detail::disable_if_or; +using boost::move_detail::remove_const; template struct select1st @@ -102,6 +103,36 @@ struct enable_if_transparent : boost::move_detail::enable_if_c::value, R> {}; +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + +// void_t (void_t for C++11) +template using variadic_void_t = void; + +// Trait to detect Allocator-like types. +template +struct is_allocator +{ + static const bool value = false; +}; + +template +T&& ctad_declval(); + +template +struct is_allocator < Allocator, + variadic_void_t< typename Allocator::value_type + , decltype(ctad_declval().allocate(size_t{})) >> +{ + static const bool value = true; +}; + +template +using require_allocator_t = typename enable_if_c::value, T>::type; + +template +using require_nonallocator_t = typename enable_if_c::value, T>::type; + +#endif } //namespace dtl { } //namespace container { diff --git a/include/boost/container/detail/workaround.hpp b/include/boost/container/detail/workaround.hpp index 1fea112..4e49c0a 100644 --- a/include/boost/container/detail/workaround.hpp +++ b/include/boost/container/detail/workaround.hpp @@ -119,4 +119,11 @@ #define BOOST_CONTAINER_ASAN #endif + +#if (__cplusplus >= 201703L) +//CTAD supported +#else +#define BOOST_CONTAINER_NO_CXX17_CTAD +#endif + #endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP diff --git a/include/boost/container/flat_map.hpp b/include/boost/container/flat_map.hpp index e11522a..5cbbf9c 100644 --- a/include/boost/container/flat_map.hpp +++ b/include/boost/container/flat_map.hpp @@ -319,6 +319,21 @@ class flat_map : m_flat_tree(ordered_range, first, last, comp, dtl::force(a)) {} + //! Effects: Constructs an empty flat_map using the specified allocator and + //! inserts elements from the ordered range [first ,last). This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! Requires: [first ,last) must be ordered according to the predicate. + //! + //! Complexity: Linear in N. + //! + //! Note: Non-standard extension. + template + BOOST_CONTAINER_FORCEINLINE + flat_map(ordered_unique_range_t, InputIterator first, InputIterator last, const allocator_type& a) + : m_flat_tree(ordered_range, first, last, Compare(), a) + {} + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! Effects: Constructs an empty flat_map and //! inserts elements from the range [il.begin() ,il.end()). @@ -1563,89 +1578,63 @@ class flat_map #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD template flat_map(InputIterator, InputIterator) -> - flat_map< typename dtl::remove_const< typename iterator_traits::value_type::first_type>::type - , typename iterator_traits::value_type::second_type>; + flat_map< it_based_non_const_first_type_t + , it_based_second_type_t>; -#ifdef BOOST_HAS_CTAD_SFINAE - -namespace dtl { - - template - using enable_if_allocator_t = std::enable_if_t().allocate(0)), U *>, T>; - - template - using enable_if_compare_t = std::enable_if_t()(std::declval(), std::declval())), bool>, T>; - -} // namespace dtl - -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> flat_map(InputIterator, InputIterator, Allocator const&) -> - flat_map< typename dtl::remove_const< typename iterator_traits::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , std::less::value_type::first_type>::type> - , dtl::enable_if_allocator_t::value_type>>>; + flat_map< it_based_non_const_first_type_t + , it_based_second_type_t + , std::less> + , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> flat_map(InputIterator, InputIterator, Compare const&) -> - flat_map< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , dtl::enable_if_compare_t::value_type::first_type>>>; - -#else - -template -flat_map(InputIterator, InputIterator, Compare const&) -> - flat_map< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type + flat_map< it_based_non_const_first_type_t + , it_based_second_type_t , Compare>; -#endif - -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> flat_map(InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_map< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type + flat_map< it_based_non_const_first_type_t + , it_based_second_type_t , Compare , Allocator>; template flat_map(ordered_unique_range_t, InputIterator, InputIterator) -> - flat_map< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type>; + flat_map< it_based_non_const_first_type_t + , it_based_second_type_t>; -#ifdef BOOST_HAS_CTAD_SFINAE - -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> flat_map(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) -> - flat_map< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , std::less::value_type::first_type>::type> - , dtl::enable_if_allocator_t::value_type>>>; + flat_map< it_based_non_const_first_type_t + , it_based_second_type_t + , std::less> + , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> flat_map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) -> - flat_map< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , dtl::enable_if_compare_t::value_type::first_type>>>; - -#else - -template -flat_map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) -> - flat_map< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type + flat_map< it_based_non_const_first_type_t + , it_based_second_type_t , Compare>; -#endif - -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> flat_map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_map< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type + flat_map< it_based_non_const_first_type_t + , it_based_second_type_t , Compare , Allocator>; @@ -1912,6 +1901,21 @@ class flat_multimap : m_flat_tree(ordered_range, first, last, comp, a) {} + //! Effects: Constructs an empty flat_multimap using the specified comparison object and + //! inserts elements from the ordered range [first ,last). This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! Requires: [first ,last) must be ordered according to the predicate. + //! + //! Complexity: Linear in N. + //! + //! Note: Non-standard extension. + template + BOOST_CONTAINER_FORCEINLINE + flat_multimap(ordered_range_t, InputIterator first, InputIterator last, const allocator_type &a) + : m_flat_tree(ordered_range, first, last, Compare(), a) + {} + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! Effects: Constructs an empty flat_map and //! inserts elements from the range [il.begin(), il.end()). @@ -2880,82 +2884,65 @@ class flat_multimap { x.swap(y); } }; -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD template flat_multimap(InputIterator, InputIterator) -> - flat_multimap::value_type::first_type>::type - , typename iterator_traits::value_type::second_type>; + flat_multimap< it_based_non_const_first_type_t + , it_based_second_type_t>; -#ifdef BOOST_HAS_CTAD_SFINAE - -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> flat_multimap(InputIterator, InputIterator, Allocator const&) -> - flat_multimap::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , std::less::value_type::first_type>::type> - , dtl::enable_if_allocator_t::value_type>>>; + flat_multimap< it_based_non_const_first_type_t + , it_based_second_type_t + , std::less> + , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> flat_multimap(InputIterator, InputIterator, Compare const&) -> - flat_multimap< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , dtl::enable_if_compare_t::value_type::first_type>>>; + flat_multimap< it_based_non_const_first_type_t + , it_based_second_type_t + , Compare>; -#else - -template -flat_multimap(InputIterator, InputIterator, Compare const&) -> - flat_multimap< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , Compare>; - -#endif - -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> flat_multimap(InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_multimap< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , Compare - , Allocator>; + flat_multimap< it_based_non_const_first_type_t + , it_based_second_type_t + , Compare + , Allocator>; template flat_multimap(ordered_range_t, InputIterator, InputIterator) -> - flat_multimap< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type>; + flat_multimap< it_based_non_const_first_type_t + , it_based_second_type_t>; -#ifdef BOOST_HAS_CTAD_SFINAE - -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> flat_multimap(ordered_range_t, InputIterator, InputIterator, Allocator const&) -> - flat_multimap< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , std::less::value_type::first_type>::type> - , dtl::enable_if_allocator_t::value_type>>>; + flat_multimap< it_based_non_const_first_type_t + , it_based_second_type_t + , std::less> + , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> flat_multimap(ordered_range_t, InputIterator, InputIterator, Compare const&) -> - flat_multimap< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , dtl::enable_if_compare_t::value_type::first_type>>>; + flat_multimap< it_based_non_const_first_type_t + , it_based_second_type_t + , Compare>; -#else - -template -flat_multimap(ordered_range_t, InputIterator, InputIterator, Compare const&) -> - flat_multimap< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , Compare>; - -#endif - - -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> flat_multimap(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_multimap< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , Compare - , Allocator>; + flat_multimap< it_based_non_const_first_type_t + , it_based_second_type_t + , Compare + , Allocator>; #endif diff --git a/include/boost/container/flat_set.hpp b/include/boost/container/flat_set.hpp index c4dd827..bd0b3cf 100644 --- a/include/boost/container/flat_set.hpp +++ b/include/boost/container/flat_set.hpp @@ -257,6 +257,22 @@ class flat_set : tree_t(ordered_unique_range, first, last, comp, a) {} + //! Effects: Constructs an empty container using the specified allocator and + //! inserts elements from the ordered unique range [first ,last). This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! Requires: [first ,last) must be ordered according to the predicate and must be + //! unique values. + //! + //! Complexity: Linear in N. + //! + //! Note: Non-standard extension. + template + BOOST_CONTAINER_FORCEINLINE + flat_set(ordered_unique_range_t, InputIterator first, InputIterator last, const allocator_type& a) + : tree_t(ordered_unique_range, first, last, Compare(), a) + {} + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! Effects: Constructs an empty container and //! inserts elements from the range [il.begin(), il.end()). @@ -1108,39 +1124,57 @@ class flat_set #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD template flat_set(InputIterator, InputIterator) -> - flat_set::value_type>; + flat_set< it_based_value_type_t >; -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> flat_set(InputIterator, InputIterator, Allocator const&) -> - flat_set::value_type, std::less::value_type>, Allocator>; + flat_set< it_based_value_type_t + , std::less> + , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> flat_set(InputIterator, InputIterator, Compare const&) -> - flat_set::value_type, Compare>; + flat_set< it_based_value_type_t + , Compare>; -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> flat_set(InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_set::value_type, Compare, Allocator>; + flat_set< it_based_value_type_t + , Compare + , Allocator>; template flat_set(ordered_unique_range_t, InputIterator, InputIterator) -> - flat_set::value_type>; + flat_set< it_based_value_type_t>; -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> flat_set(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) -> - flat_set::value_type, std::less::value_type>, Allocator>; + flat_set< it_based_value_type_t + , std::less> + , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> flat_set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) -> - flat_set::value_type, Compare>; + flat_set< it_based_value_type_t + , Compare>; -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> flat_set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_set::value_type, Compare, Allocator>; + flat_set< it_based_value_type_t + , Compare + , Allocator>; #endif @@ -1320,6 +1354,20 @@ class flat_multiset : tree_t(ordered_range, first, last, comp, a) {} + //! Effects: Constructs an empty flat_multiset using the specified allocator and + //! inserts elements from the ordered range [first ,last ). This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! Requires: [first ,last) must be ordered according to the predicate. + //! + //! Complexity: Linear in N. + //! + //! Note: Non-standard extension. + template + BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, InputIterator first, InputIterator last, const allocator_type &a) + : tree_t(ordered_range, first, last, Compare(), a) + {} + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list il) @@ -1805,43 +1853,57 @@ class flat_multiset #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD template flat_multiset(InputIterator, InputIterator) -> - flat_multiset::value_type>; + flat_multiset< it_based_value_type_t >; -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> flat_multiset(InputIterator, InputIterator, Allocator const&) -> - flat_multiset< typename iterator_traits::value_type - , std::less::value_type> - , Allocator>; + flat_multiset< it_based_value_type_t + , std::less> + , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> flat_multiset(InputIterator, InputIterator, Compare const&) -> - flat_multiset::value_type, Compare>; + flat_multiset< it_based_value_type_t + , Compare>; -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> flat_multiset(InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_multiset::value_type, Compare, Allocator>; + flat_multiset< it_based_value_type_t + , Compare + , Allocator>; template flat_multiset(ordered_range_t, InputIterator, InputIterator) -> - flat_multiset::value_type>; + flat_multiset< it_based_value_type_t>; -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> flat_multiset(ordered_range_t, InputIterator, InputIterator, Allocator const&) -> - flat_multiset< typename iterator_traits::value_type - , std::less::value_type> - , Allocator>; + flat_multiset< it_based_value_type_t + , std::less> + , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> flat_multiset(ordered_range_t, InputIterator, InputIterator, Compare const&) -> - flat_multiset< typename iterator_traits::value_type, Compare>; + flat_multiset< it_based_value_type_t + , Compare>; -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> flat_multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_multiset::value_type, Compare, Allocator>; + flat_multiset< it_based_value_type_t + , Compare + , Allocator>; #endif diff --git a/include/boost/container/list.hpp b/include/boost/container/list.hpp index 2e512f9..4be33fc 100644 --- a/include/boost/container/list.hpp +++ b/include/boost/container/list.hpp @@ -1498,7 +1498,7 @@ class list }; -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD template list(InputIterator, InputIterator) -> list::value_type>; diff --git a/include/boost/container/map.hpp b/include/boost/container/map.hpp index 02bd74f..98109ad 100644 --- a/include/boost/container/map.hpp +++ b/include/boost/container/map.hpp @@ -256,6 +256,22 @@ class map : base_t(ordered_range, first, last, comp, a) {} + //! Effects: Constructs an empty map using the specified allocator object and + //! inserts elements from the ordered unique range [first ,last). This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! Requires: [first ,last) must be ordered according to the predicate and must be + //! unique values. + //! + //! Complexity: Linear in N. + //! + //! Note: Non-standard extension. + template + BOOST_CONTAINER_FORCEINLINE map(ordered_unique_range_t, InputIterator first, InputIterator last, const allocator_type& a) + : base_t(ordered_range, first, last, Compare(), a) + {} + + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! Effects: Constructs an empty map and //! inserts elements from the range [il.begin(), il.end()). @@ -1279,55 +1295,63 @@ class map #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD template map(InputIterator, InputIterator) -> - map< typename dtl::remove_const< typename iterator_traits::value_type::first_type>::type - , typename iterator_traits::value_type::second_type>; + map< it_based_non_const_first_type_t + , it_based_second_type_t>; -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> map(InputIterator, InputIterator, Allocator const&) -> - map< typename dtl::remove_const< typename iterator_traits::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , std::less::value_type::first_type>::type> + map< it_based_non_const_first_type_t + , it_based_second_type_t + , std::less> , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> map(InputIterator, InputIterator, Compare const&) -> - map< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type + map< it_based_non_const_first_type_t + , it_based_second_type_t , Compare>; -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> map(InputIterator, InputIterator, Compare const&, Allocator const&) -> - map< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type + map< it_based_non_const_first_type_t + , it_based_second_type_t , Compare , Allocator>; template map(ordered_unique_range_t, InputIterator, InputIterator) -> - map< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type>; + map< it_based_non_const_first_type_t + , it_based_second_type_t>; -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> map(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) -> - map< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , std::less::value_type::first_type>::type> + map< it_based_non_const_first_type_t + , it_based_second_type_t + , std::less> , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) -> - map< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type + map< it_based_non_const_first_type_t + , it_based_second_type_t , Compare>; -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - map< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type + map< it_based_non_const_first_type_t + , it_based_second_type_t , Compare , Allocator>; @@ -1552,6 +1576,20 @@ class multimap : base_t(ordered_range, first, last, comp, a) {} + //! Effects: Constructs an empty multimap using the specified allocator and + //! inserts elements from the ordered range [first ,last). This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! Requires: [first ,last) must be ordered according to the predicate. + //! + //! Complexity: Linear in N. + //! + //! Note: Non-standard extension. + template + BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last, const allocator_type& a) + : base_t(ordered_range, first, last, Compare(), a) + {} + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! Effects: Constructs an empty multimap and //! and inserts elements from the range [il.begin(), il.end()). @@ -2184,58 +2222,65 @@ class multimap #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) }; -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD template multimap(InputIterator, InputIterator) -> - multimap::value_type::first_type>::type - , typename iterator_traits::value_type::second_type>; + multimap< it_based_non_const_first_type_t + , it_based_second_type_t>; -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> multimap(InputIterator, InputIterator, Allocator const&) -> - multimap::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , std::less::value_type::first_type>::type> - , Allocator>; + multimap< it_based_non_const_first_type_t + , it_based_second_type_t + , std::less> + , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> multimap(InputIterator, InputIterator, Compare const&) -> - multimap< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type + multimap< it_based_non_const_first_type_t + , it_based_second_type_t , Compare>; -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> multimap(InputIterator, InputIterator, Compare const&, Allocator const&) -> - multimap< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type + multimap< it_based_non_const_first_type_t + , it_based_second_type_t , Compare , Allocator>; template multimap(ordered_range_t, InputIterator, InputIterator) -> - multimap< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type>; + multimap< it_based_non_const_first_type_t + , it_based_second_type_t>; -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> multimap(ordered_range_t, InputIterator, InputIterator, Allocator const&) -> - multimap< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type - , std::less::value_type::first_type>::type> + multimap< it_based_non_const_first_type_t + , it_based_second_type_t + , std::less> , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> multimap(ordered_range_t, InputIterator, InputIterator, Compare const&) -> - multimap< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type + multimap< it_based_non_const_first_type_t + , it_based_second_type_t , Compare>; -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> multimap(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - multimap< typename dtl::remove_const::value_type::first_type>::type - , typename iterator_traits::value_type::second_type + multimap< it_based_non_const_first_type_t + , it_based_second_type_t , Compare , Allocator>; - #endif #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED diff --git a/include/boost/container/set.hpp b/include/boost/container/set.hpp index c2e6890..c985c7e 100644 --- a/include/boost/container/set.hpp +++ b/include/boost/container/set.hpp @@ -227,6 +227,21 @@ class set : base_t(ordered_range, first, last, comp, a) {} + //! Effects: Constructs an empty set using the specified allocator and + //! inserts elements from the ordered unique range [first ,last). This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! Requires: [first ,last) must be ordered according to the predicate and must be + //! unique values. + //! + //! Complexity: Linear in N. + //! + //! Note: Non-standard extension. + template + BOOST_CONTAINER_FORCEINLINE set(ordered_unique_range_t, InputIterator first, InputIterator last, const allocator_type& a) + : base_t(ordered_range, first, last, Compare(), a) + {} + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! Effects: Constructs an empty set and //! inserts elements from the range [il.begin(), il.end()). @@ -944,39 +959,57 @@ class set #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD template set(InputIterator, InputIterator) -> - set::value_type>; + set< it_based_value_type_t >; -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> set(InputIterator, InputIterator, Allocator const&) -> - set::value_type, std::less::value_type>, Allocator>; + set< it_based_value_type_t + , std::less> + , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> set(InputIterator, InputIterator, Compare const&) -> - set::value_type, Compare>; + set< it_based_value_type_t + , Compare>; -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> set(InputIterator, InputIterator, Compare const&, Allocator const&) -> - set::value_type, Compare, Allocator>; + set< it_based_value_type_t + , Compare + , Allocator>; template set(ordered_unique_range_t, InputIterator, InputIterator) -> - set::value_type>; + set< it_based_value_type_t>; -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> set(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) -> - set::value_type, std::less::value_type>, Allocator>; + set< it_based_value_type_t + , std::less> + , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) -> - set::value_type, Compare>; + set< it_based_value_type_t + , Compare>; -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - set::value_type, Compare, Allocator>; + set< it_based_value_type_t + , Compare + , Allocator>; #endif @@ -1150,6 +1183,20 @@ class multiset : base_t(ordered_range, first, last, comp, a) {} + //! Effects: Constructs an empty multiset using the specified allocator and + //! inserts elements from the ordered range [first ,last ). This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! Requires: [first ,last) must be ordered according to the predicate. + //! + //! Complexity: Linear in N. + //! + //! Note: Non-standard extension. + template + BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, InputIterator first, InputIterator last, const allocator_type &a) + : base_t(ordered_range, first, last, Compare(), a) + {} + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! @copydoc ::boost::container::set::set(std::initializer_list) BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list il) @@ -1573,43 +1620,57 @@ class multiset #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD template multiset(InputIterator, InputIterator) -> - multiset::value_type>; + multiset< it_based_value_type_t >; -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> multiset(InputIterator, InputIterator, Allocator const&) -> - multiset< typename iterator_traits::value_type - , std::less::value_type> - , Allocator>; + multiset< it_based_value_type_t + , std::less> + , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> multiset(InputIterator, InputIterator, Compare const&) -> - multiset::value_type, Compare>; + multiset< it_based_value_type_t + , Compare>; -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> multiset(InputIterator, InputIterator, Compare const&, Allocator const&) -> - multiset::value_type, Compare, Allocator>; + multiset< it_based_value_type_t + , Compare + , Allocator>; template multiset(ordered_range_t, InputIterator, InputIterator) -> - multiset::value_type>; + multiset< it_based_value_type_t>; -template +template < typename InputIterator, typename Allocator + , typename = dtl::require_allocator_t> multiset(ordered_range_t, InputIterator, InputIterator, Allocator const&) -> - multiset< typename iterator_traits::value_type - , std::less::value_type> - , Allocator>; + multiset< it_based_value_type_t + , std::less> + , Allocator>; -template +template < typename InputIterator, typename Compare + , typename = dtl::require_nonallocator_t> multiset(ordered_range_t, InputIterator, InputIterator, Compare const&) -> - multiset< typename iterator_traits::value_type, Compare>; + multiset< it_based_value_type_t + , Compare>; -template +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t + , typename = dtl::require_allocator_t> multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - multiset::value_type, Compare, Allocator>; + multiset< it_based_value_type_t + , Compare + , Allocator>; #endif diff --git a/include/boost/container/slist.hpp b/include/boost/container/slist.hpp index 2bdf843..6310f58 100644 --- a/include/boost/container/slist.hpp +++ b/include/boost/container/slist.hpp @@ -1668,7 +1668,7 @@ class slist #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD template slist(InpIt, InpIt) -> diff --git a/include/boost/container/stable_vector.hpp b/include/boost/container/stable_vector.hpp index cf7a0ef..1f55c43 100644 --- a/include/boost/container/stable_vector.hpp +++ b/include/boost/container/stable_vector.hpp @@ -2142,7 +2142,7 @@ class stable_vector #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD template stable_vector(InputIterator, InputIterator) -> diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp index 99120a1..ca51cfd 100644 --- a/include/boost/container/string.hpp +++ b/include/boost/container/string.hpp @@ -2978,7 +2978,7 @@ class basic_string #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD template basic_string(InputIterator, InputIterator) -> diff --git a/include/boost/container/vector.hpp b/include/boost/container/vector.hpp index aa4b505..939b62f 100644 --- a/include/boost/container/vector.hpp +++ b/include/boost/container/vector.hpp @@ -3370,7 +3370,7 @@ class vector #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD template vector(InputIterator, InputIterator) -> diff --git a/test/deque_test.cpp b/test/deque_test.cpp index 86173db..01c47e0 100644 --- a/test/deque_test.cpp +++ b/test/deque_test.cpp @@ -268,7 +268,7 @@ bool do_test() if(!test::CheckEqualContainers(cntdeque, stddeque)) return 1; } -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD //Check Constructor Template Auto Deduction { auto gold = MyStdDeque{ 1, 2, 3 }; diff --git a/test/flat_map_test.cpp b/test/flat_map_test.cpp index bd7af01..f1cc06b 100644 --- a/test/flat_map_test.cpp +++ b/test/flat_map_test.cpp @@ -178,28 +178,98 @@ bool flat_tree_ordered_insertion_test() bool constructor_template_auto_deduction_test() { -#if __cplusplus >= 201703L + +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD using namespace boost::container; const std::size_t NumElements = 100; - //Ordered insertion map { std::map int_map; for(std::size_t i = 0; i != NumElements; ++i){ int_map.insert(std::map::value_type(static_cast(i), static_cast(i))); } - //Construction insertion - auto fmap = flat_map(ordered_unique_range, int_map.begin(), int_map.end()); - if(!CheckEqualContainers(int_map, fmap)) - return false; - std::multimap int_mmap; - for(std::size_t i = 0; i != NumElements; ++i){ + for (std::size_t i = 0; i != NumElements; ++i) { int_mmap.insert(std::multimap::value_type(static_cast(i), static_cast(i))); } - //Construction insertion - auto fmmap = flat_multimap(ordered_range, int_mmap.begin(), int_mmap.end()); - if(!CheckEqualContainers(int_mmap, fmmap)) - return false; + + typedef std::less comp_int_t; + typedef std::allocator > alloc_pair_int_t; + + //range + { + auto fmap = flat_map(int_map.begin(), int_map.end()); + if (!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = flat_multimap(int_mmap.begin(), int_mmap.end()); + if (!CheckEqualContainers(int_mmap, fmmap)) + return false; + } + //range+comp + { + auto fmap = flat_map(int_map.begin(), int_map.end(), comp_int_t()); + if (!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = flat_multimap(int_mmap.begin(), int_mmap.end(), comp_int_t()); + if (!CheckEqualContainers(int_mmap, fmmap)) + return false; + } + //range+comp+alloc + { + auto fmap = flat_map(int_map.begin(), int_map.end(), comp_int_t(), alloc_pair_int_t()); + if (!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = flat_multimap(int_mmap.begin(), int_mmap.end(), comp_int_t(), alloc_pair_int_t()); + if (!CheckEqualContainers(int_mmap, fmmap)) + return false; + } + //range+alloc + { + auto fmap = flat_map(int_map.begin(), int_map.end(), alloc_pair_int_t()); + if (!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = flat_multimap(int_mmap.begin(), int_mmap.end(), alloc_pair_int_t()); + if (!CheckEqualContainers(int_mmap, fmmap)) + return false; + } + + //ordered_unique_range / ordered_range + + //range + { + auto fmap = flat_map(ordered_unique_range, int_map.begin(), int_map.end()); + if(!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = flat_multimap(ordered_range, int_mmap.begin(), int_mmap.end()); + if(!CheckEqualContainers(int_mmap, fmmap)) + return false; + } + //range+comp + { + auto fmap = flat_map(ordered_unique_range, int_map.begin(), int_map.end(), comp_int_t()); + if (!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = flat_multimap(ordered_range, int_mmap.begin(), int_mmap.end(), comp_int_t()); + if (!CheckEqualContainers(int_mmap, fmmap)) + return false; + } + //range+comp+alloc + { + auto fmap = flat_map(ordered_unique_range, int_map.begin(), int_map.end(), comp_int_t(), alloc_pair_int_t()); + if (!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = flat_multimap(ordered_range, int_mmap.begin(), int_mmap.end(), comp_int_t(), alloc_pair_int_t()); + if (!CheckEqualContainers(int_mmap, fmmap)) + return false; + } + //range+alloc + { + auto fmap = flat_map(ordered_unique_range, int_map.begin(), int_map.end(),alloc_pair_int_t()); + if (!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = flat_multimap(ordered_range, int_mmap.begin(), int_mmap.end(),alloc_pair_int_t()); + if (!CheckEqualContainers(int_mmap, fmmap)) + return false; + } } #endif @@ -476,7 +546,7 @@ bool test_heterogeneous_lookups() int main() { using namespace boost::container::test; -/* + //Allocator argument container { flat_map map_((flat_map::allocator_type())); @@ -530,7 +600,7 @@ int main() if (!test_heterogeneous_lookups()) return 1; -*/ + //////////////////////////////////// // Testing allocator implementations //////////////////////////////////// @@ -546,7 +616,7 @@ int main() std::cout << "Error in map_test >" << std::endl; return 1; } - /* + if (0 != test::map_test < GetMapContainer >::apply::map_type , MyStdMap @@ -581,9 +651,9 @@ int main() , MyStdMultiMap>()) { std::cout << "Error in map_test >" << std::endl; return 1; - }*/ + } } -/* + if(!boost::container::test::test_map_support_for_initialization_list_for >()) return 1; @@ -628,7 +698,7 @@ int main() return 1; } } -*/ + return 0; } diff --git a/test/flat_set_test.cpp b/test/flat_set_test.cpp index 753c074..7e561f7 100644 --- a/test/flat_set_test.cpp +++ b/test/flat_set_test.cpp @@ -276,6 +276,106 @@ bool flat_tree_ordered_insertion_test() return true; } +bool constructor_template_auto_deduction_test() +{ + +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + using namespace boost::container; + const std::size_t NumElements = 100; + { + std::set int_set; + for (std::size_t i = 0; i != NumElements; ++i) { + int_set.insert(static_cast(i)); + } + std::multiset int_mset; + for (std::size_t i = 0; i != NumElements; ++i) { + int_mset.insert(static_cast(i)); + } + + typedef std::less comp_int_t; + typedef std::allocator alloc_int_t; + + //range + { + auto fset = flat_set(int_set.begin(), int_set.end()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = flat_multiset(int_mset.begin(), int_mset.end()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + //range+comp + { + auto fset = flat_set(int_set.begin(), int_set.end(), comp_int_t()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = flat_multiset(int_mset.begin(), int_mset.end(), comp_int_t()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + //range+comp+alloc + { + auto fset = flat_set(int_set.begin(), int_set.end(), comp_int_t(), alloc_int_t()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = flat_multiset(int_mset.begin(), int_mset.end(), comp_int_t(), alloc_int_t()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + //range+alloc + { + auto fset = flat_set(int_set.begin(), int_set.end(), alloc_int_t()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = flat_multiset(int_mset.begin(), int_mset.end(), alloc_int_t()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + + //ordered_unique_range / ordered_range + + //range + { + auto fset = flat_set(ordered_unique_range, int_set.begin(), int_set.end()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = flat_multiset(ordered_range, int_mset.begin(), int_mset.end()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + //range+comp + { + auto fset = flat_set(ordered_unique_range, int_set.begin(), int_set.end(), comp_int_t()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = flat_multiset(ordered_range, int_mset.begin(), int_mset.end(), comp_int_t()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + //range+comp+alloc + { + auto fset = flat_set(ordered_unique_range, int_set.begin(), int_set.end(), comp_int_t(), alloc_int_t()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = flat_multiset(ordered_range, int_mset.begin(), int_mset.end(), comp_int_t(), alloc_int_t()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + //range+alloc + { + auto fset = flat_set(ordered_unique_range, int_set.begin(), int_set.end(), alloc_int_t()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = flat_multiset(ordered_range, int_mset.begin(), int_mset.end(), alloc_int_t()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + } +#endif + + return true; +} + template< class RandomIt > void random_shuffle( RandomIt first, RandomIt last ) { @@ -594,6 +694,13 @@ int main() return 1; } + //////////////////////////////////// + // Constructor Template Auto Deduction test + //////////////////////////////////// + if (!constructor_template_auto_deduction_test()) { + return 1; + } + //////////////////////////////////// // Extract/Adopt test //////////////////////////////////// @@ -706,30 +813,6 @@ int main() } } -#if __cplusplus >= 201703L - //////////////////////////////////// - // Constructor Template Auto Deduction - //////////////////////////////////// - { - auto gold = std::set({ 1, 2, 3 }); - auto test = boost::container::flat_set(gold.begin(), gold.end()); - if (test.size() != 3) - return 1; - test = boost::container::flat_set(ordered_unique_range, gold.begin(), gold.end()); - if (test.size() != 3) - return 1; - } - { - auto gold = std::multiset({ 1, 2, 3 }); - auto test = boost::container::flat_multiset(gold.begin(), gold.end()); - if (test.size() != 3) - return 1; - test = boost::container::flat_multiset(ordered_range, gold.begin(), gold.end()); - if (test.size() != 3) - return 1; - } -#endif - return 0; } diff --git a/test/list_test.cpp b/test/list_test.cpp index 8348725..5006a7d 100644 --- a/test/list_test.cpp +++ b/test/list_test.cpp @@ -214,7 +214,7 @@ int main () } } -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD //////////////////////////////////// // Constructor Template Auto Deduction Tests //////////////////////////////////// diff --git a/test/map_test.cpp b/test/map_test.cpp index ca323f2..90998f0 100644 --- a/test/map_test.cpp +++ b/test/map_test.cpp @@ -337,6 +337,106 @@ bool test_heterogeneous_lookups() return true; } +bool constructor_template_auto_deduction_test() +{ + +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + using namespace boost::container; + const std::size_t NumElements = 100; + { + std::map int_map; + for(std::size_t i = 0; i != NumElements; ++i){ + int_map.insert(std::map::value_type(static_cast(i), static_cast(i))); + } + std::multimap int_mmap; + for (std::size_t i = 0; i != NumElements; ++i) { + int_mmap.insert(std::multimap::value_type(static_cast(i), static_cast(i))); + } + + typedef std::less comp_int_t; + typedef std::allocator > alloc_pair_int_t; + + //range + { + auto fmap = map(int_map.begin(), int_map.end()); + if (!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = multimap(int_mmap.begin(), int_mmap.end()); + if (!CheckEqualContainers(int_mmap, fmmap)) + return false; + } + //range+comp + { + auto fmap = map(int_map.begin(), int_map.end(), comp_int_t()); + if (!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = multimap(int_mmap.begin(), int_mmap.end(), comp_int_t()); + if (!CheckEqualContainers(int_mmap, fmmap)) + return false; + } + //range+comp+alloc + { + auto fmap = map(int_map.begin(), int_map.end(), comp_int_t(), alloc_pair_int_t()); + if (!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = multimap(int_mmap.begin(), int_mmap.end(), comp_int_t(), alloc_pair_int_t()); + if (!CheckEqualContainers(int_mmap, fmmap)) + return false; + } + //range+alloc + { + auto fmap = map(int_map.begin(), int_map.end(), alloc_pair_int_t()); + if (!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = multimap(int_mmap.begin(), int_mmap.end(), alloc_pair_int_t()); + if (!CheckEqualContainers(int_mmap, fmmap)) + return false; + } + + //ordered_unique_range / ordered_range + + //range + { + auto fmap = map(ordered_unique_range, int_map.begin(), int_map.end()); + if(!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = multimap(ordered_range, int_mmap.begin(), int_mmap.end()); + if(!CheckEqualContainers(int_mmap, fmmap)) + return false; + } + //range+comp + { + auto fmap = map(ordered_unique_range, int_map.begin(), int_map.end(), comp_int_t()); + if (!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = multimap(ordered_range, int_mmap.begin(), int_mmap.end(), comp_int_t()); + if (!CheckEqualContainers(int_mmap, fmmap)) + return false; + } + //range+comp+alloc + { + auto fmap = map(ordered_unique_range, int_map.begin(), int_map.end(), comp_int_t(), alloc_pair_int_t()); + if (!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = multimap(ordered_range, int_mmap.begin(), int_mmap.end(), comp_int_t(), alloc_pair_int_t()); + if (!CheckEqualContainers(int_mmap, fmmap)) + return false; + } + //range+alloc + { + auto fmap = map(ordered_unique_range, int_map.begin(), int_map.end(),alloc_pair_int_t()); + if (!CheckEqualContainers(int_map, fmap)) + return false; + auto fmmap = multimap(ordered_range, int_mmap.begin(), int_mmap.end(),alloc_pair_int_t()); + if (!CheckEqualContainers(int_mmap, fmmap)) + return false; + } + } +#endif + + return true; +} + }}} //namespace boost::container::test int main () @@ -474,30 +574,19 @@ int main () } } -#if __cplusplus >= 201703L - //////////////////////////////////// - // Constructor Template Auto Deduction - //////////////////////////////////// - { - auto gold = std::map({ {1,1}, {2,2}, {3,3} } ); - auto test = boost::container::map(gold.begin(), gold.end()); - if (test.size() != 3) - return 1; - } - { - auto gold = std::multimap({ {1,1}, {2,2}, {3,3} } ); - auto test = boost::container::multimap(gold.begin(), gold.end()); - if (test.size() != 3) - return 1; - } -#endif - //////////////////////////////////// // Node extraction/insertion testing functions //////////////////////////////////// if(!node_type_test()) return 1; + //////////////////////////////////// + // Constructor Template Auto Deduction test + //////////////////////////////////// + if (!test::constructor_template_auto_deduction_test()) { + return 1; + } + if (!boost::container::test::instantiate_constructors, multimap >()) return 1; diff --git a/test/set_test.cpp b/test/set_test.cpp index 33cc0a4..9164222 100644 --- a/test/set_test.cpp +++ b/test/set_test.cpp @@ -206,6 +206,104 @@ struct alloc_propagate_base }; }; +bool constructor_template_auto_deduction_test() +{ +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + using namespace boost::container; + const std::size_t NumElements = 100; + { + std::set int_set; + for (std::size_t i = 0; i != NumElements; ++i) { + int_set.insert(static_cast(i)); + } + std::multiset int_mset; + for (std::size_t i = 0; i != NumElements; ++i) { + int_mset.insert(static_cast(i)); + } + + typedef std::less comp_int_t; + typedef std::allocator alloc_int_t; + + //range + { + auto fset = set(int_set.begin(), int_set.end()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = multiset(int_mset.begin(), int_mset.end()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + //range+comp + { + auto fset = set(int_set.begin(), int_set.end(), comp_int_t()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = multiset(int_mset.begin(), int_mset.end(), comp_int_t()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + //range+comp+alloc + { + auto fset = set(int_set.begin(), int_set.end(), comp_int_t(), alloc_int_t()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = multiset(int_mset.begin(), int_mset.end(), comp_int_t(), alloc_int_t()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + //range+alloc + { + auto fset = set(int_set.begin(), int_set.end(), alloc_int_t()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = multiset(int_mset.begin(), int_mset.end(), alloc_int_t()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + + //ordered_unique_range / ordered_range + + //range + { + auto fset = set(ordered_unique_range, int_set.begin(), int_set.end()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = multiset(ordered_range, int_mset.begin(), int_mset.end()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + //range+comp + { + auto fset = set(ordered_unique_range, int_set.begin(), int_set.end(), comp_int_t()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = multiset(ordered_range, int_mset.begin(), int_mset.end(), comp_int_t()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + //range+comp+alloc + { + auto fset = set(ordered_unique_range, int_set.begin(), int_set.end(), comp_int_t(), alloc_int_t()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = multiset(ordered_range, int_mset.begin(), int_mset.end(), comp_int_t(), alloc_int_t()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + //range+alloc + { + auto fset = set(ordered_unique_range, int_set.begin(), int_set.end(), alloc_int_t()); + if (!CheckEqualContainers(int_set, fset)) + return false; + auto fmset = multiset(ordered_range, int_mset.begin(), int_mset.end(), alloc_int_t()); + if (!CheckEqualContainers(int_mset, fmset)) + return false; + } + } +#endif + return true; +} + }}} //boost::container::test template @@ -360,6 +458,13 @@ int main () test_merge_from_different_comparison(); + //////////////////////////////////// + // Constructor Template Auto Deduction test + //////////////////////////////////// + if (!test::constructor_template_auto_deduction_test()) { + return 1; + } + if(!test_heterogeneous_lookups()) return 1; @@ -500,7 +605,7 @@ int main () if(!node_type_test()) return 1; -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD //////////////////////////////////// // Constructor Template Auto Deduction //////////////////////////////////// diff --git a/test/slist_test.cpp b/test/slist_test.cpp index 543eba1..4e09837 100644 --- a/test/slist_test.cpp +++ b/test/slist_test.cpp @@ -217,7 +217,7 @@ int main () return 1; } } -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD //////////////////////////////////// // Constructor Template Auto Deduction Tests //////////////////////////////////// diff --git a/test/stable_vector_test.cpp b/test/stable_vector_test.cpp index 7fb1014..fd76330 100644 --- a/test/stable_vector_test.cpp +++ b/test/stable_vector_test.cpp @@ -177,7 +177,7 @@ int main() } } -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD //////////////////////////////////// // Constructor Template Auto Deduction testing //////////////////////////////////// diff --git a/test/string_test.cpp b/test/string_test.cpp index 4c15fe6..2dfb2a4 100644 --- a/test/string_test.cpp +++ b/test/string_test.cpp @@ -456,7 +456,7 @@ int string_test() return 1; } -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD //Chect Constructor Template Auto Deduction { auto gold = StdString(string_literals::String()); diff --git a/test/vector_test.cpp b/test/vector_test.cpp index 903d3ea..84a7569 100644 --- a/test/vector_test.cpp +++ b/test/vector_test.cpp @@ -61,15 +61,15 @@ struct X; template struct XRef { - explicit XRef(T* ptr) noexcept : ptr(ptr) {} - operator T*() const noexcept { return ptr; } + explicit XRef(T* ptr) : ptr(ptr) {} + operator T*() const { return ptr; } T* ptr; }; struct X { - XRef operator&() const noexcept { return XRef(this); } - XRef operator&() noexcept { return XRef(this); } + XRef operator&() const { return XRef(this); } + XRef operator&() { return XRef(this); } }; @@ -260,7 +260,7 @@ int main() } } -#if __cplusplus >= 201703L +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD //////////////////////////////////// // Constructor Template Auto Deduction testing ////////////////////////////////////