mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-30 11:27:15 +02:00
Merge pull request #161 from cmazakas/fix/ctad
Complete deduction tests, implement guides for all containers
This commit is contained in:
@ -72,6 +72,8 @@ namespace unordered{
|
||||
namespace detail{
|
||||
namespace foa{
|
||||
|
||||
static const std::size_t default_bucket_count = 0;
|
||||
|
||||
/* foa::table is an open-addressing hash table serving as the foundational core
|
||||
* of boost::unordered_flat_[map|set]. Its main internal design aspects are:
|
||||
*
|
||||
|
@ -182,18 +182,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
|
||||
#if !defined(BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES)
|
||||
#if BOOST_COMP_CLANG && __cplusplus >= 201703
|
||||
#define BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES)
|
||||
#define BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES 0
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
namespace detail {
|
||||
|
@ -14,6 +14,25 @@
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/make_void.hpp>
|
||||
#include <boost/type_traits/type_identity.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)
|
||||
#include <boost/type_traits/enable_if.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#endif
|
||||
|
||||
// BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
|
||||
#if !defined(BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES)
|
||||
#if !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)
|
||||
#define BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES)
|
||||
#define BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES 0
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
@ -52,6 +71,37 @@ namespace boost {
|
||||
!boost::is_convertible<Key, iterator>::value &&
|
||||
!boost::is_convertible<Key, const_iterator>::value;
|
||||
};
|
||||
|
||||
#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
// https://eel.is/c++draft/container.requirements#container.alloc.reqmts-34
|
||||
// https://eel.is/c++draft/container.requirements#unord.req.general-243
|
||||
|
||||
template <class InputIterator>
|
||||
constexpr bool const is_input_iterator_v =
|
||||
!boost::is_integral<InputIterator>::value;
|
||||
|
||||
template <class A, class = void> struct is_allocator
|
||||
{
|
||||
constexpr static bool const value = false;
|
||||
};
|
||||
|
||||
template <class A>
|
||||
struct is_allocator<A,
|
||||
boost::void_t<typename A::value_type,
|
||||
decltype(std::declval<A&>().allocate(std::size_t{}))> >
|
||||
{
|
||||
constexpr static bool const value = true;
|
||||
};
|
||||
|
||||
template <class A>
|
||||
constexpr bool const is_allocator_v = is_allocator<A>::value;
|
||||
|
||||
template <class H>
|
||||
constexpr bool const is_hash_v =
|
||||
!boost::is_integral<H>::value && !is_allocator_v<H>;
|
||||
|
||||
template <class P> constexpr bool const is_pred_v = !is_allocator_v<P>;
|
||||
#endif
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
@ -76,9 +76,9 @@ namespace boost {
|
||||
using init_type = typename map_types::init_type;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using hasher = Hash;
|
||||
using key_equal = KeyEqual;
|
||||
using allocator_type = Allocator;
|
||||
using hasher = typename boost::type_identity<Hash>::type;
|
||||
using key_equal = typename boost::type_identity<KeyEqual>::type;
|
||||
using allocator_type = typename boost::type_identity<Allocator>::type;
|
||||
using reference = value_type&;
|
||||
using const_reference = value_type const&;
|
||||
using pointer = typename boost::allocator_pointer<allocator_type>::type;
|
||||
@ -628,6 +628,104 @@ namespace boost {
|
||||
#pragma warning(pop) /* C4714 */
|
||||
#endif
|
||||
|
||||
#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
using iter_key_t =
|
||||
typename std::iterator_traits<T>::value_type::first_type;
|
||||
template <typename T>
|
||||
using iter_val_t =
|
||||
typename std::iterator_traits<T>::value_type::second_type;
|
||||
template <typename T>
|
||||
using iter_to_alloc_t =
|
||||
typename std::pair<iter_key_t<T> const, iter_val_t<T> >;
|
||||
} // namespace detail
|
||||
|
||||
template <class InputIterator,
|
||||
class Hash =
|
||||
boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
class Pred =
|
||||
std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
class Allocator = std::allocator<
|
||||
boost::unordered::detail::iter_to_alloc_t<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_map(InputIterator, InputIterator,
|
||||
std::size_t = boost::unordered::detail::foa::default_bucket_count,
|
||||
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
|
||||
-> unordered_flat_map<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
boost::unordered::detail::iter_val_t<InputIterator>, Hash, Pred,
|
||||
Allocator>;
|
||||
|
||||
template <class Key, class T,
|
||||
class Hash = boost::hash<boost::remove_const_t<Key> >,
|
||||
class Pred = std::equal_to<boost::remove_const_t<Key> >,
|
||||
class Allocator = std::allocator<std::pair<const Key, T> >,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_map(std::initializer_list<std::pair<Key, T> >,
|
||||
std::size_t = boost::unordered::detail::foa::default_bucket_count,
|
||||
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
|
||||
-> unordered_flat_map<boost::remove_const_t<Key>, T, Hash, Pred,
|
||||
Allocator>;
|
||||
|
||||
template <class InputIterator, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_map(InputIterator, InputIterator, std::size_t, Allocator)
|
||||
-> unordered_flat_map<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
boost::unordered::detail::iter_val_t<InputIterator>,
|
||||
boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
Allocator>;
|
||||
|
||||
template <class InputIterator, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_map(InputIterator, InputIterator, Allocator)
|
||||
-> unordered_flat_map<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
boost::unordered::detail::iter_val_t<InputIterator>,
|
||||
boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
Allocator>;
|
||||
|
||||
template <class InputIterator, class Hash, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_map(
|
||||
InputIterator, InputIterator, std::size_t, Hash, Allocator)
|
||||
-> unordered_flat_map<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
boost::unordered::detail::iter_val_t<InputIterator>, Hash,
|
||||
std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
Allocator>;
|
||||
|
||||
template <class Key, class T, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
|
||||
Allocator) -> unordered_flat_map<boost::remove_const_t<Key>, T,
|
||||
boost::hash<boost::remove_const_t<Key> >,
|
||||
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
|
||||
template <class Key, class T, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_map(std::initializer_list<std::pair<Key, T> >, Allocator)
|
||||
-> unordered_flat_map<boost::remove_const_t<Key>, T,
|
||||
boost::hash<boost::remove_const_t<Key> >,
|
||||
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
|
||||
template <class Key, class T, class Hash, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
|
||||
Hash, Allocator) -> unordered_flat_map<boost::remove_const_t<Key>, T,
|
||||
Hash, std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
#endif
|
||||
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
||||
|
@ -503,6 +503,68 @@ namespace boost {
|
||||
#pragma warning(pop) /* C4714 */
|
||||
#endif
|
||||
|
||||
#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
template <class InputIterator,
|
||||
class Hash =
|
||||
boost::hash<typename std::iterator_traits<InputIterator>::value_type>,
|
||||
class Pred =
|
||||
std::equal_to<typename std::iterator_traits<InputIterator>::value_type>,
|
||||
class Allocator = std::allocator<
|
||||
typename std::iterator_traits<InputIterator>::value_type>,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_set(InputIterator, InputIterator,
|
||||
std::size_t = boost::unordered::detail::foa::default_bucket_count,
|
||||
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
|
||||
-> unordered_flat_set<
|
||||
typename std::iterator_traits<InputIterator>::value_type, Hash, Pred,
|
||||
Allocator>;
|
||||
|
||||
template <class T, class Hash = boost::hash<T>,
|
||||
class Pred = std::equal_to<T>, class Allocator = std::allocator<T>,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_set(std::initializer_list<T>,
|
||||
std::size_t = boost::unordered::detail::foa::default_bucket_count,
|
||||
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
|
||||
-> unordered_flat_set<T, Hash, Pred, Allocator>;
|
||||
|
||||
template <class InputIterator, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_set(InputIterator, InputIterator, std::size_t, Allocator)
|
||||
-> unordered_flat_set<
|
||||
typename std::iterator_traits<InputIterator>::value_type,
|
||||
boost::hash<typename std::iterator_traits<InputIterator>::value_type>,
|
||||
std::equal_to<typename std::iterator_traits<InputIterator>::value_type>,
|
||||
Allocator>;
|
||||
|
||||
template <class InputIterator, class Hash, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_set(
|
||||
InputIterator, InputIterator, std::size_t, Hash, Allocator)
|
||||
-> unordered_flat_set<
|
||||
typename std::iterator_traits<InputIterator>::value_type, Hash,
|
||||
std::equal_to<typename std::iterator_traits<InputIterator>::value_type>,
|
||||
Allocator>;
|
||||
|
||||
template <class T, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_set(std::initializer_list<T>, std::size_t, Allocator)
|
||||
-> unordered_flat_set<T, boost::hash<T>, std::equal_to<T>, Allocator>;
|
||||
|
||||
template <class T, class Hash, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_set(std::initializer_list<T>, std::size_t, Hash, Allocator)
|
||||
-> unordered_flat_set<T, Hash, std::equal_to<T>, Allocator>;
|
||||
#endif
|
||||
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/type_traits/is_constructible.hpp>
|
||||
#include <boost/unordered/detail/map.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
#include <initializer_list>
|
||||
@ -50,9 +51,9 @@ namespace boost {
|
||||
typedef K key_type;
|
||||
typedef T mapped_type;
|
||||
typedef std::pair<const K, T> value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef A allocator_type;
|
||||
typedef typename boost::type_identity<H>::type hasher;
|
||||
typedef typename boost::type_identity<P>::type key_equal;
|
||||
typedef typename boost::type_identity<A>::type allocator_type;
|
||||
|
||||
private:
|
||||
typedef boost::unordered::detail::map<A, K, T, H, P> types;
|
||||
@ -931,7 +932,7 @@ namespace boost {
|
||||
template <typename T>
|
||||
using iter_to_alloc_t =
|
||||
typename std::pair<iter_key_t<T> const, iter_val_t<T> >;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <class InputIterator,
|
||||
class Hash =
|
||||
@ -939,58 +940,80 @@ namespace boost {
|
||||
class Pred =
|
||||
std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
class Allocator = std::allocator<
|
||||
boost::unordered::detail::iter_to_alloc_t<InputIterator> > >
|
||||
boost::unordered::detail::iter_to_alloc_t<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_map(InputIterator, InputIterator,
|
||||
std::size_t = boost::unordered::detail::default_bucket_count,
|
||||
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
|
||||
->unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
-> unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
boost::unordered::detail::iter_val_t<InputIterator>, Hash, Pred,
|
||||
Allocator>;
|
||||
|
||||
template <class Key, class T, class Hash = boost::hash<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Allocator = std::allocator<std::pair<const Key, T> > >
|
||||
unordered_map(std::initializer_list<std::pair<const Key, T> >,
|
||||
template <class Key, class T,
|
||||
class Hash = boost::hash<boost::remove_const_t<Key> >,
|
||||
class Pred = std::equal_to<boost::remove_const_t<Key> >,
|
||||
class Allocator = std::allocator<std::pair<const Key, T> >,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_map(std::initializer_list<std::pair<Key, T> >,
|
||||
std::size_t = boost::unordered::detail::default_bucket_count,
|
||||
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
|
||||
->unordered_map<Key, T, Hash, Pred, Allocator>;
|
||||
-> unordered_map<boost::remove_const_t<Key>, T, Hash, Pred, Allocator>;
|
||||
|
||||
template <class InputIterator, class Allocator>
|
||||
template <class InputIterator, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_map(InputIterator, InputIterator, std::size_t, Allocator)
|
||||
->unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
-> unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
boost::unordered::detail::iter_val_t<InputIterator>,
|
||||
boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
Allocator>;
|
||||
|
||||
template <class InputIterator, class Allocator>
|
||||
template <class InputIterator, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_map(InputIterator, InputIterator, Allocator)
|
||||
->unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
-> unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
boost::unordered::detail::iter_val_t<InputIterator>,
|
||||
boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
Allocator>;
|
||||
|
||||
template <class InputIterator, class Hash, class Allocator>
|
||||
template <class InputIterator, class Hash, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_map(InputIterator, InputIterator, std::size_t, Hash, Allocator)
|
||||
->unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
-> unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
boost::unordered::detail::iter_val_t<InputIterator>, Hash,
|
||||
std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
Allocator>;
|
||||
|
||||
template <class Key, class T, typename Allocator>
|
||||
unordered_map(
|
||||
std::initializer_list<std::pair<const Key, T> >, std::size_t, Allocator)
|
||||
->unordered_map<Key, T, boost::hash<Key>, std::equal_to<Key>, Allocator>;
|
||||
template <class Key, class T, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
|
||||
Allocator) -> unordered_map<boost::remove_const_t<Key>, T,
|
||||
boost::hash<boost::remove_const_t<Key> >,
|
||||
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
|
||||
template <class Key, class T, typename Allocator>
|
||||
unordered_map(std::initializer_list<std::pair<const Key, T> >, Allocator)
|
||||
->unordered_map<Key, T, boost::hash<Key>, std::equal_to<Key>, Allocator>;
|
||||
template <class Key, class T, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_map(std::initializer_list<std::pair<Key, T> >, Allocator)
|
||||
-> unordered_map<boost::remove_const_t<Key>, T,
|
||||
boost::hash<boost::remove_const_t<Key> >,
|
||||
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
|
||||
template <class Key, class T, class Hash, class Allocator>
|
||||
unordered_map(std::initializer_list<std::pair<const Key, T> >, std::size_t,
|
||||
Hash, Allocator)
|
||||
->unordered_map<Key, T, Hash, std::equal_to<Key>, Allocator>;
|
||||
template <class Key, class T, class Hash, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_map(std::initializer_list<std::pair<Key, T> >, std::size_t, Hash,
|
||||
Allocator) -> unordered_map<boost::remove_const_t<Key>, T, Hash,
|
||||
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
|
||||
#endif
|
||||
|
||||
@ -1007,9 +1030,9 @@ namespace boost {
|
||||
typedef K key_type;
|
||||
typedef T mapped_type;
|
||||
typedef std::pair<const K, T> value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef A allocator_type;
|
||||
typedef typename boost::type_identity<H>::type hasher;
|
||||
typedef typename boost::type_identity<P>::type key_equal;
|
||||
typedef typename boost::type_identity<A>::type allocator_type;
|
||||
|
||||
private:
|
||||
typedef boost::unordered::detail::map<A, K, T, H, P> types;
|
||||
@ -1612,62 +1635,82 @@ namespace boost {
|
||||
class Pred =
|
||||
std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
class Allocator = std::allocator<
|
||||
boost::unordered::detail::iter_to_alloc_t<InputIterator> > >
|
||||
boost::unordered::detail::iter_to_alloc_t<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_multimap(InputIterator, InputIterator,
|
||||
std::size_t = boost::unordered::detail::default_bucket_count,
|
||||
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
|
||||
->unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
-> unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
boost::unordered::detail::iter_val_t<InputIterator>, Hash, Pred,
|
||||
Allocator>;
|
||||
|
||||
template <class Key, class T, class Hash = boost::hash<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Allocator = std::allocator<std::pair<const Key, T> > >
|
||||
unordered_multimap(std::initializer_list<std::pair<const Key, T> >,
|
||||
template <class Key, class T,
|
||||
class Hash = boost::hash<boost::remove_const_t<Key> >,
|
||||
class Pred = std::equal_to<boost::remove_const_t<Key> >,
|
||||
class Allocator = std::allocator<std::pair<const Key, T> >,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_multimap(std::initializer_list<std::pair<Key, T> >,
|
||||
std::size_t = boost::unordered::detail::default_bucket_count,
|
||||
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
|
||||
->unordered_multimap<Key, T, Hash, Pred, Allocator>;
|
||||
-> unordered_multimap<boost::remove_const_t<Key>, T, Hash, Pred,
|
||||
Allocator>;
|
||||
|
||||
template <class InputIterator, class Allocator>
|
||||
template <class InputIterator, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_multimap(InputIterator, InputIterator, std::size_t, Allocator)
|
||||
->unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
-> unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
boost::unordered::detail::iter_val_t<InputIterator>,
|
||||
boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
Allocator>;
|
||||
|
||||
template <class InputIterator, class Allocator>
|
||||
template <class InputIterator, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_multimap(InputIterator, InputIterator, Allocator)
|
||||
->unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
-> unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
boost::unordered::detail::iter_val_t<InputIterator>,
|
||||
boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
Allocator>;
|
||||
|
||||
template <class InputIterator, class Hash, class Allocator>
|
||||
template <class InputIterator, class Hash, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_multimap(
|
||||
InputIterator, InputIterator, std::size_t, Hash, Allocator)
|
||||
->unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
-> unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
|
||||
boost::unordered::detail::iter_val_t<InputIterator>, Hash,
|
||||
std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
|
||||
Allocator>;
|
||||
|
||||
template <class Key, class T, typename Allocator>
|
||||
unordered_multimap(
|
||||
std::initializer_list<std::pair<const Key, T> >, std::size_t, Allocator)
|
||||
->unordered_multimap<Key, T, boost::hash<Key>, std::equal_to<Key>,
|
||||
Allocator>;
|
||||
template <class Key, class T, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_multimap(std::initializer_list<std::pair<Key, T> >, std::size_t,
|
||||
Allocator) -> unordered_multimap<boost::remove_const_t<Key>, T,
|
||||
boost::hash<boost::remove_const_t<Key> >,
|
||||
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
|
||||
template <class Key, class T, typename Allocator>
|
||||
unordered_multimap(
|
||||
std::initializer_list<std::pair<const Key, T> >, Allocator)
|
||||
->unordered_multimap<Key, T, boost::hash<Key>, std::equal_to<Key>,
|
||||
Allocator>;
|
||||
template <class Key, class T, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_multimap(std::initializer_list<std::pair<Key, T> >, Allocator)
|
||||
-> unordered_multimap<boost::remove_const_t<Key>, T,
|
||||
boost::hash<boost::remove_const_t<Key> >,
|
||||
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
|
||||
template <class Key, class T, class Hash, class Allocator>
|
||||
unordered_multimap(std::initializer_list<std::pair<const Key, T> >,
|
||||
std::size_t, Hash, Allocator)
|
||||
->unordered_multimap<Key, T, Hash, std::equal_to<Key>, Allocator>;
|
||||
template <class Key, class T, class Hash, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_multimap(std::initializer_list<std::pair<Key, T> >, std::size_t,
|
||||
Hash, Allocator) -> unordered_multimap<boost::remove_const_t<Key>, T,
|
||||
Hash, std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/unordered/detail/set.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
#include <initializer_list>
|
||||
@ -621,41 +622,56 @@ namespace boost {
|
||||
class Pred =
|
||||
std::equal_to<typename std::iterator_traits<InputIterator>::value_type>,
|
||||
class Allocator = std::allocator<
|
||||
typename std::iterator_traits<InputIterator>::value_type> >
|
||||
typename std::iterator_traits<InputIterator>::value_type>,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_set(InputIterator, InputIterator,
|
||||
std::size_t = boost::unordered::detail::default_bucket_count,
|
||||
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
|
||||
->unordered_set<typename std::iterator_traits<InputIterator>::value_type,
|
||||
-> unordered_set<typename std::iterator_traits<InputIterator>::value_type,
|
||||
Hash, Pred, Allocator>;
|
||||
|
||||
template <class T, class Hash = boost::hash<T>,
|
||||
class Pred = std::equal_to<T>, class Allocator = std::allocator<T> >
|
||||
class Pred = std::equal_to<T>, class Allocator = std::allocator<T>,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_set(std::initializer_list<T>,
|
||||
std::size_t = boost::unordered::detail::default_bucket_count,
|
||||
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
|
||||
->unordered_set<T, Hash, Pred, Allocator>;
|
||||
-> unordered_set<T, Hash, Pred, Allocator>;
|
||||
|
||||
template <class InputIterator, class Allocator>
|
||||
template <class InputIterator, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_set(InputIterator, InputIterator, std::size_t, Allocator)
|
||||
->unordered_set<typename std::iterator_traits<InputIterator>::value_type,
|
||||
-> unordered_set<typename std::iterator_traits<InputIterator>::value_type,
|
||||
boost::hash<typename std::iterator_traits<InputIterator>::value_type>,
|
||||
std::equal_to<typename std::iterator_traits<InputIterator>::value_type>,
|
||||
Allocator>;
|
||||
|
||||
template <class InputIterator, class Hash, class Allocator>
|
||||
template <class InputIterator, class Hash, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_set(InputIterator, InputIterator, std::size_t, Hash, Allocator)
|
||||
->unordered_set<typename std::iterator_traits<InputIterator>::value_type,
|
||||
-> unordered_set<typename std::iterator_traits<InputIterator>::value_type,
|
||||
Hash,
|
||||
std::equal_to<typename std::iterator_traits<InputIterator>::value_type>,
|
||||
Allocator>;
|
||||
|
||||
template <class T, class Allocator>
|
||||
template <class T, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_set(std::initializer_list<T>, std::size_t, Allocator)
|
||||
->unordered_set<T, boost::hash<T>, std::equal_to<T>, Allocator>;
|
||||
-> unordered_set<T, boost::hash<T>, std::equal_to<T>, Allocator>;
|
||||
|
||||
template <class T, class Hash, class Allocator>
|
||||
template <class T, class Hash, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_set(std::initializer_list<T>, std::size_t, Hash, Allocator)
|
||||
->unordered_set<T, Hash, std::equal_to<T>, Allocator>;
|
||||
-> unordered_set<T, Hash, std::equal_to<T>, Allocator>;
|
||||
|
||||
#endif
|
||||
|
||||
@ -1233,44 +1249,59 @@ namespace boost {
|
||||
class Pred =
|
||||
std::equal_to<typename std::iterator_traits<InputIterator>::value_type>,
|
||||
class Allocator = std::allocator<
|
||||
typename std::iterator_traits<InputIterator>::value_type> >
|
||||
typename std::iterator_traits<InputIterator>::value_type>,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_multiset(InputIterator, InputIterator,
|
||||
std::size_t = boost::unordered::detail::default_bucket_count,
|
||||
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
|
||||
->unordered_multiset<
|
||||
-> unordered_multiset<
|
||||
typename std::iterator_traits<InputIterator>::value_type, Hash, Pred,
|
||||
Allocator>;
|
||||
|
||||
template <class T, class Hash = boost::hash<T>,
|
||||
class Pred = std::equal_to<T>, class Allocator = std::allocator<T> >
|
||||
class Pred = std::equal_to<T>, class Allocator = std::allocator<T>,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_multiset(std::initializer_list<T>,
|
||||
std::size_t = boost::unordered::detail::default_bucket_count,
|
||||
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
|
||||
->unordered_multiset<T, Hash, Pred, Allocator>;
|
||||
-> unordered_multiset<T, Hash, Pred, Allocator>;
|
||||
|
||||
template <class InputIterator, class Allocator>
|
||||
template <class InputIterator, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_multiset(InputIterator, InputIterator, std::size_t, Allocator)
|
||||
->unordered_multiset<
|
||||
-> unordered_multiset<
|
||||
typename std::iterator_traits<InputIterator>::value_type,
|
||||
boost::hash<typename std::iterator_traits<InputIterator>::value_type>,
|
||||
std::equal_to<typename std::iterator_traits<InputIterator>::value_type>,
|
||||
Allocator>;
|
||||
|
||||
template <class InputIterator, class Hash, class Allocator>
|
||||
template <class InputIterator, class Hash, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_multiset(
|
||||
InputIterator, InputIterator, std::size_t, Hash, Allocator)
|
||||
->unordered_multiset<
|
||||
-> unordered_multiset<
|
||||
typename std::iterator_traits<InputIterator>::value_type, Hash,
|
||||
std::equal_to<typename std::iterator_traits<InputIterator>::value_type>,
|
||||
Allocator>;
|
||||
|
||||
template <class T, class Allocator>
|
||||
template <class T, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_multiset(std::initializer_list<T>, std::size_t, Allocator)
|
||||
->unordered_multiset<T, boost::hash<T>, std::equal_to<T>, Allocator>;
|
||||
-> unordered_multiset<T, boost::hash<T>, std::equal_to<T>, Allocator>;
|
||||
|
||||
template <class T, class Hash, class Allocator>
|
||||
template <class T, class Hash, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_multiset(std::initializer_list<T>, std::size_t, Hash, Allocator)
|
||||
->unordered_multiset<T, Hash, std::equal_to<T>, Allocator>;
|
||||
-> unordered_multiset<T, Hash, std::equal_to<T>, Allocator>;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -3,11 +3,17 @@
|
||||
// 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)
|
||||
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
|
||||
#include <boost/unordered/unordered_flat_map.hpp>
|
||||
#include <boost/unordered/unordered_flat_set.hpp>
|
||||
|
||||
struct hash_equals
|
||||
{
|
||||
template <typename T> bool operator()(T const& x) const
|
||||
@ -33,22 +39,15 @@ template <typename T> struct test_allocator
|
||||
bool operator==(test_allocator const&) const { return true; }
|
||||
bool operator!=(test_allocator const&) const { return false; }
|
||||
};
|
||||
#endif
|
||||
|
||||
int main()
|
||||
template <template <class...> class UnorderedMap> void map_tests()
|
||||
{
|
||||
std::cout << "BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES: "
|
||||
<< BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES << std::endl;
|
||||
|
||||
#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
std::vector<std::pair<int, int> > x;
|
||||
x.push_back(std::make_pair(1, 3));
|
||||
x.push_back(std::make_pair(5, 10));
|
||||
test_allocator<std::pair<const int, int> > pair_allocator;
|
||||
hash_equals f;
|
||||
|
||||
// unordered_map
|
||||
|
||||
/*
|
||||
template<class InputIterator,
|
||||
class Hash = hash<iter_key_t<InputIterator>>,
|
||||
@ -63,32 +62,28 @@ int main()
|
||||
*/
|
||||
|
||||
{
|
||||
boost::unordered_map m(x.begin(), x.end());
|
||||
static_assert(
|
||||
std::is_same<decltype(m), boost::unordered_map<int, int> >::value);
|
||||
}
|
||||
|
||||
/* Ambiguous:
|
||||
{
|
||||
boost::unordered_map m(x.begin(), x.end(), 0, std::hash<int>());
|
||||
static_assert(std::is_same<decltype(m),boost::unordered_map<int, int,
|
||||
std::hash<int>>>::value);
|
||||
UnorderedMap m(x.begin(), x.end());
|
||||
BOOST_TEST_TRAIT_SAME(decltype(m), UnorderedMap<int, int>);
|
||||
}
|
||||
|
||||
{
|
||||
boost::unordered_map m(x.begin(), x.end(), 0, std::hash<int>(),
|
||||
std::equal_to<int>());
|
||||
static_assert(std::is_same<decltype(m),boost::unordered_map<int, int,
|
||||
std::hash<int>, std::equal_to<int>>>::value);
|
||||
UnorderedMap m(x.begin(), x.end(), 0, std::hash<int>());
|
||||
BOOST_TEST_TRAIT_SAME(decltype(m), UnorderedMap<int, int, std::hash<int> >);
|
||||
}
|
||||
*/
|
||||
|
||||
{
|
||||
boost::unordered_map m(x.begin(), x.end(), 0, std::hash<int>(),
|
||||
UnorderedMap m(
|
||||
x.begin(), x.end(), 0, std::hash<int>(), std::equal_to<int>());
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(m), UnorderedMap<int, int, std::hash<int>, std::equal_to<int> >);
|
||||
}
|
||||
|
||||
{
|
||||
UnorderedMap m(x.begin(), x.end(), 0, std::hash<int>(),
|
||||
std::equal_to<int>(), pair_allocator);
|
||||
static_assert(std::is_same<decltype(m),
|
||||
boost::unordered_map<int, int, std::hash<int>, std::equal_to<int>,
|
||||
test_allocator<std::pair<const int, int> > > >::value);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(m), UnorderedMap<int, int, std::hash<int>, std::equal_to<int>,
|
||||
test_allocator<std::pair<const int, int> > >);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -102,33 +97,51 @@ int main()
|
||||
*/
|
||||
|
||||
{
|
||||
boost::unordered_map m({std::pair<int const, int>(1, 2)});
|
||||
static_assert(
|
||||
std::is_same<decltype(m), boost::unordered_map<int, int> >::value);
|
||||
}
|
||||
|
||||
/* Ambiguous
|
||||
{
|
||||
boost::unordered_map m({std::pair<int const, int>(1,2)}, 0,
|
||||
std::hash<int>());
|
||||
static_assert(std::is_same<decltype(m),boost::unordered_map<int, int,
|
||||
std::hash<int>>>::value);
|
||||
UnorderedMap m({std::pair<int const, int>(1, 2)});
|
||||
BOOST_TEST_TRAIT_SAME(decltype(m), UnorderedMap<int, int>);
|
||||
}
|
||||
|
||||
{
|
||||
boost::unordered_map m({std::pair<int const, int>(1,2)}, 0,
|
||||
std::hash<int>(), std::equal_to<int>());
|
||||
static_assert(std::is_same<decltype(m),boost::unordered_map<int, int,
|
||||
std::hash<int>, std::equal_to<int>>>::value);
|
||||
UnorderedMap m({std::pair<int, int>(1, 2)});
|
||||
BOOST_TEST_TRAIT_SAME(decltype(m), UnorderedMap<int, int>);
|
||||
}
|
||||
*/
|
||||
|
||||
{
|
||||
boost::unordered_map m(
|
||||
{std::pair<int const, int>(1, 2)}, 0, f, f, pair_allocator);
|
||||
static_assert(std::is_same<decltype(m),
|
||||
boost::unordered_map<int, int, hash_equals, hash_equals,
|
||||
test_allocator<std::pair<const int, int> > > >::value);
|
||||
UnorderedMap m({std::pair<int const, int>(1, 2)}, 0, std::hash<int>());
|
||||
BOOST_TEST_TRAIT_SAME(decltype(m), UnorderedMap<int, int, std::hash<int> >);
|
||||
}
|
||||
|
||||
{
|
||||
UnorderedMap m({std::pair<int, int>(1, 2)}, 0, std::hash<int>());
|
||||
BOOST_TEST_TRAIT_SAME(decltype(m), UnorderedMap<int, int, std::hash<int> >);
|
||||
}
|
||||
|
||||
{
|
||||
UnorderedMap m({std::pair<int const, int>(1, 2)}, 0, std::hash<int>(),
|
||||
std::equal_to<int>());
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(m), UnorderedMap<int, int, std::hash<int>, std::equal_to<int> >);
|
||||
}
|
||||
|
||||
{
|
||||
UnorderedMap m(
|
||||
{std::pair<int, int>(1, 2)}, 0, std::hash<int>(), std::equal_to<int>());
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(m), UnorderedMap<int, int, std::hash<int>, std::equal_to<int> >);
|
||||
}
|
||||
|
||||
{
|
||||
UnorderedMap m({std::pair<int const, int>(1, 2)}, 0, f, f, pair_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(m), UnorderedMap<int, int, hash_equals, hash_equals,
|
||||
test_allocator<std::pair<const int, int> > >);
|
||||
}
|
||||
|
||||
{
|
||||
UnorderedMap m({std::pair<int, int>(1, 2)}, 0, f, f, pair_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(m), UnorderedMap<int, int, hash_equals, hash_equals,
|
||||
test_allocator<std::pair<const int, int> > >);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -141,14 +154,12 @@ int main()
|
||||
Allocator>;
|
||||
*/
|
||||
|
||||
/* Ambiguous
|
||||
{
|
||||
boost::unordered_map m(x.begin(), x.end(), 0u, pair_allocator);
|
||||
static_assert(std::is_same<decltype(m), boost::unordered_map<int, int,
|
||||
boost::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int,
|
||||
int>>>>::value);
|
||||
UnorderedMap m(x.begin(), x.end(), 0u, pair_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(m), UnorderedMap<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test_allocator<std::pair<const int, int> > >);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
template<class InputIterator, class Allocator>
|
||||
@ -159,14 +170,12 @@ int main()
|
||||
Allocator>;
|
||||
*/
|
||||
|
||||
/* No constructor:
|
||||
{
|
||||
boost::unordered_map m(x.begin(), x.end(), pair_allocator);
|
||||
static_assert(std::is_same<decltype(m), boost::unordered_map<int, int,
|
||||
boost::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int,
|
||||
int>>>>::value);
|
||||
UnorderedMap m(x.begin(), x.end(), pair_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(m), UnorderedMap<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test_allocator<std::pair<const int, int> > >);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
template<class InputIterator, class Hash, class Allocator>
|
||||
@ -177,14 +186,12 @@ int main()
|
||||
equal_to<iter_key_t<InputIterator>>, Allocator>;
|
||||
*/
|
||||
|
||||
/* Ambiguous
|
||||
{
|
||||
boost::unordered_map m(x.begin(), x.end(), 0u, f, pair_allocator);
|
||||
static_assert(std::is_same<decltype(m), boost::unordered_map<int, int,
|
||||
hash_equals, std::equal_to<int>, test_allocator<std::pair<const int,
|
||||
int>>>>::value);
|
||||
UnorderedMap m(x.begin(), x.end(), 0u, f, pair_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(m), UnorderedMap<int, int, hash_equals, std::equal_to<int>,
|
||||
test_allocator<std::pair<const int, int> > >);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
template<class Key, class T, typename Allocator>
|
||||
@ -194,14 +201,19 @@ int main()
|
||||
-> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>;
|
||||
*/
|
||||
|
||||
/* Ambiguous
|
||||
{
|
||||
boost::unordered_map m({std::pair<int const, int>(1,2)}, 0, pair_allocator);
|
||||
static_assert(std::is_same<decltype(m),boost::unordered_map<int, int,
|
||||
boost::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int,
|
||||
int>>>>::value);
|
||||
UnorderedMap m({std::pair<int const, int>(1, 2)}, 0, pair_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(m), UnorderedMap<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test_allocator<std::pair<const int, int> > >);
|
||||
}
|
||||
|
||||
{
|
||||
UnorderedMap m({std::pair<int, int>(1, 2)}, 0, pair_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(m), UnorderedMap<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test_allocator<std::pair<const int, int> > >);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
template<class Key, class T, typename Allocator>
|
||||
@ -210,10 +222,17 @@ int main()
|
||||
*/
|
||||
|
||||
{
|
||||
boost::unordered_map m({std::pair<int const, int>(1, 2)}, pair_allocator);
|
||||
static_assert(std::is_same<decltype(m),
|
||||
boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test_allocator<std::pair<const int, int> > > >::value);
|
||||
UnorderedMap m({std::pair<int const, int>(1, 2)}, pair_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(m), UnorderedMap<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test_allocator<std::pair<const int, int> > >);
|
||||
}
|
||||
|
||||
{
|
||||
UnorderedMap m({std::pair<int, int>(1, 2)}, pair_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(m), UnorderedMap<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test_allocator<std::pair<const int, int> > >);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -224,129 +243,170 @@ int main()
|
||||
-> unordered_map<Key, T, Hash, equal_to<Key>, Allocator>;
|
||||
*/
|
||||
|
||||
/* Ambiguous
|
||||
{
|
||||
boost::unordered_map m({std::pair<int const, int>(1,2)}, 0, f,
|
||||
pair_allocator);
|
||||
static_assert(std::is_same<decltype(m),boost::unordered_map<int, int,
|
||||
boost::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int,
|
||||
int>>>>::value);
|
||||
}
|
||||
*/
|
||||
|
||||
// unordered_multimap
|
||||
|
||||
{
|
||||
boost::unordered_multimap m(x.begin(), x.end());
|
||||
static_assert(
|
||||
std::is_same<decltype(m), boost::unordered_multimap<int, int> >::value);
|
||||
}
|
||||
|
||||
/* Ambiguous:
|
||||
{
|
||||
boost::unordered_multimap m(x.begin(), x.end(), 0, std::hash<int>());
|
||||
static_assert(std::is_same<decltype(m),boost::unordered_multimap<int, int,
|
||||
std::hash<int>>>::value);
|
||||
UnorderedMap m({std::pair<int const, int>(1, 2)}, 0, f, pair_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(m), UnorderedMap<int, int, hash_equals, std::equal_to<int>,
|
||||
test_allocator<std::pair<const int, int> > >);
|
||||
}
|
||||
|
||||
{
|
||||
boost::unordered_multimap m(x.begin(), x.end(), 0, std::hash<int>(),
|
||||
std::equal_to<int>());
|
||||
static_assert(std::is_same<decltype(m),boost::unordered_multimap<int, int,
|
||||
std::hash<int>, std::equal_to<int>>>::value);
|
||||
UnorderedMap m({std::pair<int, int>(1, 2)}, 0, f, pair_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(m), UnorderedMap<int, int, hash_equals, std::equal_to<int>,
|
||||
test_allocator<std::pair<const int, int> > >);
|
||||
}
|
||||
}
|
||||
|
||||
template <template <class...> class UnorderedSet> void set_tests()
|
||||
{
|
||||
std::vector<int> y;
|
||||
y.push_back(1);
|
||||
y.push_back(2);
|
||||
|
||||
hash_equals f;
|
||||
|
||||
test_allocator<int> int_allocator;
|
||||
|
||||
/* template<class InputIt,
|
||||
class Hash = std::hash<typename
|
||||
std::iterator_traits<InputIt>::value_type>, class Pred =
|
||||
std::equal_to<typename std::iterator_traits<InputIt>::value_type>, class
|
||||
Alloc = std::allocator<typename std::iterator_traits<InputIt>::value_type>>
|
||||
unordered_set(InputIt, InputIt,
|
||||
typename see below ::size_type = see below,
|
||||
Hash = Hash(), Pred = Pred(), Alloc = Alloc())
|
||||
-> unordered_set<typename std::iterator_traits<InputIt>::value_type, Hash,
|
||||
Pred, Alloc>; */
|
||||
|
||||
{
|
||||
UnorderedSet s(y.begin(), y.end());
|
||||
BOOST_TEST_TRAIT_SAME(decltype(s), UnorderedSet<int>);
|
||||
}
|
||||
|
||||
{
|
||||
UnorderedSet s(y.begin(), y.end(), 0, std::hash<int>());
|
||||
BOOST_TEST_TRAIT_SAME(decltype(s), UnorderedSet<int, std::hash<int> >);
|
||||
}
|
||||
|
||||
{
|
||||
UnorderedSet s(
|
||||
y.begin(), y.end(), 0, std::hash<int>(), std::equal_to<int>());
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(s), UnorderedSet<int, std::hash<int>, std::equal_to<int> >);
|
||||
}
|
||||
|
||||
{
|
||||
UnorderedSet s(y.begin(), y.end(), 0, std::hash<int>(),
|
||||
std::equal_to<int>(), int_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(s), UnorderedSet<int, std::hash<int>, std::equal_to<int>,
|
||||
test_allocator<int> >);
|
||||
}
|
||||
|
||||
/* template<class T,
|
||||
class Hash = std::hash<T>,
|
||||
class Pred = std::equal_to<T>,
|
||||
class Alloc = std::allocator<T>>
|
||||
unordered_set(std::initializer_list<T>,
|
||||
typename see below::size_type = see below,
|
||||
Hash = Hash(), Pred = Pred(), Alloc = Alloc())
|
||||
-> unordered_set<T, Hash, Pred, Alloc>; */
|
||||
|
||||
{
|
||||
UnorderedSet s({1, 2});
|
||||
BOOST_TEST_TRAIT_SAME(decltype(s), UnorderedSet<int>);
|
||||
}
|
||||
|
||||
{
|
||||
UnorderedSet s({1, 2}, 0, std::hash<int>());
|
||||
BOOST_TEST_TRAIT_SAME(decltype(s), UnorderedSet<int, std::hash<int> >);
|
||||
}
|
||||
|
||||
{
|
||||
UnorderedSet s({1, 2}, 0, std::hash<int>(), std::equal_to<int>());
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(s), UnorderedSet<int, std::hash<int>, std::equal_to<int> >);
|
||||
}
|
||||
|
||||
{
|
||||
UnorderedSet s(
|
||||
{1, 2}, 0, std::hash<int>(), std::equal_to<int>(), int_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(s), UnorderedSet<int, std::hash<int>, std::equal_to<int>,
|
||||
test_allocator<int> >);
|
||||
}
|
||||
|
||||
{
|
||||
UnorderedSet s({1, 2}, 0, f, f, int_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(decltype(s),
|
||||
UnorderedSet<int, hash_equals, hash_equals, test_allocator<int> >);
|
||||
}
|
||||
|
||||
/* template<class InputIt, class Alloc>
|
||||
unordered_set(InputIt, InputIt, typename see below::size_type, Alloc)
|
||||
-> unordered_set<typename std::iterator_traits<InputIt>::value_type,
|
||||
std::hash<typename std::iterator_traits<InputIt>::value_type>,
|
||||
std::equal_to<typename
|
||||
std::iterator_traits<InputIt>::value_type>, Alloc>; */
|
||||
|
||||
{
|
||||
UnorderedSet s(y.begin(), y.end(), 0u, int_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(s), UnorderedSet<int, boost::hash<int>, std::equal_to<int>,
|
||||
test_allocator<int> >);
|
||||
}
|
||||
|
||||
/* template<class InputIt, class Hash, class Alloc>
|
||||
unordered_set(InputIt, InputIt, typename see below::size_type, Hash, Alloc)
|
||||
-> unordered_set<typename std::iterator_traits<InputIt>::value_type, Hash,
|
||||
std::equal_to<typename
|
||||
std::iterator_traits<InputIt>::value_type>, Allocator>; */
|
||||
|
||||
{
|
||||
UnorderedSet s(y.begin(), y.end(), 0u, f, int_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(decltype(s),
|
||||
UnorderedSet<int, hash_equals, std::equal_to<int>, test_allocator<int> >);
|
||||
}
|
||||
|
||||
/* template<class T, class Allocator>
|
||||
unordered_set(std::initializer_list<T>, typename see below::size_type,
|
||||
Allocator)
|
||||
-> unordered_set<T, std::hash<T>, std::equal_to<T>, Alloc>; */
|
||||
|
||||
{
|
||||
UnorderedSet s({1, 2}, 0u, int_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(
|
||||
decltype(s), UnorderedSet<int, boost::hash<int>, std::equal_to<int>,
|
||||
test_allocator<int> >);
|
||||
}
|
||||
|
||||
/* template<class T, class Hash, class Alloc>
|
||||
unordered_set(std::initializer_list<T>, typename see below::size_type, Hash,
|
||||
Alloc)
|
||||
-> unordered_set<T, Hash, std::equal_to<T>, Alloc>; */
|
||||
{
|
||||
UnorderedSet s({1, 2}, 0u, f, int_allocator);
|
||||
BOOST_TEST_TRAIT_SAME(decltype(s),
|
||||
UnorderedSet<int, hash_equals, std::equal_to<int>, test_allocator<int> >);
|
||||
}
|
||||
*/
|
||||
|
||||
{
|
||||
boost::unordered_multimap m(x.begin(), x.end(), 0, std::hash<int>(),
|
||||
std::equal_to<int>(), pair_allocator);
|
||||
static_assert(std::is_same<decltype(m),
|
||||
boost::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>,
|
||||
test_allocator<std::pair<const int, int> > > >::value);
|
||||
}
|
||||
|
||||
{
|
||||
boost::unordered_multimap m({std::pair<int const, int>(1, 2)});
|
||||
static_assert(
|
||||
std::is_same<decltype(m), boost::unordered_multimap<int, int> >::value);
|
||||
}
|
||||
|
||||
/* Ambiguous
|
||||
{
|
||||
boost::unordered_multimap m({std::pair<int const, int>(1,2)}, 0,
|
||||
std::hash<int>());
|
||||
static_assert(std::is_same<decltype(m),boost::unordered_multimap<int, int,
|
||||
std::hash<int>>>::value);
|
||||
}
|
||||
|
||||
{
|
||||
boost::unordered_multimap m({std::pair<int const, int>(1,2)}, 0,
|
||||
std::hash<int>(), std::equal_to<int>());
|
||||
static_assert(std::is_same<decltype(m),boost::unordered_multimap<int, int,
|
||||
std::hash<int>, std::equal_to<int>>>::value);
|
||||
}
|
||||
*/
|
||||
|
||||
{
|
||||
boost::unordered_multimap m(
|
||||
{std::pair<int const, int>(1, 2)}, 0, f, f, pair_allocator);
|
||||
static_assert(std::is_same<decltype(m),
|
||||
boost::unordered_multimap<int, int, hash_equals, hash_equals,
|
||||
test_allocator<std::pair<const int, int> > > >::value);
|
||||
}
|
||||
|
||||
/* Ambiguous
|
||||
{
|
||||
boost::unordered_multimap m(x.begin(), x.end(), 0u, pair_allocator);
|
||||
static_assert(std::is_same<decltype(m), boost::unordered_multimap<int, int,
|
||||
boost::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int,
|
||||
int>>>>::value);
|
||||
}
|
||||
*/
|
||||
|
||||
/* No constructor:
|
||||
{
|
||||
boost::unordered_multimap m(x.begin(), x.end(), pair_allocator);
|
||||
static_assert(std::is_same<decltype(m), boost::unordered_multimap<int, int,
|
||||
boost::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int,
|
||||
int>>>>::value);
|
||||
}
|
||||
*/
|
||||
|
||||
/* Ambiguous
|
||||
{
|
||||
boost::unordered_multimap m(x.begin(), x.end(), 0u, f, pair_allocator);
|
||||
static_assert(std::is_same<decltype(m), boost::unordered_multimap<int, int,
|
||||
hash_equals, std::equal_to<int>, test_allocator<std::pair<const int,
|
||||
int>>>>::value);
|
||||
}
|
||||
|
||||
{
|
||||
boost::unordered_multimap m({std::pair<int const, int>(1,2)}, 0,
|
||||
pair_allocator);
|
||||
static_assert(std::is_same<decltype(m),boost::unordered_multimap<int, int,
|
||||
boost::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int,
|
||||
int>>>>::value);
|
||||
}
|
||||
*/
|
||||
|
||||
{
|
||||
boost::unordered_multimap m(
|
||||
{std::pair<int const, int>(1, 2)}, pair_allocator);
|
||||
static_assert(std::is_same<decltype(m),
|
||||
boost::unordered_multimap<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test_allocator<std::pair<const int, int> > > >::value);
|
||||
}
|
||||
|
||||
/* Ambiguous
|
||||
{
|
||||
boost::unordered_multimap m({std::pair<int const, int>(1,2)}, 0, f,
|
||||
pair_allocator);
|
||||
static_assert(std::is_same<decltype(m),boost::unordered_multimap<int, int,
|
||||
boost::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int,
|
||||
int>>>>::value);
|
||||
}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES: "
|
||||
<< BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES << std::endl;
|
||||
|
||||
#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
map_tests<boost::unordered_map>();
|
||||
map_tests<boost::unordered_multimap>();
|
||||
map_tests<boost::unordered_flat_map>();
|
||||
set_tests<boost::unordered_set>();
|
||||
set_tests<boost::unordered_multiset>();
|
||||
set_tests<boost::unordered_flat_set>();
|
||||
|
||||
return boost::report_errors();
|
||||
#endif
|
||||
}
|
||||
|
Reference in New Issue
Block a user