forked from boostorg/unordered
equality operators when not required, and some bookkeeping. ................ r42539 | danieljames | 2008-01-06 17:48:11 +0000 (Sun, 06 Jan 2008) | 2 lines Add the unordered library to the maintainers list. ................ r46579 | danieljames | 2008-06-21 16:32:11 +0100 (Sat, 21 Jun 2008) | 10 lines Define unordered containers' friend functions outside of the class. On some compilers, friend functions are being instantiated when the main class is explicitly instantiated. This is slightly problematic because the equality functions (which are an extension) put extra requirements on the types used. So I'm going to try defining the functions outside of the class, in the hope that they won't get instantiated. If someone wants non-member functions to be instantiated, I think it's reasonable to expect them to explicitly instantiate them, especially as compilers don't seem to be consistent about this. ................ r46587 | danieljames | 2008-06-21 20:58:39 +0100 (Sat, 21 Jun 2008) | 8 lines Get the test to pass when pair's default constructor creates two instances of the member classes. With some standard libraries I was getting two copies of the object after creating a default pair, probably because it was creating an instance for its default parameter. So only test after creating the pair object - since it isn't our concern how many instances that creates. ................ r46588 | danieljames | 2008-06-21 21:11:26 +0100 (Sat, 21 Jun 2008) | 1 line Markup an expected failure for unordered. ................ r46594 | danieljames | 2008-06-21 23:02:15 +0100 (Sat, 21 Jun 2008) | 19 lines Merge inspect fixes for the unordered library. Merged revisions 46470-46592 via svnmerge from https://svn.boost.org/svn/boost/branches/unordered/trunk ................ r46589 | danieljames | 2008-06-21 21:37:42 +0100 (Sat, 21 Jun 2008) | 2 lines Fix some inspect errors (tabs and missing copyright/license). ................ r46591 | danieljames | 2008-06-21 21:47:51 +0100 (Sat, 21 Jun 2008) | 1 line Move memory.hpp into the helpers subdirectory. ................ r46592 | danieljames | 2008-06-21 22:08:53 +0100 (Sat, 21 Jun 2008) | 1 line Prevent inspect errors for unnamed namespaces in some of the test header files. ................ ................ r46607 | danieljames | 2008-06-22 14:54:45 +0100 (Sun, 22 Jun 2008) | 9 lines Extract the hash and equality functions from hash_table_data_*. As these are extensions and add extra requirements to the container elements, they shouldn't be part of hash_table_data_* so that they won't get instantiated if an unordered container is explicitly instantiated. Merged revisions 46594-46604 via svnmerge from https://svn.boost.org/svn/boost/branches/unordered/trunk ................ r46608 | danieljames | 2008-06-22 16:00:02 +0100 (Sun, 22 Jun 2008) | 5 lines Remove the svnmerge integration information for the unordered branch. Now that the unordered library is moving towards release, the main development version is in trunk. New features will be developed on a new branch. ................ [SVN r46629]
790 lines
22 KiB
C++
790 lines
22 KiB
C++
|
|
// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
|
|
// Copyright (C) 2005-2008 Daniel James.
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
// See http://www.boost.org/libs/unordered for documentation
|
|
|
|
#ifndef BOOST_UNORDERED_SET_HPP_INCLUDED
|
|
#define BOOST_UNORDERED_SET_HPP_INCLUDED
|
|
|
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
|
# pragma once
|
|
#endif
|
|
|
|
#include <boost/config.hpp>
|
|
|
|
#include <functional>
|
|
#include <memory>
|
|
|
|
#include <boost/functional/hash.hpp>
|
|
#include <boost/unordered/detail/hash_table.hpp>
|
|
|
|
#if !defined(BOOST_HAS_RVALUE_REFS)
|
|
#include <boost/unordered/detail/move.hpp>
|
|
#endif
|
|
|
|
namespace boost
|
|
{
|
|
template <class Value,
|
|
class Hash = hash<Value>,
|
|
class Pred = std::equal_to<Value>,
|
|
class Alloc = std::allocator<Value> >
|
|
class unordered_set;
|
|
template <class T, class H, class P, class A>
|
|
bool operator==(unordered_set<T, H, P, A> const&,
|
|
unordered_set<T, H, P, A> const&);
|
|
template <class T, class H, class P, class A>
|
|
bool operator!=(unordered_set<T, H, P, A> const&,
|
|
unordered_set<T, H, P, A> const&);
|
|
template <class T, class H, class P, class A>
|
|
std::size_t hash_value(unordered_set<T, H, P, A> const& m);
|
|
template <class T, class H, class P, class A>
|
|
void swap(unordered_set<T, H, P, A> &m1,
|
|
unordered_set<T, H, P, A> &m2);
|
|
|
|
template <class Value,
|
|
class Hash = hash<Value>,
|
|
class Pred = std::equal_to<Value>,
|
|
class Alloc = std::allocator<Value> >
|
|
class unordered_multiset;
|
|
template <class T, class H, class P, class A>
|
|
bool operator==(unordered_multiset<T, H, P, A> const&,
|
|
unordered_multiset<T, H, P, A> const&);
|
|
template <class T, class H, class P, class A>
|
|
bool operator!=(unordered_multiset<T, H, P, A> const&,
|
|
unordered_multiset<T, H, P, A> const&);
|
|
template <class T, class H, class P, class A>
|
|
std::size_t hash_value(unordered_multiset<T, H, P, A> const& m);
|
|
template <class T, class H, class P, class A>
|
|
void swap(unordered_multiset<T, H, P, A> &m1,
|
|
unordered_multiset<T, H, P, A> &m2);
|
|
|
|
template <class Value, class Hash, class Pred, class Alloc>
|
|
class unordered_set
|
|
{
|
|
typedef boost::unordered_detail::hash_types_unique_keys<
|
|
Value, Value, Hash, Pred, Alloc
|
|
> implementation;
|
|
|
|
BOOST_DEDUCED_TYPENAME implementation::hash_table base;
|
|
|
|
public:
|
|
|
|
// types
|
|
|
|
typedef Value key_type;
|
|
typedef Value value_type;
|
|
typedef Hash hasher;
|
|
typedef Pred key_equal;
|
|
|
|
typedef Alloc allocator_type;
|
|
typedef BOOST_DEDUCED_TYPENAME allocator_type::pointer pointer;
|
|
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_pointer const_pointer;
|
|
typedef BOOST_DEDUCED_TYPENAME allocator_type::reference reference;
|
|
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_reference const_reference;
|
|
|
|
typedef BOOST_DEDUCED_TYPENAME implementation::size_type size_type;
|
|
typedef BOOST_DEDUCED_TYPENAME implementation::difference_type difference_type;
|
|
|
|
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator iterator;
|
|
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator const_iterator;
|
|
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator local_iterator;
|
|
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator const_local_iterator;
|
|
|
|
// construct/destroy/copy
|
|
|
|
explicit unordered_set(
|
|
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
|
const hasher &hf = hasher(),
|
|
const key_equal &eql = key_equal(),
|
|
const allocator_type &a = allocator_type())
|
|
: base(n, hf, eql, a)
|
|
{
|
|
}
|
|
|
|
// TODO: Should this be explicit?
|
|
unordered_set(allocator_type const& a)
|
|
: base(boost::unordered_detail::default_initial_bucket_count,
|
|
hasher(), key_equal(), a)
|
|
{
|
|
}
|
|
|
|
unordered_set(unordered_set const& other, allocator_type const& a)
|
|
: base(other.base, a)
|
|
{
|
|
}
|
|
|
|
template <class InputIterator>
|
|
unordered_set(InputIterator f, InputIterator l)
|
|
: base(f, l, boost::unordered_detail::default_initial_bucket_count,
|
|
hasher(), key_equal(), allocator_type())
|
|
{
|
|
}
|
|
|
|
template <class InputIterator>
|
|
unordered_set(InputIterator f, InputIterator l, size_type n,
|
|
const hasher &hf = hasher(),
|
|
const key_equal &eql = key_equal(),
|
|
const allocator_type &a = allocator_type())
|
|
: base(f, l, n, hf, eql, a)
|
|
{
|
|
}
|
|
|
|
#if defined(BOOST_HAS_RVALUE_REFS)
|
|
unordered_set(unordered_set&& other)
|
|
: base(other.base, boost::unordered_detail::move_tag())
|
|
{
|
|
}
|
|
|
|
unordered_set(unordered_set&& other, allocator_type const& a)
|
|
: base(other.base, a, boost::unordered_detail::move_tag())
|
|
{
|
|
}
|
|
|
|
unordered_set& operator=(unordered_set&& x)
|
|
{
|
|
base.move(x.base);
|
|
return *this;
|
|
}
|
|
#else
|
|
unordered_set(boost::unordered_detail::move_from<unordered_set<Value, Hash, Pred, Alloc> > other)
|
|
: base(other.source.base, boost::unordered_detail::move_tag())
|
|
{
|
|
}
|
|
|
|
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
|
|
unordered_set& operator=(unordered_set x)
|
|
{
|
|
base.move(x.base);
|
|
return *this;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
private:
|
|
|
|
BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
|
|
get(const_iterator const& it)
|
|
{
|
|
return boost::unordered_detail::iterator_access::get(it);
|
|
}
|
|
|
|
public:
|
|
|
|
allocator_type get_allocator() const
|
|
{
|
|
return base.get_allocator();
|
|
}
|
|
|
|
// size and capacity
|
|
|
|
bool empty() const
|
|
{
|
|
return base.empty();
|
|
}
|
|
|
|
size_type size() const
|
|
{
|
|
return base.size();
|
|
}
|
|
|
|
size_type max_size() const
|
|
{
|
|
return base.max_size();
|
|
}
|
|
|
|
// iterators
|
|
|
|
iterator begin()
|
|
{
|
|
return iterator(base.data_.begin());
|
|
}
|
|
|
|
const_iterator begin() const
|
|
{
|
|
return const_iterator(base.data_.begin());
|
|
}
|
|
|
|
iterator end()
|
|
{
|
|
return iterator(base.data_.end());
|
|
}
|
|
|
|
const_iterator end() const
|
|
{
|
|
return const_iterator(base.data_.end());
|
|
}
|
|
|
|
const_iterator cbegin() const
|
|
{
|
|
return const_iterator(base.data_.begin());
|
|
}
|
|
|
|
const_iterator cend() const
|
|
{
|
|
return const_iterator(base.data_.end());
|
|
}
|
|
|
|
// modifiers
|
|
|
|
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
|
template <class... Args>
|
|
std::pair<iterator, bool> emplace(Args&&... args)
|
|
{
|
|
return boost::unordered_detail::pair_cast<iterator, bool>(
|
|
base.insert(std::forward<Args>(args)...));
|
|
}
|
|
|
|
template <class... Args>
|
|
iterator emplace(const_iterator hint, Args&&... args)
|
|
{
|
|
return iterator(
|
|
base.insert_hint(get(hint), std::forward<Args>(args)...));
|
|
}
|
|
#endif
|
|
|
|
std::pair<iterator, bool> insert(const value_type& obj)
|
|
{
|
|
return boost::unordered_detail::pair_cast<iterator, bool>(
|
|
base.insert(obj));
|
|
}
|
|
|
|
iterator insert(const_iterator hint, const value_type& obj)
|
|
{
|
|
return iterator(base.insert_hint(get(hint), obj));
|
|
}
|
|
|
|
template <class InputIterator>
|
|
void insert(InputIterator first, InputIterator last)
|
|
{
|
|
base.insert_range(first, last);
|
|
}
|
|
|
|
iterator erase(const_iterator position)
|
|
{
|
|
return iterator(base.data_.erase(get(position)));
|
|
}
|
|
|
|
size_type erase(const key_type& k)
|
|
{
|
|
return base.erase_key(k);
|
|
}
|
|
|
|
iterator erase(const_iterator first, const_iterator last)
|
|
{
|
|
return iterator(base.data_.erase_range(get(first), get(last)));
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
base.data_.clear();
|
|
}
|
|
|
|
void swap(unordered_set& other)
|
|
{
|
|
base.swap(other.base);
|
|
}
|
|
|
|
// observers
|
|
|
|
hasher hash_function() const
|
|
{
|
|
return base.hash_function();
|
|
}
|
|
|
|
key_equal key_eq() const
|
|
{
|
|
return base.key_eq();
|
|
}
|
|
|
|
// lookup
|
|
|
|
const_iterator find(const key_type& k) const
|
|
{
|
|
return const_iterator(base.find(k));
|
|
}
|
|
|
|
size_type count(const key_type& k) const
|
|
{
|
|
return base.count(k);
|
|
}
|
|
|
|
std::pair<const_iterator, const_iterator>
|
|
equal_range(const key_type& k) const
|
|
{
|
|
return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
|
|
base.equal_range(k));
|
|
}
|
|
|
|
// bucket interface
|
|
|
|
size_type bucket_count() const
|
|
{
|
|
return base.bucket_count();
|
|
}
|
|
|
|
size_type max_bucket_count() const
|
|
{
|
|
return base.max_bucket_count();
|
|
}
|
|
|
|
size_type bucket_size(size_type n) const
|
|
{
|
|
return base.data_.bucket_size(n);
|
|
}
|
|
|
|
size_type bucket(const key_type& k) const
|
|
{
|
|
return base.bucket(k);
|
|
}
|
|
|
|
local_iterator begin(size_type n)
|
|
{
|
|
return local_iterator(base.data_.begin(n));
|
|
}
|
|
|
|
const_local_iterator begin(size_type n) const
|
|
{
|
|
return const_local_iterator(base.data_.begin(n));
|
|
}
|
|
|
|
local_iterator end(size_type n)
|
|
{
|
|
return local_iterator(base.data_.end(n));
|
|
}
|
|
|
|
const_local_iterator end(size_type n) const
|
|
{
|
|
return const_local_iterator(base.data_.end(n));
|
|
}
|
|
|
|
const_local_iterator cbegin(size_type n) const
|
|
{
|
|
return const_local_iterator(base.data_.begin(n));
|
|
}
|
|
|
|
const_local_iterator cend(size_type n) const
|
|
{
|
|
return const_local_iterator(base.data_.end(n));
|
|
}
|
|
|
|
// hash policy
|
|
|
|
float load_factor() const
|
|
{
|
|
return base.load_factor();
|
|
}
|
|
|
|
float max_load_factor() const
|
|
{
|
|
return base.max_load_factor();
|
|
}
|
|
|
|
void max_load_factor(float m)
|
|
{
|
|
base.max_load_factor(m);
|
|
}
|
|
|
|
void rehash(size_type n)
|
|
{
|
|
base.rehash(n);
|
|
}
|
|
|
|
friend bool operator==<>(unordered_set const&, unordered_set const&);
|
|
friend bool operator!=<>(unordered_set const&, unordered_set const&);
|
|
friend std::size_t hash_value<>(unordered_set const&);
|
|
}; // class template unordered_set
|
|
|
|
template <class T, class H, class P, class A>
|
|
inline bool operator==(unordered_set<T, H, P, A> const& m1,
|
|
unordered_set<T, H, P, A> const& m2)
|
|
{
|
|
return boost::unordered_detail::equals(m1.base, m2.base);
|
|
}
|
|
|
|
template <class T, class H, class P, class A>
|
|
inline bool operator!=(unordered_set<T, H, P, A> const& m1,
|
|
unordered_set<T, H, P, A> const& m2)
|
|
{
|
|
return !boost::unordered_detail::equals(m1.base, m2.base);
|
|
}
|
|
|
|
template <class T, class H, class P, class A>
|
|
inline std::size_t hash_value(unordered_set<T, H, P, A> const& m)
|
|
{
|
|
return boost::unordered_detail::hash_value(m.base);
|
|
}
|
|
|
|
template <class T, class H, class P, class A>
|
|
inline void swap(unordered_set<T, H, P, A> &m1,
|
|
unordered_set<T, H, P, A> &m2)
|
|
{
|
|
m1.swap(m2);
|
|
}
|
|
|
|
template <class Value, class Hash, class Pred, class Alloc>
|
|
class unordered_multiset
|
|
{
|
|
typedef boost::unordered_detail::hash_types_equivalent_keys<
|
|
Value, Value, Hash, Pred, Alloc
|
|
> implementation;
|
|
|
|
BOOST_DEDUCED_TYPENAME implementation::hash_table base;
|
|
|
|
public:
|
|
|
|
//types
|
|
|
|
typedef Value key_type;
|
|
typedef Value value_type;
|
|
typedef Hash hasher;
|
|
typedef Pred key_equal;
|
|
|
|
typedef Alloc allocator_type;
|
|
typedef BOOST_DEDUCED_TYPENAME allocator_type::pointer pointer;
|
|
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_pointer const_pointer;
|
|
typedef BOOST_DEDUCED_TYPENAME allocator_type::reference reference;
|
|
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_reference const_reference;
|
|
|
|
typedef BOOST_DEDUCED_TYPENAME implementation::size_type size_type;
|
|
typedef BOOST_DEDUCED_TYPENAME implementation::difference_type difference_type;
|
|
|
|
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator iterator;
|
|
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator const_iterator;
|
|
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator local_iterator;
|
|
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator const_local_iterator;
|
|
|
|
// construct/destroy/copy
|
|
|
|
explicit unordered_multiset(
|
|
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
|
const hasher &hf = hasher(),
|
|
const key_equal &eql = key_equal(),
|
|
const allocator_type &a = allocator_type())
|
|
: base(n, hf, eql, a)
|
|
{
|
|
}
|
|
|
|
// TODO: Should this be explicit?
|
|
unordered_multiset(allocator_type const& a)
|
|
: base(boost::unordered_detail::default_initial_bucket_count,
|
|
hasher(), key_equal(), a)
|
|
{
|
|
}
|
|
|
|
unordered_multiset(unordered_multiset const& other, allocator_type const& a)
|
|
: base(other.base, a)
|
|
{
|
|
}
|
|
|
|
template <class InputIterator>
|
|
unordered_multiset(InputIterator f, InputIterator l)
|
|
: base(f, l, boost::unordered_detail::default_initial_bucket_count,
|
|
hasher(), key_equal(), allocator_type())
|
|
{
|
|
}
|
|
|
|
template <class InputIterator>
|
|
unordered_multiset(InputIterator f, InputIterator l, size_type n,
|
|
const hasher &hf = hasher(),
|
|
const key_equal &eql = key_equal(),
|
|
const allocator_type &a = allocator_type())
|
|
: base(f, l, n, hf, eql, a)
|
|
{
|
|
}
|
|
|
|
#if defined(BOOST_HAS_RVALUE_REFS)
|
|
unordered_multiset(unordered_multiset&& other)
|
|
: base(other.base, boost::unordered_detail::move_tag())
|
|
{
|
|
}
|
|
|
|
unordered_multiset(unordered_multiset&& other, allocator_type const& a)
|
|
: base(other.base, a, boost::unordered_detail::move_tag())
|
|
{
|
|
}
|
|
|
|
unordered_multiset& operator=(unordered_multiset&& x)
|
|
{
|
|
base.move(x.base);
|
|
return *this;
|
|
}
|
|
#else
|
|
unordered_multiset(boost::unordered_detail::move_from<unordered_multiset<Value, Hash, Pred, Alloc> > other)
|
|
: base(other.source.base, boost::unordered_detail::move_tag())
|
|
{
|
|
}
|
|
|
|
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
|
|
unordered_multiset& operator=(unordered_multiset x)
|
|
{
|
|
base.move(x.base);
|
|
return *this;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
private:
|
|
|
|
BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
|
|
get(const_iterator const& it)
|
|
{
|
|
return boost::unordered_detail::iterator_access::get(it);
|
|
}
|
|
|
|
public:
|
|
|
|
allocator_type get_allocator() const
|
|
{
|
|
return base.get_allocator();
|
|
}
|
|
|
|
// size and capacity
|
|
|
|
bool empty() const
|
|
{
|
|
return base.empty();
|
|
}
|
|
|
|
size_type size() const
|
|
{
|
|
return base.size();
|
|
}
|
|
|
|
size_type max_size() const
|
|
{
|
|
return base.max_size();
|
|
}
|
|
|
|
// iterators
|
|
|
|
iterator begin()
|
|
{
|
|
return iterator(base.data_.begin());
|
|
}
|
|
|
|
const_iterator begin() const
|
|
{
|
|
return const_iterator(base.data_.begin());
|
|
}
|
|
|
|
iterator end()
|
|
{
|
|
return iterator(base.data_.end());
|
|
}
|
|
|
|
const_iterator end() const
|
|
{
|
|
return const_iterator(base.data_.end());
|
|
}
|
|
|
|
const_iterator cbegin() const
|
|
{
|
|
return const_iterator(base.data_.begin());
|
|
}
|
|
|
|
const_iterator cend() const
|
|
{
|
|
return const_iterator(base.data_.end());
|
|
}
|
|
|
|
// modifiers
|
|
|
|
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
|
template <class... Args>
|
|
iterator emplace(Args&&... args)
|
|
{
|
|
return iterator(base.insert(std::forward<Args>(args)...));
|
|
}
|
|
|
|
template <class... Args>
|
|
iterator emplace(const_iterator hint, Args&&... args)
|
|
{
|
|
return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
|
|
}
|
|
#endif
|
|
|
|
iterator insert(const value_type& obj)
|
|
{
|
|
return iterator(base.insert(obj));
|
|
}
|
|
|
|
iterator insert(const_iterator hint, const value_type& obj)
|
|
{
|
|
return iterator(base.insert_hint(get(hint), obj));
|
|
}
|
|
|
|
template <class InputIterator>
|
|
void insert(InputIterator first, InputIterator last)
|
|
{
|
|
base.insert_range(first, last);
|
|
}
|
|
|
|
iterator erase(const_iterator position)
|
|
{
|
|
return iterator(base.data_.erase(get(position)));
|
|
}
|
|
|
|
size_type erase(const key_type& k)
|
|
{
|
|
return base.erase_key(k);
|
|
}
|
|
|
|
iterator erase(const_iterator first, const_iterator last)
|
|
{
|
|
return iterator(base.data_.erase_range(get(first), get(last)));
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
base.data_.clear();
|
|
}
|
|
|
|
void swap(unordered_multiset& other)
|
|
{
|
|
base.swap(other.base);
|
|
}
|
|
|
|
// observers
|
|
|
|
hasher hash_function() const
|
|
{
|
|
return base.hash_function();
|
|
}
|
|
|
|
key_equal key_eq() const
|
|
{
|
|
return base.key_eq();
|
|
}
|
|
|
|
// lookup
|
|
|
|
const_iterator find(const key_type& k) const
|
|
{
|
|
return const_iterator(base.find(k));
|
|
}
|
|
|
|
size_type count(const key_type& k) const
|
|
{
|
|
return base.count(k);
|
|
}
|
|
|
|
std::pair<const_iterator, const_iterator>
|
|
equal_range(const key_type& k) const
|
|
{
|
|
return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
|
|
base.equal_range(k));
|
|
}
|
|
|
|
// bucket interface
|
|
|
|
size_type bucket_count() const
|
|
{
|
|
return base.bucket_count();
|
|
}
|
|
|
|
size_type max_bucket_count() const
|
|
{
|
|
return base.max_bucket_count();
|
|
}
|
|
|
|
size_type bucket_size(size_type n) const
|
|
{
|
|
return base.data_.bucket_size(n);
|
|
}
|
|
|
|
size_type bucket(const key_type& k) const
|
|
{
|
|
return base.bucket(k);
|
|
}
|
|
|
|
local_iterator begin(size_type n)
|
|
{
|
|
return local_iterator(base.data_.begin(n));
|
|
}
|
|
|
|
const_local_iterator begin(size_type n) const
|
|
{
|
|
return const_local_iterator(base.data_.begin(n));
|
|
}
|
|
|
|
local_iterator end(size_type n)
|
|
{
|
|
return local_iterator(base.data_.end(n));
|
|
}
|
|
|
|
const_local_iterator end(size_type n) const
|
|
{
|
|
return const_local_iterator(base.data_.end(n));
|
|
}
|
|
|
|
const_local_iterator cbegin(size_type n) const
|
|
{
|
|
return const_local_iterator(base.data_.begin(n));
|
|
}
|
|
|
|
const_local_iterator cend(size_type n) const
|
|
{
|
|
return const_local_iterator(base.data_.end(n));
|
|
}
|
|
|
|
// hash policy
|
|
|
|
float load_factor() const
|
|
{
|
|
return base.load_factor();
|
|
}
|
|
|
|
float max_load_factor() const
|
|
{
|
|
return base.max_load_factor();
|
|
}
|
|
|
|
void max_load_factor(float m)
|
|
{
|
|
base.max_load_factor(m);
|
|
}
|
|
|
|
void rehash(size_type n)
|
|
{
|
|
base.rehash(n);
|
|
}
|
|
|
|
friend bool operator==<>(unordered_multiset const&, unordered_multiset const&);
|
|
friend bool operator!=<>(unordered_multiset const&, unordered_multiset const&);
|
|
friend std::size_t hash_value<>(unordered_multiset const&);
|
|
}; // class template unordered_multiset
|
|
|
|
template <class T, class H, class P, class A>
|
|
inline bool operator==(unordered_multiset<T, H, P, A> const& m1,
|
|
unordered_multiset<T, H, P, A> const& m2)
|
|
{
|
|
return boost::unordered_detail::equals(m1.base, m2.base);
|
|
}
|
|
|
|
template <class T, class H, class P, class A>
|
|
inline bool operator!=(unordered_multiset<T, H, P, A> const& m1,
|
|
unordered_multiset<T, H, P, A> const& m2)
|
|
{
|
|
return !boost::unordered_detail::equals(m1.base, m2.base);
|
|
}
|
|
|
|
template <class T, class H, class P, class A>
|
|
inline std::size_t hash_value(unordered_multiset<T, H, P, A> const& m)
|
|
{
|
|
return boost::unordered_detail::hash_value(m.base);
|
|
}
|
|
|
|
template <class T, class H, class P, class A>
|
|
inline void swap(unordered_multiset<T, H, P, A> &m1,
|
|
unordered_multiset<T, H, P, A> &m2)
|
|
{
|
|
m1.swap(m2);
|
|
}
|
|
|
|
} // namespace boost
|
|
|
|
#endif // BOOST_UNORDERED_SET_HPP_INCLUDED
|