155 lines
4.5 KiB
C++
155 lines
4.5 KiB
C++
/* Boost.MultiIndex test for rank operations.
|
|
*
|
|
* Copyright 2003-2017 Joaquin M Lopez Munoz.
|
|
* 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/multi_index for library home page.
|
|
*/
|
|
|
|
#include "test_rank_ops.hpp"
|
|
|
|
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
|
#include <algorithm>
|
|
#include <iterator>
|
|
#include <set>
|
|
#include <boost/detail/lightweight_test.hpp>
|
|
#include "pre_multi_index.hpp"
|
|
#include <boost/multi_index_container.hpp>
|
|
#include <boost/multi_index/identity.hpp>
|
|
#include <boost/multi_index/ranked_index.hpp>
|
|
|
|
using namespace boost::multi_index;
|
|
|
|
template<
|
|
typename Sequence1,typename Iterator2,typename Sequence2
|
|
>
|
|
bool same_position(
|
|
std::size_t n1,const Sequence1& s1,Iterator2 it2,const Sequence2& s2)
|
|
{
|
|
typedef typename Sequence1::const_iterator const_iterator1;
|
|
typedef typename Sequence2::const_iterator const_iterator2;
|
|
|
|
const_iterator1 cit1=s1.begin();
|
|
std::advance(cit1,n1);
|
|
const_iterator2 cit2=it2;
|
|
return std::distance(s1.begin(),cit1)==std::distance(s2.begin(),cit2);
|
|
}
|
|
|
|
struct less_equal_than
|
|
{
|
|
less_equal_than(int n_):n(n_){}
|
|
bool operator()(int x)const{return x<=n;}
|
|
int n;
|
|
};
|
|
|
|
struct greater_equal_than
|
|
{
|
|
greater_equal_than(int n_):n(n_){}
|
|
bool operator()(int x)const{return x>=n;}
|
|
int n;
|
|
};
|
|
|
|
template<typename Sequence>
|
|
static void local_test_rank_ops()
|
|
{
|
|
int data[]={2,2,1,5,6,7,9,10,9,6,9,6,9};
|
|
Sequence s(data,data+sizeof(data)/sizeof(data[0]));
|
|
std::multiset<int> ss(s.begin(),s.end());
|
|
|
|
typedef typename Sequence::iterator iterator;
|
|
|
|
iterator it=s.begin();
|
|
for(std::size_t n=0;n<=s.size()+1;++n){
|
|
BOOST_TEST(s.nth(n)==it);
|
|
BOOST_TEST(s.rank(it)==(std::min)(s.size(),n));
|
|
if(it!=s.end())++it;
|
|
}
|
|
|
|
std::pair<std::size_t,std::size_t> p1;
|
|
std::pair<iterator,iterator> p2;
|
|
|
|
p1=s.range_rank(unbounded,unbounded);
|
|
p2=s.range(unbounded,unbounded);
|
|
BOOST_TEST(same_position(p1.first,s,p2.first,s));
|
|
BOOST_TEST(same_position(p1.second,s,p2.second,s));
|
|
|
|
for(int i=0;i<12;++i){
|
|
std::size_t pos=s.find_rank(i);
|
|
BOOST_TEST((pos==s.size()&&ss.find(i)==ss.end())||(*s.nth(pos)==i));
|
|
BOOST_TEST(same_position(s.lower_bound_rank(i),s,ss.lower_bound(i),ss));
|
|
BOOST_TEST(same_position(s.upper_bound_rank(i),s,ss.upper_bound(i),ss));
|
|
std::pair<std::size_t,std::size_t> posp=s.equal_range_rank(i);
|
|
BOOST_TEST(same_position(posp.first,s,ss.lower_bound(i),ss));
|
|
BOOST_TEST(same_position(posp.second,s,ss.upper_bound(i),ss));
|
|
|
|
p1=s.range_rank(greater_equal_than(i),unbounded);
|
|
p2=s.range(greater_equal_than(i),unbounded);
|
|
BOOST_TEST(same_position(p1.first,s,p2.first,s));
|
|
BOOST_TEST(same_position(p1.second,s,p2.second,s));
|
|
p1=s.range_rank(unbounded,less_equal_than(i));
|
|
p2=s.range(unbounded,less_equal_than(i));
|
|
BOOST_TEST(same_position(p1.first,s,p2.first,s));
|
|
BOOST_TEST(same_position(p1.second,s,p2.second,s));
|
|
|
|
for(int j=0;j<12;++j){
|
|
p1=s.range_rank(greater_equal_than(i),less_equal_than(j));
|
|
p2=s.range(greater_equal_than(i),less_equal_than(j));
|
|
BOOST_TEST(same_position(p1.first,s,p2.first,s));
|
|
BOOST_TEST(same_position(p1.second,s,p2.second,s));
|
|
}
|
|
}
|
|
|
|
Sequence se; /* empty */
|
|
BOOST_TEST(se.nth(0)==se.end());
|
|
BOOST_TEST(se.nth(1)==se.end());
|
|
BOOST_TEST(se.rank(se.end())==0);
|
|
BOOST_TEST(se.find_rank(0)==0);
|
|
BOOST_TEST(se.lower_bound_rank(0)==0);
|
|
BOOST_TEST(se.upper_bound_rank(0)==0);
|
|
p1=se.equal_range_rank(0);
|
|
BOOST_TEST(p1.first==0&&p1.second==0);
|
|
p1=se.range_rank(unbounded,unbounded);
|
|
BOOST_TEST(p1.first==0&&p1.second==0);
|
|
p1=se.range_rank(greater_equal_than(0),unbounded);
|
|
BOOST_TEST(p1.first==0&&p1.second==0);
|
|
p1=se.range_rank(unbounded,less_equal_than(0));
|
|
BOOST_TEST(p1.first==0&&p1.second==0);
|
|
p1=se.range_rank(greater_equal_than(0),less_equal_than(0));
|
|
BOOST_TEST(p1.first==0&&p1.second==0);
|
|
}
|
|
|
|
void test_rank_ops()
|
|
{
|
|
typedef multi_index_container<
|
|
int,
|
|
indexed_by<
|
|
ranked_unique<identity<int> >
|
|
>
|
|
> ranked_set;
|
|
|
|
local_test_rank_ops<ranked_set>();
|
|
|
|
typedef multi_index_container<
|
|
int,
|
|
indexed_by<
|
|
ranked_non_unique<identity<int> >
|
|
>
|
|
> ranked_multiset;
|
|
|
|
local_test_rank_ops<ranked_multiset>();
|
|
|
|
/* testcase for https://svn.boost.org/trac/boost/ticket/12955 */
|
|
|
|
typedef multi_index_container<
|
|
int,
|
|
indexed_by<
|
|
ranked_unique<identity<int> >,
|
|
ranked_non_unique<identity<int> >
|
|
>
|
|
> biranked_set;
|
|
|
|
local_test_rank_ops<biranked_set>();
|
|
}
|