1 // Aleth: Ethereum C++ client, tools and libraries.
2 // Copyright 2014-2019 Aleth Authors.
3 // Licensed under the GNU General Public License, Version 3.
4 
5 #include <libdevcore/RangeMask.h>
6 
7 #include <gtest/gtest.h>
8 
9 using namespace std;
10 using namespace dev;
11 
TEST(RangeMask,constructor)12 TEST(RangeMask, constructor)
13 {
14     using RM = RangeMask;
15     using Range = pair<unsigned, unsigned>;
16     for (RM r : {RM(), RM(1, 10), RM(Range(2, 10))})
17     {
18         EXPECT_TRUE(r.empty());
19         EXPECT_FALSE(r.contains(0));
20         EXPECT_FALSE(r.contains(1));
21         EXPECT_EQ(0, r.size());
22     }
23     EXPECT_TRUE(RM().full());
24     EXPECT_FALSE(RM(1, 10).full());
25     EXPECT_FALSE(RM(Range(2, 10)).full());
26 }
27 
TEST(RangeMask,simpleUnions)28 TEST(RangeMask, simpleUnions)
29 {
30     using RM = RangeMask;
31     using Range = pair<unsigned, unsigned>;
32     RM m(Range(0, 2000));
33     m.unionWith(Range(1, 2));
34     EXPECT_EQ(m.size(), 1);
35     m.unionWith(Range(50, 250));
36     EXPECT_EQ(m.size(), 201);
37     m.unionWith(Range(10, 16));
38     EXPECT_EQ(m.size(), 207);
39     EXPECT_TRUE(m.contains(1));
40     EXPECT_TRUE(m.contains(11));
41     EXPECT_TRUE(m.contains(51));
42     EXPECT_TRUE(m.contains(200));
43     EXPECT_FALSE(m.contains(2));
44     EXPECT_FALSE(m.contains(7));
45     EXPECT_FALSE(m.contains(17));
46     EXPECT_FALSE(m.contains(258));
47 }
48 
TEST(RangeMask,emptyUnion)49 TEST(RangeMask, emptyUnion)
50 {
51     using RM = RangeMask;
52     using Range = pair<unsigned, unsigned>;
53     RM m(Range(0, 2000));
54     m.unionWith(Range(3, 6));
55     EXPECT_EQ(m.size(), 3);
56     m.unionWith(Range(50, 50));
57     EXPECT_EQ(m.size(), 3);
58     m.unionWith(Range(0, 0));
59     EXPECT_EQ(m.size(), 3);
60     m.unionWith(Range(1, 1));
61     EXPECT_EQ(m.size(), 3);
62     m.unionWith(Range(2, 2));
63     EXPECT_EQ(m.size(), 3);
64     m.unionWith(Range(3, 3));
65     EXPECT_EQ(m.size(), 3);
66 }
67 
TEST(RangeMask,overlappingUnions)68 TEST(RangeMask, overlappingUnions)
69 {
70     using RM = RangeMask;
71     using Range = pair<unsigned, unsigned>;
72     RM m(Range(0, 2000));
73     m.unionWith(Range(10, 20));
74     EXPECT_EQ(10, m.size());
75     m.unionWith(Range(30, 40));
76     EXPECT_EQ(20, m.size());
77     m.unionWith(Range(15, 30));
78     EXPECT_EQ(40 - 10, m.size());
79     m.unionWith(Range(50, 60));
80     m.unionWith(Range(45, 55));
81     // [40, 45) still missing here
82     EXPECT_EQ(60 - 10 - 5, m.size());
83     m.unionWith(Range(15, 56));
84     EXPECT_EQ(60 - 10, m.size());
85     m.unionWith(Range(15, 65));
86     EXPECT_EQ(65 - 10, m.size());
87     m.unionWith(Range(5, 70));
88     EXPECT_EQ(70 - 5, m.size());
89 }
90 
TEST(RangeMask,complement)91 TEST(RangeMask, complement)
92 {
93     using RM = RangeMask;
94     using Range = pair<unsigned, unsigned>;
95     RM m(Range(0, 2000));
96     m.unionWith(7).unionWith(9);
97     m = ~m;
98     m.unionWith(7).unionWith(9);
99     m = ~m;
100     EXPECT_TRUE(m.empty());
101 
102     m += Range(0, 10);
103     m += Range(1000, 2000);
104     m.invert();
105     EXPECT_EQ(m.size(), 1000 - 10);
106 }
107 
TEST(RangeMask,iterator)108 TEST(RangeMask, iterator)
109 {
110     using RM = RangeMask;
111     using Range = pair<unsigned, unsigned>;
112     RM m(Range(0, 2000));
113     m.unionWith(Range(7, 9));
114     m.unionWith(11);
115     m.unionWith(Range(200, 205));
116 
117     vector<unsigned> elements;
118     copy(m.begin(), m.end(), back_inserter(elements));
119     EXPECT_TRUE(elements == (vector<unsigned>{7, 8, 11, 200, 201, 202, 203, 204}));
120 }
121 
122