Merge pull request #128 from cmazakas/feature/iterator-independence

Remove dependencies on Iterator, Detail
This commit is contained in:
Peter Dimov
2022-06-21 21:45:12 +03:00
committed by GitHub
5 changed files with 218 additions and 72 deletions

View File

@ -18,7 +18,6 @@ target_link_libraries(boost_unordered
Boost::config Boost::config
Boost::container_hash Boost::container_hash
Boost::core Boost::core
Boost::iterator
Boost::move Boost::move
Boost::mp11 Boost::mp11
Boost::predef Boost::predef

View File

@ -124,25 +124,6 @@ to normal separate chaining implementations.
#include <boost/core/empty_value.hpp> #include <boost/core/empty_value.hpp>
#include <boost/core/no_exceptions_support.hpp> #include <boost/core/no_exceptions_support.hpp>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
// `iterator_facade` has transitive dependencies on Boost.MPL; one of the
// headers is generating a `-Wsign-conversion` warning which has an open PR to
// address the issue but merging does not seem likely so for now create a rote
// workaround.
//
// TODO: eventually remove this once MPL is fixed or we decide to migrate off of
// the Boost.Iterator dependency.
//
#if defined(BOOST_GCC)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wconversion"
#include <boost/iterator/iterator_facade.hpp>
#pragma GCC diagnostic pop
#else
#include <boost/iterator/iterator_facade.hpp>
#endif
#include <boost/move/core.hpp> #include <boost/move/core.hpp>
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
#include <boost/preprocessor/seq/enum.hpp> #include <boost/preprocessor/seq/enum.hpp>
@ -153,6 +134,7 @@ to normal separate chaining implementations.
#include <boost/type_traits/alignment_of.hpp> #include <boost/type_traits/alignment_of.hpp>
#include <climits> #include <climits>
#include <iterator>
namespace boost { namespace boost {
namespace unordered { namespace unordered {
@ -472,10 +454,7 @@ namespace boost {
return ~(~(std::size_t(0)) >> (sizeof(std::size_t) * 8 - n)); return ~(~(std::size_t(0)) >> (sizeof(std::size_t) * 8 - n));
} }
template <class Bucket> template <class Bucket> struct grouped_bucket_iterator
struct grouped_bucket_iterator
: public boost::iterator_facade<grouped_bucket_iterator<Bucket>,
Bucket, boost::forward_traversal_tag>
{ {
public: public:
typedef typename Bucket::bucket_pointer bucket_pointer; typedef typename Bucket::bucket_pointer bucket_pointer;
@ -483,8 +462,12 @@ namespace boost {
typename boost::pointer_traits<bucket_pointer>::template rebind_to< typename boost::pointer_traits<bucket_pointer>::template rebind_to<
bucket_group<Bucket> >::type bucket_group_pointer; bucket_group<Bucket> >::type bucket_group_pointer;
typedef Bucket value_type;
typedef typename boost::pointer_traits<bucket_pointer>::difference_type typedef typename boost::pointer_traits<bucket_pointer>::difference_type
difference_type; difference_type;
typedef Bucket& reference;
typedef Bucket* pointer;
typedef std::forward_iterator_tag iterator_category;
private: private:
bucket_pointer p; bucket_pointer p;
@ -493,9 +476,38 @@ namespace boost {
public: public:
grouped_bucket_iterator() : p(), pbg() {} grouped_bucket_iterator() : p(), pbg() {}
private: reference operator*() const BOOST_NOEXCEPT { return dereference(); }
friend class boost::iterator_core_access; pointer operator->() const BOOST_NOEXCEPT
{
return boost::to_address(p);
}
grouped_bucket_iterator& operator++() BOOST_NOEXCEPT
{
increment();
return *this;
}
grouped_bucket_iterator operator++(int) BOOST_NOEXCEPT
{
grouped_bucket_iterator old = *this;
increment();
return old;
}
bool operator==(
grouped_bucket_iterator const& other) const BOOST_NOEXCEPT
{
return equal(other);
}
bool operator!=(
grouped_bucket_iterator const& other) const BOOST_NOEXCEPT
{
return !equal(other);
}
private:
template <typename, typename, typename> template <typename, typename, typename>
friend class grouped_bucket_array; friend class grouped_bucket_array;
@ -533,12 +545,8 @@ namespace boost {
template <class Node> struct const_grouped_local_bucket_iterator; template <class Node> struct const_grouped_local_bucket_iterator;
template <class Node> template <class Node> struct grouped_local_bucket_iterator
struct grouped_local_bucket_iterator
: public boost::iterator_facade<grouped_local_bucket_iterator<Node>,
typename Node::value_type, boost::forward_traversal_tag>
{ {
typedef typename Node::node_pointer node_pointer; typedef typename Node::node_pointer node_pointer;
public: public:
@ -551,9 +559,39 @@ namespace boost {
grouped_local_bucket_iterator() : p() {} grouped_local_bucket_iterator() : p() {}
private: reference operator*() const BOOST_NOEXCEPT { return dereference(); }
friend class boost::iterator_core_access;
pointer operator->() const BOOST_NOEXCEPT
{
return boost::to_address(p);
}
grouped_local_bucket_iterator& operator++() BOOST_NOEXCEPT
{
increment();
return *this;
}
grouped_local_bucket_iterator operator++(int) BOOST_NOEXCEPT
{
grouped_local_bucket_iterator old = *this;
increment();
return old;
}
bool operator==(
grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT
{
return equal(other);
}
bool operator!=(
grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT
{
return !equal(other);
}
private:
template <typename, typename, typename> template <typename, typename, typename>
friend class grouped_bucket_array; friend class grouped_bucket_array;
@ -573,11 +611,7 @@ namespace boost {
node_pointer p; node_pointer p;
}; };
template <class Node> template <class Node> struct const_grouped_local_bucket_iterator
struct const_grouped_local_bucket_iterator
: public boost::iterator_facade<
const_grouped_local_bucket_iterator<Node>,
typename Node::value_type const, boost::forward_traversal_tag>
{ {
typedef typename Node::node_pointer node_pointer; typedef typename Node::node_pointer node_pointer;
@ -596,9 +630,39 @@ namespace boost {
{ {
} }
private: reference operator*() const BOOST_NOEXCEPT { return dereference(); }
friend class boost::iterator_core_access;
pointer operator->() const BOOST_NOEXCEPT
{
return boost::to_address(p);
}
const_grouped_local_bucket_iterator& operator++() BOOST_NOEXCEPT
{
increment();
return *this;
}
const_grouped_local_bucket_iterator operator++(int) BOOST_NOEXCEPT
{
const_grouped_local_bucket_iterator old = *this;
increment();
return old;
}
bool operator==(
const_grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT
{
return equal(other);
}
bool operator!=(
const_grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT
{
return !equal(other);
}
private:
template <typename, typename, typename> template <typename, typename, typename>
friend class grouped_bucket_array; friend class grouped_bucket_array;

View File

@ -1697,10 +1697,9 @@ namespace boost {
}; };
template <typename T> template <typename T>
struct rv_ref struct rv_ref : boost::conditional<boost::is_class<T>::value,
: boost::detail::if_true<boost::is_class<T>::value>:: boost::unordered::detail::rv_ref_impl<T>,
BOOST_NESTED_TEMPLATE then<boost::unordered::detail::rv_ref_impl<T>, please_ignore_this_overload>::type
please_ignore_this_overload>::type
{ {
}; };
@ -1730,10 +1729,7 @@ namespace boost {
namespace iterator_detail { namespace iterator_detail {
template <class Node, class Bucket> class c_iterator; template <class Node, class Bucket> class c_iterator;
template <class Node, class Bucket> template <class Node, class Bucket> class iterator
class iterator
: public boost::iterator_facade<iterator<Node, Bucket>,
typename Node::value_type, boost::forward_traversal_tag>
{ {
public: public:
typedef typename Node::value_type value_type; typedef typename Node::value_type value_type;
@ -1745,6 +1741,50 @@ namespace boost {
iterator() : p(), itb(){}; iterator() : p(), itb(){};
reference operator*() const BOOST_NOEXCEPT { return dereference(); }
pointer operator->() const BOOST_NOEXCEPT
{
pointer x = boost::addressof(p->value());
return x;
}
iterator& operator++() BOOST_NOEXCEPT
{
increment();
return *this;
}
iterator operator++(int) BOOST_NOEXCEPT
{
iterator old = *this;
increment();
return old;
}
bool operator==(iterator const& other) const BOOST_NOEXCEPT
{
return equal(other);
}
bool operator!=(iterator const& other) const BOOST_NOEXCEPT
{
return !equal(other);
}
bool operator==(
boost::unordered::detail::iterator_detail::c_iterator<Node,
Bucket> const& other) const BOOST_NOEXCEPT
{
return equal(other);
}
bool operator!=(
boost::unordered::detail::iterator_detail::c_iterator<Node,
Bucket> const& other) const BOOST_NOEXCEPT
{
return !equal(other);
}
private: private:
typedef typename Node::node_pointer node_pointer; typedef typename Node::node_pointer node_pointer;
typedef grouped_bucket_iterator<Bucket> bucket_iterator; typedef grouped_bucket_iterator<Bucket> bucket_iterator;
@ -1754,7 +1794,6 @@ namespace boost {
template <class Types> friend struct boost::unordered::detail::table; template <class Types> friend struct boost::unordered::detail::table;
template <class N, class B> friend class c_iterator; template <class N, class B> friend class c_iterator;
friend class boost::iterator_core_access;
iterator(node_pointer p_, bucket_iterator itb_) : p(p_), itb(itb_) {} iterator(node_pointer p_, bucket_iterator itb_) : p(p_), itb(itb_) {}
@ -1765,6 +1804,13 @@ namespace boost {
return (p == x.p); return (p == x.p);
} }
bool equal(
const boost::unordered::detail::iterator_detail::c_iterator<Node,
Bucket>& x) const BOOST_NOEXCEPT
{
return (p == x.p);
}
void increment() BOOST_NOEXCEPT void increment() BOOST_NOEXCEPT
{ {
p = p->next; p = p->next;
@ -1774,10 +1820,7 @@ namespace boost {
} }
}; };
template <class Node, class Bucket> template <class Node, class Bucket> class c_iterator
class c_iterator
: public boost::iterator_facade<c_iterator<Node, Bucket>,
typename Node::value_type const, boost::forward_traversal_tag>
{ {
public: public:
typedef typename Node::value_type value_type; typedef typename Node::value_type value_type;
@ -1788,7 +1831,51 @@ namespace boost {
typedef std::forward_iterator_tag iterator_category; typedef std::forward_iterator_tag iterator_category;
c_iterator() : p(), itb(){}; c_iterator() : p(), itb(){};
c_iterator(iterator<Node, Bucket> it) : p(it.p), itb(it.itb){}; c_iterator(iterator<Node, Bucket> it) : p(it.p), itb(it.itb) {}
reference operator*() const BOOST_NOEXCEPT { return dereference(); }
pointer operator->() const BOOST_NOEXCEPT
{
pointer x = boost::addressof(p->value());
return x;
}
c_iterator& operator++() BOOST_NOEXCEPT
{
increment();
return *this;
}
c_iterator operator++(int) BOOST_NOEXCEPT
{
c_iterator old = *this;
increment();
return old;
}
bool operator==(c_iterator const& other) const BOOST_NOEXCEPT
{
return equal(other);
}
bool operator!=(c_iterator const& other) const BOOST_NOEXCEPT
{
return !equal(other);
}
bool operator==(
boost::unordered::detail::iterator_detail::iterator<Node,
Bucket> const& other) const BOOST_NOEXCEPT
{
return equal(other);
}
bool operator!=(
boost::unordered::detail::iterator_detail::iterator<Node,
Bucket> const& other) const BOOST_NOEXCEPT
{
return !equal(other);
}
private: private:
typedef typename Node::node_pointer node_pointer; typedef typename Node::node_pointer node_pointer;
@ -1798,7 +1885,7 @@ namespace boost {
bucket_iterator itb; bucket_iterator itb;
template <class Types> friend struct boost::unordered::detail::table; template <class Types> friend struct boost::unordered::detail::table;
friend class boost::iterator_core_access; template <class, class> friend class iterator;
c_iterator(node_pointer p_, bucket_iterator itb_) : p(p_), itb(itb_) c_iterator(node_pointer p_, bucket_iterator itb_) : p(p_), itb(itb_)
{ {
@ -2362,13 +2449,8 @@ namespace boost {
k, this->hash_function(), this->key_eq()); k, this->hash_function(), this->key_eq());
} }
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning( \
disable : 4714) // function 'function' marked as __forceinline not inlined
#endif
template <class Key, class Hash, class Pred> template <class Key, class Hash, class Pred>
BOOST_FORCEINLINE iterator transparent_find( inline iterator transparent_find(
Key const& k, Hash const& h, Pred const& pred) const Key const& k, Hash const& h, Pred const& pred) const
{ {
std::size_t const key_hash = h(k); std::size_t const key_hash = h(k);
@ -2382,10 +2464,6 @@ namespace boost {
return this->end(); return this->end();
} }
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
template <class Key> template <class Key>
node_pointer* find_prev(Key const& key, bucket_iterator itb) node_pointer* find_prev(Key const& key, bucket_iterator itb)
{ {
@ -3418,8 +3496,8 @@ namespace boost {
sizeof(choice2::type) sizeof(choice2::type)
}; };
typedef typename boost::detail::if_true<value>::BOOST_NESTED_TEMPLATE typedef
then<Key const&, no_key>::type type; typename boost::conditional<value, Key const&, no_key>::type type;
}; };
template <class ValueType> struct set_extractor template <class ValueType> struct set_extractor

View File

@ -6,6 +6,12 @@ include(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST)
if(HAVE_BOOST_TEST) if(HAVE_BOOST_TEST)
boost_test_jamfile(FILE Jamfile.v2 LINK_LIBRARIES Boost::unordered Boost::core) boost_test_jamfile(
FILE Jamfile.v2
LINK_LIBRARIES
Boost::unordered
Boost::core
Boost::concept_check
)
endif() endif()

View File

@ -9,8 +9,8 @@
#include "./generators.hpp" #include "./generators.hpp"
#include "./list.hpp" #include "./list.hpp"
#include "./metafunctions.hpp" #include "./metafunctions.hpp"
#include <boost/type_traits/conditional.hpp>
#include <algorithm> #include <algorithm>
#include <boost/detail/select_type.hpp>
namespace test { namespace test {
template <class X> struct unordered_generator_set template <class X> struct unordered_generator_set
@ -69,9 +69,8 @@ namespace test {
template <class X> template <class X>
struct unordered_generator_base struct unordered_generator_base
: public boost::detail::if_true<test::is_set<X>::value>:: : public boost::conditional<test::is_set<X>::value,
BOOST_NESTED_TEMPLATE then<test::unordered_generator_set<X>, test::unordered_generator_set<X>, test::unordered_generator_map<X> >
test::unordered_generator_map<X> >
{ {
}; };