Improved unique associative container count function. Improved also flat_xxx's equal_range.

This commit is contained in:
Ion Gaztañaga
2014-01-19 19:18:57 +01:00
parent 6d6656fcc1
commit abc50c7275
5 changed files with 55 additions and 32 deletions

View File

@@ -717,6 +717,7 @@ class flat_tree
return i; return i;
} }
// set operations:
size_type count(const key_type& k) const size_type count(const key_type& k) const
{ {
std::pair<const_iterator, const_iterator> p = this->equal_range(k); std::pair<const_iterator, const_iterator> p = this->equal_range(k);
@@ -875,7 +876,7 @@ class flat_tree
} }
template <class RanIt> template <class RanIt>
RanIt priv_lower_bound(RanIt first, RanIt last, RanIt priv_lower_bound(RanIt first, const RanIt last,
const key_type & key) const const key_type & key) const
{ {
const Compare &key_cmp = this->m_data.get_comp(); const Compare &key_cmp = this->m_data.get_comp();
@@ -884,24 +885,23 @@ class flat_tree
RanIt middle; RanIt middle;
while (len) { while (len) {
size_type half = len >> 1; size_type step = len >> 1;
middle = first; middle = first;
middle += half; middle += step;
if (key_cmp(key_extract(*middle), key)) { if (key_cmp(key_extract(*middle), key)) {
++middle; first = ++middle;
first = middle; len -= step + 1;
len = len - half - 1; }
else{
len = step;
} }
else
len = half;
} }
return first; return first;
} }
template <class RanIt> template <class RanIt>
RanIt priv_upper_bound(RanIt first, RanIt last, RanIt priv_upper_bound(RanIt first, const RanIt last,
const key_type & key) const const key_type & key) const
{ {
const Compare &key_cmp = this->m_data.get_comp(); const Compare &key_cmp = this->m_data.get_comp();
@@ -910,16 +910,16 @@ class flat_tree
RanIt middle; RanIt middle;
while (len) { while (len) {
size_type half = len >> 1; size_type step = len >> 1;
middle = first; middle = first;
middle += half; middle += step;
if (key_cmp(key, key_extract(*middle))) { if (key_cmp(key, key_extract(*middle))) {
len = half; len = step;
} }
else{ else{
first = ++middle; first = ++middle;
len = len - half - 1; len -= step + 1;
} }
} }
return first; return first;
@@ -935,24 +935,24 @@ class flat_tree
RanIt middle; RanIt middle;
while (len) { while (len) {
size_type half = len >> 1; size_type step = len >> 1;
middle = first; middle = first;
middle += half; middle += step;
if (key_cmp(key_extract(*middle), key)){ if (key_cmp(key_extract(*middle), key)){
first = middle; first = ++middle;
++first; len -= step + 1;
len = len - half - 1;
} }
else if (key_cmp(key, key_extract(*middle))){ else if (key_cmp(key, key_extract(*middle))){
len = half; len = step;
} }
else { else {
//Middle is equal to key //Middle is equal to key
last = first; last = first;
last += len; last += len;
first = this->priv_lower_bound(first, middle, key); return std::pair<RanIt, RanIt>
return std::pair<RanIt, RanIt> (first, this->priv_upper_bound(++middle, last, key)); ( this->priv_lower_bound(first, middle, key)
, this->priv_upper_bound(++middle, last, key));
} }
} }
return std::pair<RanIt, RanIt>(first, first); return std::pair<RanIt, RanIt>(first, first);

View File

@@ -287,7 +287,7 @@ struct intrusive_tree_dispatch
<NodeType <NodeType
,container_detail::bi::compare<NodeCompareType> ,container_detail::bi::compare<NodeCompareType>
,container_detail::bi::base_hook<HookType> ,container_detail::bi::base_hook<HookType>
,container_detail::bi::constant_time_size<true> ,container_detail::bi::floating_point<true>
,container_detail::bi::size_type<SizeType> ,container_detail::bi::size_type<SizeType>
>::type type; >::type type;
}; };

View File

@@ -575,7 +575,7 @@ class flat_set
//! //!
//! <b>Complexity</b>: log(size())+count(k) //! <b>Complexity</b>: log(size())+count(k)
size_type count(const key_type& x) const size_type count(const key_type& x) const
{ return static_cast<size_type>(this->find(x) != this->cend()); } { return static_cast<size_type>(this->base_t::find(x) != this->base_t::cend()); }
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Returns</b>: An iterator pointing to the first element with key not less //! <b>Returns</b>: An iterator pointing to the first element with key not less
@@ -602,15 +602,34 @@ class flat_set
//! <b>Complexity</b>: Logarithmic //! <b>Complexity</b>: Logarithmic
const_iterator upper_bound(const key_type& x) const; const_iterator upper_bound(const key_type& x) const;
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//!
//! <b>Complexity</b>: Logarithmic
std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//! //!
//! <b>Complexity</b>: Logarithmic //! <b>Complexity</b>: Logarithmic
std::pair<iterator,iterator> equal_range(const key_type& x); std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
{
const_iterator lb = this->lower_bound(x), ub(lb);
if(lb != this->cend() && static_cast<difference_type>(!this->key_comp()(x, *lb))){
++ub;
}
return std::pair<const_iterator, const_iterator>(lb, ub);
}
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic
std::pair<iterator,iterator> equal_range(const key_type& x)
{
iterator lb = this->lower_bound(x), ub(lb);
if(lb != this->end() && static_cast<difference_type>(!this->key_comp()(x, *lb))){
++ub;
}
return std::pair<iterator, iterator>(lb, ub);
}
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Returns true if x and y are equal //! <b>Effects</b>: Returns true if x and y are equal
//! //!

View File

@@ -506,7 +506,13 @@ class set
//! //!
//! <b>Complexity</b>: log(size())+count(k) //! <b>Complexity</b>: log(size())+count(k)
size_type count(const key_type& x) const size_type count(const key_type& x) const
{ return static_cast<size_type>(this->find(x) != this->cend()); } { return static_cast<size_type>(this->base_t::find(x) != this->base_t::cend()); }
//! <b>Returns</b>: The number of elements with key equivalent to x.
//!
//! <b>Complexity</b>: log(size())+count(k)
size_type count(const key_type& x)
{ return static_cast<size_type>(this->base_t::find(x) != this->base_t::end()); }
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)

View File

@@ -508,7 +508,6 @@ int set_test ()
typename MyBoostSet::iterator bs_b = boostset->begin(); typename MyBoostSet::iterator bs_b = boostset->begin();
typename MyBoostSet::iterator bs_e = boostset->end(); typename MyBoostSet::iterator bs_e = boostset->end();
typename MyStdSet::iterator ss_b = stdset->begin(); typename MyStdSet::iterator ss_b = stdset->begin();
typename MyStdSet::iterator ss_e = stdset->end();
std::size_t i = 0; std::size_t i = 0;
while(bs_b != bs_e){ while(bs_b != bs_e){
@@ -555,7 +554,6 @@ int set_test ()
typename MyBoostMultiSet::iterator bm_b = boostmultiset->begin(); typename MyBoostMultiSet::iterator bm_b = boostmultiset->begin();
typename MyBoostMultiSet::iterator bm_e = boostmultiset->end(); typename MyBoostMultiSet::iterator bm_e = boostmultiset->end();
typename MyStdMultiSet::iterator sm_b = stdmultiset->begin(); typename MyStdMultiSet::iterator sm_b = stdmultiset->begin();
typename MyStdMultiSet::iterator sm_e = stdmultiset->end();
while(bm_b != bm_e){ while(bm_b != bm_e){
typename MyBoostMultiSet::iterator bm_i; typename MyBoostMultiSet::iterator bm_i;