- Reduced compile-time dependencies:

- linear_slist_algorithms use a simple node_ptr instead of std::pair on return.
  - list/slist use operator </operator == instead of std::equal_to/std::less.
This commit is contained in:
Ion Gaztañaga
2021-01-05 10:09:01 +01:00
parent c3ac8668ae
commit 547c964381
6 changed files with 127 additions and 32 deletions

View File

@@ -3888,6 +3888,9 @@ to be inserted in intrusive containers are allocated using `std::vector` or `std
[section:release_notes_boost_1_76_00 Boost 1.76 Release] [section:release_notes_boost_1_76_00 Boost 1.76 Release]
* Reduced compile-time dependencies:
* `linear_slist_algorithms` use a simple node_ptr instead of std::pair on return.
* `list`/`slist` use `operator <`/`operator ==` instead of `std::equal_to`/`std::less`.
* Fixed bugs: * Fixed bugs:
* [@https://github.com/boostorg/intrusive/issues/54 GitHub #54: ['set.rbegin() looks like O(log(N))]] * [@https://github.com/boostorg/intrusive/issues/54 GitHub #54: ['set.rbegin() looks like O(log(N))]]

View File

@@ -0,0 +1,45 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// 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/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_TWIN_HPP
#define BOOST_INTRUSIVE_DETAIL_TWIN_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
//A tiny utility to avoid pulling std::pair / utility for
//very simple algorithms/types
namespace boost {
namespace intrusive {
template <class T>
struct twin
{
typedef T type;
twin()
: first(), second()
{}
T first;
T second;
};
} //namespace intrusive{
} //namespace boost{
#endif //BOOST_INTRUSIVE_DETAIL_TWIN_HPP

View File

@@ -0,0 +1,42 @@
#ifndef BOOST_INTRUSIVE_DETAIL_VALUE_FUNCTORS_HPP
#define BOOST_INTRUSIVE_DETAIL_VALUE_FUNCTORS_HPP
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2017-2021. 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/intrusive for documentation.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//Functors for member algorithm defaults
template<class ValueType>
struct value_less
{
bool operator()(const ValueType &a, const ValueType &b) const
{ return a < b; }
};
template<class ValueType>
struct value_equal
{
bool operator()(const ValueType &a, const ValueType &b) const
{ return a == b; }
};
} //namespace intrusive {
} //namespace boost {
#endif //BOOST_INTRUSIVE_DETAIL_VALUE_FUNCTORS_HPP

View File

@@ -19,7 +19,7 @@
#include <boost/intrusive/detail/common_slist_algorithms.hpp> #include <boost/intrusive/detail/common_slist_algorithms.hpp>
#include <boost/intrusive/detail/algo_type.hpp> #include <boost/intrusive/detail/algo_type.hpp>
#include <cstddef> #include <cstddef>
#include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair #include <boost/intrusive/detail/twin.hpp> //for node_pair
#if defined(BOOST_HAS_PRAGMA_ONCE) #if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once # pragma once
@@ -62,6 +62,12 @@ class linear_slist_algorithms
typedef typename NodeTraits::node_ptr node_ptr; typedef typename NodeTraits::node_ptr node_ptr;
typedef typename NodeTraits::const_node_ptr const_node_ptr; typedef typename NodeTraits::const_node_ptr const_node_ptr;
typedef NodeTraits node_traits; typedef NodeTraits node_traits;
//A simple struct containing:
//
// typedef node_ptr type;
// node_ptr first;
// node_ptr second;
typedef twin<node_ptr> node_pair;
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
@@ -222,9 +228,9 @@ class linear_slist_algorithms
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
//! //!
//! <b>Complexity</b>: Linear to the number of elements plus the number moved positions. //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
static std::pair<node_ptr, node_ptr> move_first_n_backwards(node_ptr p, std::size_t n) static node_pair move_first_n_backwards(node_ptr p, std::size_t n)
{ {
std::pair<node_ptr, node_ptr> ret; node_pair ret;
//Null shift, or count() == 0 or 1, nothing to do //Null shift, or count() == 0 or 1, nothing to do
if(!n || !p || !NodeTraits::get_next(p)){ if(!n || !p || !NodeTraits::get_next(p)){
return ret; return ret;
@@ -277,9 +283,9 @@ class linear_slist_algorithms
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
//! //!
//! <b>Complexity</b>: Linear to the number of elements plus the number moved positions. //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
static std::pair<node_ptr, node_ptr> move_first_n_forward(node_ptr p, std::size_t n) static node_pair move_first_n_forward(node_ptr p, std::size_t n)
{ {
std::pair<node_ptr, node_ptr> ret; node_pair ret;
//Null shift, or count() == 0 or 1, nothing to do //Null shift, or count() == 0 or 1, nothing to do
if(!n || !p || !NodeTraits::get_next(p)) if(!n || !p || !NodeTraits::get_next(p))
return ret; return ret;

View File

@@ -39,7 +39,7 @@
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//std::less #include <boost/intrusive/detail/value_functors.hpp>
#include <cstddef> //std::size_t, etc. #include <cstddef> //std::size_t, etc.
#if defined(BOOST_HAS_PRAGMA_ONCE) #if defined(BOOST_HAS_PRAGMA_ONCE)
@@ -988,19 +988,19 @@ class list_impl
} }
} }
//! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>. //! <b>Effects</b>: This function sorts the list *this according to operator <.
//! The sort is stable, that is, the relative order of equivalent elements is preserved. //! The sort is stable, that is, the relative order of equivalent elements is preserved.
//! //!
//! <b>Throws</b>: If value_traits::node_traits::node //! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
//! or std::less<value_type> throws. Basic guarantee. //! or operator < throws. Basic guarantee.
//! //!
//! <b>Notes</b>: Iterators and references are not invalidated. //! <b>Notes</b>: Iterators and references are not invalidated.
//! //!
//! <b>Complexity</b>: The number of comparisons is approximately N log N, where N //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
//! is the list's size. //! is the list's size.
void sort() void sort()
{ this->sort(std::less<value_type>()); } { this->sort(value_less<value_type>()); }
//! <b>Requires</b>: p must be a comparison function that induces a strict weak ordering //! <b>Requires</b>: p must be a comparison function that induces a strict weak ordering
//! //!
@@ -1043,18 +1043,18 @@ class list_impl
} }
//! <b>Effects</b>: This function removes all of x's elements and inserts them //! <b>Effects</b>: This function removes all of x's elements and inserts them
//! in order into *this according to std::less<value_type>. The merge is stable; //! in order into *this according to operator <. The merge is stable;
//! that is, if an element from *this is equivalent to one from x, then the element //! that is, if an element from *this is equivalent to one from x, then the element
//! from *this will precede the one from x. //! from *this will precede the one from x.
//! //!
//! <b>Throws</b>: If std::less<value_type> throws. Basic guarantee. //! <b>Throws</b>: If operator < throws. Basic guarantee.
//! //!
//! <b>Complexity</b>: This function is linear time: it performs at most //! <b>Complexity</b>: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons. //! size() + x.size() - 1 comparisons.
//! //!
//! <b>Note</b>: Iterators and references are not invalidated //! <b>Note</b>: Iterators and references are not invalidated
void merge(list_impl& x) void merge(list_impl& x)
{ this->merge(x, std::less<value_type>()); } { this->merge(x, value_less<value_type>()); }
//! <b>Requires</b>: p must be a comparison function that induces a strict weak //! <b>Requires</b>: p must be a comparison function that induces a strict weak
//! ordering and both *this and x must be sorted according to that ordering //! ordering and both *this and x must be sorted according to that ordering
@@ -1108,21 +1108,21 @@ class list_impl
//! <b>Effects</b>: Removes all the elements that compare equal to value. //! <b>Effects</b>: Removes all the elements that compare equal to value.
//! No destructors are called. //! No destructors are called.
//! //!
//! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee. //! <b>Throws</b>: If operator == throws. Basic guarantee.
//! //!
//! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality. //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
//! //!
//! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
void remove(const_reference value) void remove(const_reference value)
{ this->remove_if(detail::equal_to_value<const_reference>(value)); } { this->remove_if(value_equal<const_reference>(value)); }
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Removes all the elements that compare equal to value. //! <b>Effects</b>: Removes all the elements that compare equal to value.
//! Disposer::operator()(pointer) is called for every removed element. //! Disposer::operator()(pointer) is called for every removed element.
//! //!
//! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee. //! <b>Throws</b>: If operator == throws. Basic guarantee.
//! //!
//! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality. //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
//! //!
@@ -1130,7 +1130,7 @@ class list_impl
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
template<class Disposer> template<class Disposer>
void remove_and_dispose(const_reference value, Disposer disposer) void remove_and_dispose(const_reference value, Disposer disposer)
{ this->remove_and_dispose_if(detail::equal_to_value<const_reference>(value), disposer); } { this->remove_and_dispose_if(value_equal<const_reference>(value), disposer); }
//! <b>Effects</b>: Removes all the elements for which a specified //! <b>Effects</b>: Removes all the elements for which a specified
//! predicate is satisfied. No destructors are called. //! predicate is satisfied. No destructors are called.

View File

@@ -37,13 +37,12 @@
#include <boost/intrusive/detail/simple_disposers.hpp> #include <boost/intrusive/detail/simple_disposers.hpp>
#include <boost/intrusive/detail/size_holder.hpp> #include <boost/intrusive/detail/size_holder.hpp>
#include <boost/intrusive/detail/algorithm.hpp> #include <boost/intrusive/detail/algorithm.hpp>
#include <boost/intrusive/detail/value_functors.hpp>
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//std::less
#include <cstddef> //std::size_t #include <cstddef> //std::size_t
#include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair
#if defined(BOOST_HAS_PRAGMA_ONCE) #if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once # pragma once
@@ -1431,7 +1430,7 @@ class slist_impl
void splice(const_iterator pos, slist_impl &x, const_iterator f, const_iterator l, size_type n) void splice(const_iterator pos, slist_impl &x, const_iterator f, const_iterator l, size_type n)
{ return this->splice_after(this->previous(pos), x, x.previous(f), x.previous(l), n); } { return this->splice_after(this->previous(pos), x, x.previous(f), x.previous(l), n); }
//! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>. //! <b>Effects</b>: This function sorts the list *this according to operator<.
//! The sort is stable, that is, the relative order of equivalent elements is preserved. //! The sort is stable, that is, the relative order of equivalent elements is preserved.
//! //!
//! <b>Throws</b>: If value_traits::node_traits::node //! <b>Throws</b>: If value_traits::node_traits::node
@@ -1501,14 +1500,14 @@ class slist_impl
//! //!
//! <b>Throws</b>: If value_traits::node_traits::node //! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
//! or std::less<value_type> throws. Basic guarantee. //! or operator< throws. Basic guarantee.
//! //!
//! <b>Complexity</b>: This function is linear time: it performs at most //! <b>Complexity</b>: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons. //! size() + x.size() - 1 comparisons.
//! //!
//! <b>Note</b>: Iterators and references are not invalidated. //! <b>Note</b>: Iterators and references are not invalidated.
void sort() void sort()
{ this->sort(std::less<value_type>()); } { this->sort(value_less<value_type>()); }
//! <b>Requires</b>: p must be a comparison function that induces a strict weak //! <b>Requires</b>: p must be a comparison function that induces a strict weak
//! ordering and both *this and x must be sorted according to that ordering //! ordering and both *this and x must be sorted according to that ordering
@@ -1557,18 +1556,18 @@ class slist_impl
} }
//! <b>Effects</b>: This function removes all of x's elements and inserts them //! <b>Effects</b>: This function removes all of x's elements and inserts them
//! in order into *this according to std::less<value_type>. The merge is stable; //! in order into *this according to operator<. The merge is stable;
//! that is, if an element from *this is equivalent to one from x, then the element //! that is, if an element from *this is equivalent to one from x, then the element
//! from *this will precede the one from x. //! from *this will precede the one from x.
//! //!
//! <b>Throws</b>: if std::less<value_type> throws. Basic guarantee. //! <b>Throws</b>: if operator< throws. Basic guarantee.
//! //!
//! <b>Complexity</b>: This function is linear time: it performs at most //! <b>Complexity</b>: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons. //! size() + x.size() - 1 comparisons.
//! //!
//! <b>Note</b>: Iterators and references are not invalidated //! <b>Note</b>: Iterators and references are not invalidated
void merge(slist_impl& x) void merge(slist_impl& x)
{ this->merge(x, std::less<value_type>()); } { this->merge(x, value_less<value_type>()); }
//! <b>Effects</b>: Reverses the order of elements in the list. //! <b>Effects</b>: Reverses the order of elements in the list.
//! //!
@@ -1588,7 +1587,7 @@ class slist_impl
//! <b>Effects</b>: Removes all the elements that compare equal to value. //! <b>Effects</b>: Removes all the elements that compare equal to value.
//! No destructors are called. //! No destructors are called.
//! //!
//! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee. //! <b>Throws</b>: If operator== throws. Basic guarantee.
//! //!
//! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality. //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
//! //!
@@ -1603,7 +1602,7 @@ class slist_impl
//! <b>Effects</b>: Removes all the elements that compare equal to value. //! <b>Effects</b>: Removes all the elements that compare equal to value.
//! Disposer::operator()(pointer) is called for every removed element. //! Disposer::operator()(pointer) is called for every removed element.
//! //!
//! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee. //! <b>Throws</b>: If operator== throws. Basic guarantee.
//! //!
//! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality. //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
//! //!
@@ -1671,14 +1670,14 @@ class slist_impl
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
//! elements that are equal from the list. No destructors are called. //! elements that are equal from the list. No destructors are called.
//! //!
//! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee. //! <b>Throws</b>: If operator== throws. Basic guarantee.
//! //!
//! <b>Complexity</b>: Linear time (size()-1) comparisons calls to pred()). //! <b>Complexity</b>: Linear time (size()-1) comparisons calls to pred()).
//! //!
//! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
void unique() void unique()
{ this->unique_and_dispose(std::equal_to<value_type>(), detail::null_disposer()); } { this->unique_and_dispose(value_equal<value_type>(), detail::null_disposer()); }
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
//! elements that satisfy some binary predicate from the list. //! elements that satisfy some binary predicate from the list.
@@ -1700,7 +1699,7 @@ class slist_impl
//! elements that satisfy some binary predicate from the list. //! elements that satisfy some binary predicate from the list.
//! Disposer::operator()(pointer) is called for every removed element. //! Disposer::operator()(pointer) is called for every removed element.
//! //!
//! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee. //! <b>Throws</b>: If operator== throws. Basic guarantee.
//! //!
//! <b>Complexity</b>: Linear time (size()-1) comparisons equality comparisons. //! <b>Complexity</b>: Linear time (size()-1) comparisons equality comparisons.
//! //!
@@ -1708,7 +1707,7 @@ class slist_impl
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
template<class Disposer> template<class Disposer>
void unique_and_dispose(Disposer disposer) void unique_and_dispose(Disposer disposer)
{ this->unique(std::equal_to<value_type>(), disposer); } { this->unique(value_equal<value_type>(), disposer); }
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
@@ -2035,7 +2034,7 @@ class slist_impl
void priv_shift_backwards(size_type n, detail::bool_<true>) void priv_shift_backwards(size_type n, detail::bool_<true>)
{ {
std::pair<node_ptr, node_ptr> ret( typename node_algorithms::node_pair ret(
node_algorithms::move_first_n_forward node_algorithms::move_first_n_forward
(node_traits::get_next(this->get_root_node()), (std::size_t)n)); (node_traits::get_next(this->get_root_node()), (std::size_t)n));
if(ret.first){ if(ret.first){
@@ -2056,7 +2055,7 @@ class slist_impl
void priv_shift_forward(size_type n, detail::bool_<true>) void priv_shift_forward(size_type n, detail::bool_<true>)
{ {
std::pair<node_ptr, node_ptr> ret( typename node_algorithms::node_pair ret(
node_algorithms::move_first_n_backwards node_algorithms::move_first_n_backwards
(node_traits::get_next(this->get_root_node()), (std::size_t)n)); (node_traits::get_next(this->get_root_node()), (std::size_t)n));
if(ret.first){ if(ret.first){