File: test_rank_ops.cpp

package info (click to toggle)
boost1.90 1.90.0-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 593,120 kB
  • sloc: cpp: 4,190,908; xml: 196,648; python: 34,618; ansic: 23,145; asm: 5,468; sh: 3,774; makefile: 1,161; perl: 1,020; sql: 728; ruby: 676; yacc: 478; java: 77; lisp: 24; csh: 6
file content (154 lines) | stat: -rw-r--r-- 4,654 bytes parent folder | download | duplicates (17)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/* 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>();
}