Use of boost::adl_move_swap.

Replaced <algorithm> with <functional> where needed
Added basic equal/lexicographical compare algorithms to avoid complex <algorithm> include and ADL problems in some compilers
This commit is contained in:
Ion Gaztañaga 2014-11-26 19:32:12 +01:00
parent 55a3c8b9a5
commit adda517544
19 changed files with 161 additions and 126 deletions

View File

@ -12,7 +12,7 @@
//[doc_avl_set_code
#include <boost/intrusive/avl_set.hpp>
#include <vector>
#include <algorithm>
#include <functional>
#include <cassert>
using namespace boost::intrusive;

View File

@ -12,7 +12,7 @@
//[doc_positional_insertion
#include <boost/intrusive/set.hpp>
#include <vector>
#include <algorithm>
#include <functional>
#include <cassert>
using namespace boost::intrusive;

View File

@ -12,7 +12,7 @@
//[doc_set_code
#include <boost/intrusive/set.hpp>
#include <vector>
#include <algorithm>
#include <functional>
#include <cassert>
using namespace boost::intrusive;

View File

@ -12,7 +12,7 @@
//[doc_sg_set_code
#include <boost/intrusive/sg_set.hpp>
#include <vector>
#include <algorithm>
#include <functional>
#include <cassert>
using namespace boost::intrusive;

View File

@ -12,7 +12,7 @@
//[doc_splay_set_code
#include <boost/intrusive/splay_set.hpp>
#include <vector>
#include <algorithm>
#include <functional>
using namespace boost::intrusive;

View File

@ -12,7 +12,7 @@
//[doc_treap_set_code
#include <boost/intrusive/treap_set.hpp>
#include <vector>
#include <algorithm>
#include <functional>
#include <cassert>
using namespace boost::intrusive;

View File

@ -12,7 +12,7 @@
//[doc_unordered_set_code
#include <boost/intrusive/unordered_set.hpp>
#include <vector>
#include <algorithm>
#include <functional>
#include <boost/functional/hash.hpp>
using namespace boost::intrusive;

View File

@ -38,15 +38,16 @@
#include <boost/intrusive/detail/simple_disposers.hpp>
#include <boost/intrusive/detail/size_holder.hpp>
#include <boost/intrusive/detail/algo_type.hpp>
#include <boost/intrusive/detail/algorithm.hpp>
#include <boost/intrusive/detail/get_value_traits.hpp>
#include <boost/intrusive/bstree_algorithms.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/parent_from_member.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/adl_move_swap.hpp>
#include <utility> //pair,lexicographical_compare
#include <algorithm> //swap
#include <utility> //pair
#include <cstddef> //size_t...
#include <functional>//less, equal_to
@ -912,8 +913,7 @@ class bstree_impl
void swap(bstree_impl& other)
{
//This can throw
using std::swap;
swap(this->comp(), this->comp());
::boost::adl_move_swap(this->comp(), this->comp());
//These can't throw
node_algorithms::swap_tree(this->header_ptr(), node_ptr(other.header_ptr()));
if(constant_time_size){
@ -1952,7 +1952,7 @@ inline bool operator<
( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
#endif
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
@ -1968,29 +1968,11 @@ bool operator==
#endif
{
typedef bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> tree_type;
typedef typename tree_type::const_iterator const_iterator;
if(tree_type::constant_time_size && x.size() != y.size()){
return false;
}
const_iterator end1 = x.end();
const_iterator i1 = x.begin();
const_iterator i2 = y.begin();
if(tree_type::constant_time_size){
while (i1 != end1 && *i1 == *i2) {
++i1;
++i2;
}
return i1 == end1;
}
else{
const_iterator end2 = y.end();
while (i1 != end1 && i2 != end2 && *i1 == *i2) {
++i1;
++i2;
}
return i1 == end1 && i2 == end2;
}
return boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
}
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)

View File

@ -0,0 +1,86 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_ALGORITHM_HPP
#define BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP
#if defined(_MSC_VER)
# pragma once
#endif
namespace boost {
namespace intrusive {
struct algo_pred_equal
{
template<class T>
bool operator()(const T &x, const T &y) const
{ return x == y; }
};
struct algo_pred_less
{
template<class T>
bool operator()(const T &x, const T &y) const
{ return x < y; }
};
template<class InputIt1, class InputIt2, class BinaryPredicate>
bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryPredicate p)
{
for (; first1 != last1; ++first1, ++first2) {
if (!p(*first1, *first2)) {
return false;
}
}
return true;
}
template<class InputIt1, class InputIt2>
bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2)
{ return (algo_equal)(first1, last1, first2, algo_pred_equal()); }
template<class InputIt1, class InputIt2, class BinaryPredicate>
bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate pred)
{
for (; first1 != last1 && first2 != last2; ++first1, ++first2)
if (!pred(*first1, *first2))
return false;
return first1 == last1 && first2 == last2;
}
template<class InputIt1, class InputIt2>
bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
{ return (algo_equal)(first1, last1, first2, last2, algo_pred_equal()); }
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
bool algo_lexicographical_compare (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
BinaryPredicate pred)
{
while (first1 != last1){
if (first2 == last2 || *first2 < *first1) return false;
else if (pred(*first1, *first2)) return true;
++first1; ++first2;
}
return (first2 != last2);
}
template <class InputIterator1, class InputIterator2>
bool algo_lexicographical_compare (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2)
{ return (algo_lexicographical_compare)(first1, last1, first2, last2, algo_pred_less()); }
} //namespace intrusive {
} //namespace boost {
#endif //#ifndef BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP

View File

@ -18,15 +18,7 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
//std C++
#include <functional> //std::equal_to
#include <utility> //std::pair
#include <algorithm> //std::swap, std::lower_bound, std::upper_bound
#include <cstddef> //std::size_t
//boost
#include <boost/intrusive/detail/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/functional/hash.hpp>
//General intrusive utilities
#include <boost/intrusive/detail/hashtable_node.hpp>
#include <boost/intrusive/detail/transform_iterator.hpp>
@ -44,7 +36,20 @@
#include <boost/intrusive/slist.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/mpl.hpp>
//boost
#include <boost/functional/hash.hpp>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/adl_move_swap.hpp>
//std C++
#include <functional> //std::equal_to
#include <utility> //std::pair
#include <algorithm> //std::lower_bound, std::upper_bound
#include <cstddef> //std::size_t
namespace boost {
namespace intrusive {
@ -973,7 +978,7 @@ struct bucket_hash_equal_t<VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTra
void priv_swap_cache(bucket_hash_equal_t &other)
{
std::swap(this->cached_begin_, other.cached_begin_);
::boost::adl_move_swap(this->cached_begin_, other.cached_begin_);
}
siterator priv_begin() const
@ -1510,13 +1515,12 @@ class hashtable_impl
//! found using ADL throw. Basic guarantee.
void swap(hashtable_impl& other)
{
using std::swap;
//These can throw
swap(this->priv_equal(), other.priv_equal());
swap(this->priv_hasher(), other.priv_hasher());
::boost::adl_move_swap(this->priv_equal(), other.priv_equal());
::boost::adl_move_swap(this->priv_hasher(), other.priv_hasher());
//These can't throw
swap(this->priv_bucket_traits(), other.priv_bucket_traits());
swap(this->priv_value_traits(), other.priv_value_traits());
::boost::adl_move_swap(this->priv_bucket_traits(), other.priv_bucket_traits());
::boost::adl_move_swap(this->priv_value_traits(), other.priv_value_traits());
this->priv_swap_cache(other);
if(constant_time_size){
size_type backup = this->priv_size_traits().get_size();

View File

@ -38,13 +38,13 @@
#include <boost/intrusive/detail/key_nodeptr_comp.hpp>
#include <boost/intrusive/detail/simple_disposers.hpp>
#include <boost/intrusive/detail/size_holder.hpp>
#include <boost/intrusive/detail/algorithm.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/static_assert.hpp>
#include <algorithm>
#include <functional>
#include <cstddef>
#include <functional>//std::less
#include <cstddef> //std::size_t, etc.
namespace boost {
namespace intrusive {
@ -1349,7 +1349,7 @@ inline bool operator<
#else
(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
#endif
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
@ -1364,30 +1364,11 @@ bool operator==
#endif
{
typedef list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> list_type;
typedef typename list_type::const_iterator const_iterator;
const bool C = list_type::constant_time_size;
if(C && x.size() != y.size()){
return false;
}
const_iterator end1 = x.end();
const_iterator i1 = x.begin();
const_iterator i2 = y.begin();
if(C){
while (i1 != end1 && *i1 == *i2) {
++i1;
++i2;
}
return i1 == end1;
}
else{
const_iterator end2 = y.end();
while (i1 != end1 && i2 != end2 && *i1 == *i2) {
++i1;
++i2;
}
return i1 == end1 && i2 == end2;
}
return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
}
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)

View File

@ -24,12 +24,6 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <algorithm>
#include <cstddef>
#include <functional>
#include <utility>
#include <cmath>
#include <cstddef>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/intrusive/bs_set_hook.hpp>
@ -42,7 +36,16 @@
#include <boost/intrusive/sgtree_algorithms.hpp>
#include <boost/intrusive/detail/key_nodeptr_comp.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/adl_move_swap.hpp>
#include <cstddef>
#include <functional>
#include <utility>
#include <cmath>
#include <cstddef>
namespace boost {
namespace intrusive {
@ -304,7 +307,7 @@ class sgtree_impl
//! @copydoc ::boost::intrusive::bstree::bstree(bstree &&)
sgtree_impl(BOOST_RV_REF(sgtree_impl) x)
: tree_type(BOOST_MOVE_BASE(tree_type, x)), alpha_traits(x.get_alpha_traits())
{ std::swap(this->get_alpha_traits(), x.get_alpha_traits()); }
{ ::boost::adl_move_swap(this->get_alpha_traits(), x.get_alpha_traits()); }
//! @copydoc ::boost::intrusive::bstree::operator=(bstree &&)
sgtree_impl& operator=(BOOST_RV_REF(sgtree_impl) x)
@ -402,9 +405,8 @@ class sgtree_impl
void swap(sgtree_impl& other)
{
//This can throw
using std::swap;
this->tree_type::swap(static_cast<tree_type&>(other));
swap(this->get_alpha_traits(), other.get_alpha_traits());
::boost::adl_move_swap(this->get_alpha_traits(), other.get_alpha_traits());
}
//! @copydoc ::boost::intrusive::bstree::clone_from

View File

@ -40,12 +40,12 @@
#include <boost/intrusive/detail/key_nodeptr_comp.hpp>
#include <boost/intrusive/detail/simple_disposers.hpp>
#include <boost/intrusive/detail/size_holder.hpp>
#include <boost/intrusive/detail/algorithm.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/static_assert.hpp>
#include <functional>
#include <algorithm>
#include <functional>//std::less
#include <cstddef> //std::size_t
#include <utility> //std::pair
@ -2056,7 +2056,7 @@ inline bool operator<
( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
#endif
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
@ -2072,30 +2072,11 @@ bool operator==
#endif
{
typedef slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> slist_type;
typedef typename slist_type::const_iterator const_iterator;
const bool C = slist_type::constant_time_size;
if(C && x.size() != y.size()){
return false;
}
const_iterator end1 = x.end();
const_iterator i1 = x.begin();
const_iterator i2 = y.begin();
if(C){
while (i1 != end1 && *i1 == *i2) {
++i1;
++i2;
}
return i1 == end1;
}
else{
const_iterator end2 = y.end();
while (i1 != end1 && i2 != end2 && *i1 == *i2) {
++i1;
++i2;
}
return i1 == end1 && i2 == end2;
}
return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
}
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)

View File

@ -18,13 +18,8 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <algorithm>
#include <cstddef>
#include <functional>
#include <utility>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/intrusive/bs_set_hook.hpp>
#include <boost/intrusive/bstree.hpp>
#include <boost/intrusive/detail/tree_node.hpp>
@ -34,11 +29,19 @@
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/treap_algorithms.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/intrusive/priority_compare.hpp>
#include <boost/intrusive/detail/node_cloner_disposer.hpp>
#include <boost/intrusive/detail/key_nodeptr_comp.hpp>
#include <boost/static_assert.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/adl_move_swap.hpp>
#include <cstddef>
#include <functional>
#include <utility>
namespace boost {
namespace intrusive {
@ -329,8 +332,7 @@ class treap_impl
{
tree_type::swap(other);
//This can throw
using std::swap;
swap(this->priv_pcomp(), other.priv_pcomp());
::boost::adl_move_swap(this->priv_pcomp(), other.priv_pcomp());
}
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.

View File

@ -25,7 +25,6 @@
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/algo_type.hpp>
#include <boost/intrusive/bstree_algorithms.hpp>
#include <algorithm>
namespace boost {

View File

@ -232,6 +232,9 @@
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\algo_type.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\algorithm.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\any_node_and_algorithms.hpp">
</File>

View File

@ -20,6 +20,7 @@
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/move/adl_move_swap.hpp>
template < typename T >
class bounded_pointer;
@ -190,7 +191,7 @@ class bounded_reference
// the copy asop is shallow; we need swap overload to shuffle a vector of references
friend void swap(bounded_reference& lhs, bounded_reference& rhs)
{ std::swap(lhs.m_offset, rhs.m_offset); }
{ ::boost::adl_move_swap(lhs.m_offset, rhs.m_offset); }
private:
template <typename> friend class bounded_reference;

View File

@ -11,9 +11,10 @@
#ifndef BOOST_INTRUSIVE_SMART_PTR_HPP
#define BOOST_INTRUSIVE_SMART_PTR_HPP
#include <boost/iterator.hpp>
#include <boost/intrusive/pointer_plus_bits.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/iterator.hpp>
#include <boost/move/adl_move_swap.hpp>
#if (defined _MSC_VER)
# pragma once
@ -36,8 +37,7 @@ struct empty_type{};
template<class T>
struct random_it
: public boost::iterator<std::random_access_iterator_tag,
T, std::ptrdiff_t, T*, T&>
: public iterator<std::random_access_iterator_tag, T, std::ptrdiff_t, T*, T&>
{
typedef const T* const_pointer;
typedef const T& const_reference;
@ -190,6 +190,10 @@ class smart_ptr
//!Never throws.
bool operator! () const
{ return m_ptr == 0; }
//!swap
friend void swap(smart_ptr& x, smart_ptr& y)
{ boost::adl_move_swap(x.m_ptr, y.m_ptr); }
};
//!smart_ptr<T1> == smart_ptr<T2>. Never throws.
@ -250,16 +254,6 @@ template<class T, class T2>
inline std::ptrdiff_t operator- (const smart_ptr<T> &pt, const smart_ptr<T2> &pt2)
{ return pt.operator->()- pt2.operator->(); }
//!swap specialization
template<class T>
inline void swap (smart_ptr<T> &pt,
smart_ptr<T> &pt2)
{
typename smart_ptr<T>::value_type *ptr = pt.operator->();
pt = pt2;
pt2 = ptr;
}
} //namespace intrusive {
} //namespace boost {

View File

@ -17,7 +17,7 @@
#include "smart_ptr.hpp"
#include "common_functors.hpp"
#include <vector>
#include <algorithm> //std::sort std::find
#include <algorithm> //std::sort
#include <set>
#include <boost/detail/lightweight_test.hpp>