Refactored comparison functors to reuse compare_functors.hpp classes

This commit is contained in:
Ion Gaztañaga
2014-11-23 10:07:12 +01:00
parent 1d38ecfd10
commit d514c1ab66
10 changed files with 130 additions and 135 deletions

View File

@@ -20,7 +20,6 @@
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp>

View File

@@ -0,0 +1,70 @@
///////////////////////////////////////////////////////////////////////////////
//
// (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/container for documentation.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP
#define BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP
#if defined(_MSC_VER)
# pragma once
#endif
namespace boost {
namespace container {
template<class A>
class equal_to_value
{
typedef typename A::value_type value_type;
const value_type &t_;
public:
explicit equal_to_value(const value_type &t)
: t_(t)
{}
bool operator()(const value_type &t)const
{ return t_ == t; }
};
template<class Node, class Pred>
struct value_to_node_compare
: Pred
{
typedef Pred predicate_type;
typedef Node node_type;
value_to_node_compare()
: Pred()
{}
explicit value_to_node_compare(Pred pred)
: Pred(pred)
{}
bool operator()(const Node &a, const Node &b) const
{ return static_cast<const Pred&>(*this)(a.m_data, b.m_data); }
bool operator()(const Node &a) const
{ return static_cast<const Pred&>(*this)(a.m_data); }
bool operator()(const Node &a, const Node &b)
{ return static_cast<Pred&>(*this)(a.m_data, b.m_data); }
bool operator()(const Node &a)
{ return static_cast<Pred&>(*this)(a.m_data); }
predicate_type & predicate() { return static_cast<predicate_type&>(*this); }
const predicate_type & predicate() const { return static_cast<predicate_type&>(*this); }
};
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP

View File

@@ -79,7 +79,7 @@ BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assig
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_swap)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(wrapped_value_compare)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type)
} //namespace container_detail {
} //namespace container {

View File

@@ -47,33 +47,6 @@ namespace boost {
namespace container {
namespace container_detail {
template<class ValueCompare, class Node>
struct node_compare
: private ValueCompare
{
typedef ValueCompare wrapped_value_compare;
typedef typename wrapped_value_compare::key_type key_type;
typedef typename wrapped_value_compare::value_type value_type;
typedef typename wrapped_value_compare::key_of_value key_of_value;
explicit node_compare(const wrapped_value_compare &pred)
: wrapped_value_compare(pred)
{}
node_compare()
: wrapped_value_compare()
{}
wrapped_value_compare &value_comp()
{ return static_cast<wrapped_value_compare &>(*this); }
wrapped_value_compare &value_comp() const
{ return static_cast<const wrapped_value_compare &>(*this); }
bool operator()(const Node &a, const Node &b) const
{ return wrapped_value_compare::operator()(a.get_data(), b.get_data()); }
};
template<class A, class ICont>
struct node_alloc_holder
{
@@ -81,10 +54,10 @@ struct node_alloc_holder
//be of type node_compare<>. If not an associative container value_compare will be a "nat" type.
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, ICont,
value_compare, container_detail::nat) intrusive_value_compare;
//In that case obtain the value predicate from the node predicate via wrapped_value_compare
//In that case obtain the value predicate from the node predicate via predicate_type
//if intrusive_value_compare is node_compare<>, nat otherwise
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, ICont,
wrapped_value_compare, container_detail::nat) value_compare;
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, intrusive_value_compare,
predicate_type, container_detail::nat) value_compare;
typedef allocator_traits<A> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
@@ -133,11 +106,11 @@ struct node_alloc_holder
{ this->icont().swap(x.icont()); }
//Constructors for associative containers
explicit node_alloc_holder(const ValAlloc &a, const value_compare &c)
explicit node_alloc_holder(const value_compare &c, const ValAlloc &a)
: members_(a, c)
{}
explicit node_alloc_holder(const node_alloc_holder &x, const value_compare &c)
explicit node_alloc_holder(const value_compare &c, const node_alloc_holder &x)
: members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c)
{}

View File

@@ -21,14 +21,13 @@
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/node_alloc_holder.hpp>
#include <boost/container/detail/destroyers.hpp>
#include <boost/container/detail/pair.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/options.hpp>
#include <boost/container/detail/compare_functors.hpp>
//
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/rbtree.hpp>
@@ -94,6 +93,10 @@ struct tree_value_compare
template<class KeyType, class KeyType2>
bool operator()(const KeyType &key1, const KeyType2 &key2) const
{ return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
template<class KeyType, class KeyType2>
bool operator()(const KeyType &key1, const KeyType2 &key2)
{ return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
};
template<class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
@@ -327,7 +330,8 @@ struct intrusive_tree_type
typedef typename container_detail::tree_node
< value_type, void_pointer
, tree_type_value, OptimizeSize> node_type;
typedef node_compare<ValueCompare, node_type> node_compare_type;
typedef value_to_node_compare
<node_type, ValueCompare> node_compare_type;
//Deducing the hook type from node_type (e.g. node_type::hook_type) would
//provoke an early instantiation of node_type that could ruin recursive
//tree definitions, so retype the complete type to avoid any problem.
@@ -525,11 +529,11 @@ class tree
typedef container_detail::reverse_iterator<const_iterator> const_reverse_iterator;
tree()
: AllocHolder(ValComp(key_compare()))
: AllocHolder()
{}
explicit tree(const key_compare& comp, const allocator_type& a = allocator_type())
: AllocHolder(a, ValComp(comp))
: AllocHolder(ValComp(comp), a)
{}
explicit tree(const allocator_type& a)
@@ -546,7 +550,7 @@ class tree
>::type * = 0
#endif
)
: AllocHolder(a, value_compare(comp))
: AllocHolder(value_compare(comp), a)
{
//Use cend() as hint to achieve linear time for
//ordered ranges as required by the standard
@@ -574,7 +578,7 @@ class tree
>::type * = 0
#endif
)
: AllocHolder(a, value_compare(comp))
: AllocHolder(value_compare(comp), a)
{
if(unique_insertion){
//Use cend() as hint to achieve linear time for
@@ -603,7 +607,7 @@ class tree
>::type * = 0
#endif
)
: AllocHolder(a, value_compare(comp))
: AllocHolder(value_compare(comp), a)
{
for ( ; first != last; ++first){
this->push_back_impl(*first);
@@ -620,7 +624,7 @@ class tree
>::type * = 0
#endif
)
: AllocHolder(a, value_compare(comp))
: AllocHolder(value_compare(comp), a)
{
//Optimized allocation and construction
this->allocate_many_and_construct
@@ -629,25 +633,25 @@ class tree
}
tree(const tree& x)
: AllocHolder(x, x.value_comp())
: AllocHolder(x.value_comp(), x)
{
this->icont().clone_from
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
}
tree(BOOST_RV_REF(tree) x)
: AllocHolder(::boost::move(static_cast<AllocHolder&>(x)), x.value_comp())
: AllocHolder(BOOST_MOVE_BASE(AllocHolder, x), x.value_comp())
{}
tree(const tree& x, const allocator_type &a)
: AllocHolder(a, x.value_comp())
: AllocHolder(x.value_comp(), a)
{
this->icont().clone_from
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
}
tree(BOOST_RV_REF(tree) x, const allocator_type &a)
: AllocHolder(a, x.value_comp())
: AllocHolder(x.value_comp(), a)
{
if(this->node_alloc() == x.node_alloc()){
this->icont().swap(x.icont());
@@ -735,10 +739,10 @@ class tree
public:
// accessors:
value_compare value_comp() const
{ return this->icont().value_comp().value_comp(); }
{ return this->icont().value_comp().predicate(); }
key_compare key_comp() const
{ return this->icont().value_comp().value_comp().key_comp(); }
{ return this->icont().value_comp().predicate().key_comp(); }
allocator_type get_allocator() const
{ return allocator_type(this->node_alloc()); }

View File

@@ -27,7 +27,7 @@
#include <boost/move/traits.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/compare_functors.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/assert.hpp>
#include <boost/container/detail/node_alloc_holder.hpp>
@@ -145,35 +145,7 @@ class list
typedef typename AllocHolder::allocator_v2 allocator_v2;
typedef typename AllocHolder::alloc_version alloc_version;
typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
class equal_to_value
{
typedef typename AllocHolder::value_type value_type;
const value_type &t_;
public:
equal_to_value(const value_type &t)
: t_(t)
{}
bool operator()(const value_type &t)const
{ return t_ == t; }
};
template<class Pred>
struct ValueCompareToNodeCompare
: Pred
{
ValueCompareToNodeCompare(Pred pred)
: Pred(pred)
{}
bool operator()(const Node &a, const Node &b) const
{ return static_cast<const Pred&>(*this)(a.m_data, b.m_data); }
bool operator()(const Node &a) const
{ return static_cast<const Pred&>(*this)(a.m_data); }
};
typedef boost::container::equal_to_value<Allocator> equal_to_value_type;
BOOST_COPYABLE_AND_MOVABLE(list)
@@ -1139,7 +1111,7 @@ class list
//! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
void remove(const T& value)
{ this->remove_if(equal_to_value(value)); }
{ this->remove_if(equal_to_value_type(value)); }
//! <b>Effects</b>: Removes all the elements for which a specified
//! predicate is satisfied.
@@ -1153,8 +1125,8 @@ class list
template <class Pred>
void remove_if(Pred pred)
{
typedef ValueCompareToNodeCompare<Pred> Predicate;
this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
typedef value_to_node_compare<Node, Pred> value_to_node_compare_type;
this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
}
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
@@ -1181,8 +1153,8 @@ class list
template <class BinaryPredicate>
void unique(BinaryPredicate binary_pred)
{
typedef ValueCompareToNodeCompare<BinaryPredicate> Predicate;
this->icont().unique_and_dispose(Predicate(binary_pred), Destroyer(this->node_alloc()));
typedef value_to_node_compare<Node, BinaryPredicate> value_to_node_compare_type;
this->icont().unique_and_dispose(value_to_node_compare_type(binary_pred), Destroyer(this->node_alloc()));
}
//! <b>Requires</b>: The lists x and *this must be distinct.
@@ -1231,8 +1203,8 @@ class list
void merge(list &x, const StrictWeakOrdering &comp)
{
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().merge(x.icont(),
ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
this->icont().merge(x.icont(), value_to_node_compare_type(comp));
}
//! <b>Requires</b>: p must be a comparison function that induces a strict weak
@@ -1280,7 +1252,8 @@ class list
// nothing if the list has length 0 or 1.
if (this->size() < 2)
return;
this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
this->icont().sort(value_to_node_compare_type(comp));
}
//! <b>Effects</b>: Reverses the order of elements in the list.

View File

@@ -30,6 +30,7 @@
#include <boost/container/detail/type_traits.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/container/detail/node_alloc_holder.hpp>
#include <boost/container/detail/compare_functors.hpp>
#include <boost/intrusive/slist.hpp>
#include <iterator>
@@ -175,36 +176,9 @@ class slist
typedef typename AllocHolder::allocator_v1 allocator_v1;
typedef typename AllocHolder::allocator_v2 allocator_v2;
typedef typename AllocHolder::alloc_version alloc_version;
typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
class equal_to_value
{
typedef typename AllocHolder::value_type value_type;
const value_type &t_;
public:
equal_to_value(const value_type &t)
: t_(t)
{}
bool operator()(const value_type &t)const
{ return t_ == t; }
};
template<class Pred>
struct ValueCompareToNodeCompare
: Pred
{
ValueCompareToNodeCompare(Pred pred)
: Pred(pred)
{}
bool operator()(const Node &a, const Node &b) const
{ return static_cast<const Pred&>(*this)(a.m_data, b.m_data); }
bool operator()(const Node &a) const
{ return static_cast<const Pred&>(*this)(a.m_data); }
};
typedef boost::container::
allocator_traits<Allocator> allocator_traits_type;
typedef boost::container::equal_to_value<Allocator> equal_to_value_type;
BOOST_COPYABLE_AND_MOVABLE(slist)
typedef container_detail::iterator<typename Icont::iterator, false> iterator_impl;
@@ -1134,7 +1108,7 @@ class slist
//! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
void remove(const T& value)
{ this->remove_if(equal_to_value(value)); }
{ this->remove_if(equal_to_value_type(value)); }
//! <b>Effects</b>: Removes all the elements for which a specified
//! predicate is satisfied.
@@ -1148,8 +1122,8 @@ class slist
template <class Pred>
void remove_if(Pred pred)
{
typedef ValueCompareToNodeCompare<Pred> Predicate;
this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
typedef value_to_node_compare<Node, Pred> value_to_node_compare_type;
this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
}
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
@@ -1176,8 +1150,8 @@ class slist
template <class Pred>
void unique(Pred pred)
{
typedef ValueCompareToNodeCompare<Pred> Predicate;
this->icont().unique_and_dispose(Predicate(pred), Destroyer(this->node_alloc()));
typedef value_to_node_compare<Node, Pred> value_to_node_compare_type;
this->icont().unique_and_dispose(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
}
//! <b>Requires</b>: The lists x and *this must be distinct.
@@ -1225,9 +1199,9 @@ class slist
template <class StrictWeakOrdering>
void merge(slist& x, StrictWeakOrdering comp)
{
typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().merge(x.icont(),
ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
this->icont().merge(x.icont(), value_to_node_compare_type(comp));
}
//! <b>Requires</b>: p must be a comparison function that induces a strict weak
@@ -1272,10 +1246,11 @@ class slist
template <class StrictWeakOrdering>
void sort(StrictWeakOrdering comp)
{
typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
// nothing if the slist has length 0 or 1.
if (this->size() < 2)
return;
this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
this->icont().sort(value_to_node_compare_type(comp));
}
//! <b>Effects</b>: Reverses the order of elements in the list.

View File

@@ -23,7 +23,6 @@
#include <boost/container/throw_exception.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/allocation_type.hpp>
#include <boost/container/allocator_traits.hpp>

View File

@@ -39,7 +39,6 @@
#include <boost/container/detail/allocation_type.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/destroyers.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/allocator_version_traits.hpp>

View File

@@ -191,6 +191,9 @@
<File
RelativePath="..\..\..\..\boost\container\detail\boost_cont_ext_auto_link.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\compare_functors.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\config_begin.hpp">
</File>