1 | //==- unittests/ADT/IListIteratorBitsTest.cpp - ilist_iterator_w_bits tests -=// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/ADT/simple_ilist.h" |
10 | #include "gtest/gtest.h" |
11 | |
12 | // Test that ilist_iterator_w_bits can be used to store extra information about |
13 | // what we're iterating over, that it's only enabled when given the relevant |
14 | // option, and it can be fed into various iteration utilities. |
15 | |
16 | using namespace llvm; |
17 | |
18 | namespace { |
19 | |
20 | class dummy; |
21 | |
22 | struct Node : ilist_node<Node, ilist_iterator_bits<true>> { |
23 | friend class dummy; |
24 | }; |
25 | |
26 | struct PlainNode : ilist_node<PlainNode> { |
27 | friend class dummy; |
28 | }; |
29 | |
30 | TEST(IListIteratorBitsTest, DefaultConstructor) { |
31 | simple_ilist<Node, ilist_iterator_bits<true>>::iterator I; |
32 | simple_ilist<Node, ilist_iterator_bits<true>>::reverse_iterator RI; |
33 | simple_ilist<Node, ilist_iterator_bits<true>>::const_iterator CI; |
34 | simple_ilist<Node, ilist_iterator_bits<true>>::const_reverse_iterator CRI; |
35 | EXPECT_EQ(nullptr, I.getNodePtr()); |
36 | EXPECT_EQ(nullptr, CI.getNodePtr()); |
37 | EXPECT_EQ(nullptr, RI.getNodePtr()); |
38 | EXPECT_EQ(nullptr, CRI.getNodePtr()); |
39 | EXPECT_EQ(I, I); |
40 | EXPECT_EQ(I, CI); |
41 | EXPECT_EQ(CI, I); |
42 | EXPECT_EQ(CI, CI); |
43 | EXPECT_EQ(RI, RI); |
44 | EXPECT_EQ(RI, CRI); |
45 | EXPECT_EQ(CRI, RI); |
46 | EXPECT_EQ(CRI, CRI); |
47 | EXPECT_EQ(I, RI.getReverse()); |
48 | EXPECT_EQ(RI, I.getReverse()); |
49 | } |
50 | |
51 | TEST(IListIteratorBitsTest, ConsAndAssignment) { |
52 | simple_ilist<Node, ilist_iterator_bits<true>> L; |
53 | Node A; |
54 | L.insert(I: L.end(), Node&: A); |
55 | |
56 | simple_ilist<Node, ilist_iterator_bits<true>>::iterator I, I2; |
57 | |
58 | // Check that HeadInclusiveBit and TailInclusiveBit are preserved on |
59 | // assignment and copy construction, but not on other operations. |
60 | I = L.begin(); |
61 | EXPECT_FALSE(I.getHeadBit()); |
62 | EXPECT_FALSE(I.getTailBit()); |
63 | I.setHeadBit(true); |
64 | I.setTailBit(true); |
65 | EXPECT_TRUE(I.getHeadBit()); |
66 | EXPECT_TRUE(I.getTailBit()); |
67 | |
68 | ++I; |
69 | |
70 | EXPECT_FALSE(I.getHeadBit()); |
71 | EXPECT_FALSE(I.getTailBit()); |
72 | |
73 | I = L.begin(); |
74 | I.setHeadBit(true); |
75 | I.setTailBit(true); |
76 | I2 = I; |
77 | EXPECT_TRUE(I2.getHeadBit()); |
78 | EXPECT_TRUE(I2.getTailBit()); |
79 | |
80 | I = L.begin(); |
81 | I.setHeadBit(true); |
82 | I.setTailBit(true); |
83 | simple_ilist<Node, ilist_iterator_bits<true>>::iterator I3(I); |
84 | EXPECT_TRUE(I3.getHeadBit()); |
85 | EXPECT_TRUE(I3.getTailBit()); |
86 | } |
87 | |
88 | class dummy { |
89 | // Test that we get an ilist_iterator_w_bits out of the node given that the |
90 | // options are enabled. |
91 | using node_options = typename ilist_detail::compute_node_options< |
92 | Node, ilist_iterator_bits<true>>::type; |
93 | static_assert(std::is_same<Node::self_iterator, |
94 | llvm::ilist_iterator_w_bits<node_options, false, |
95 | false>>::value); |
96 | |
97 | // Now test that a plain node, without the option, gets a plain |
98 | // ilist_iterator. |
99 | using plain_node_options = |
100 | typename ilist_detail::compute_node_options<PlainNode>::type; |
101 | static_assert(std::is_same< |
102 | PlainNode::self_iterator, |
103 | llvm::ilist_iterator<plain_node_options, false, false>>::value); |
104 | }; |
105 | |
106 | TEST(IListIteratorBitsTest, RangeIteration) { |
107 | // Check that we can feed ilist_iterator_w_bits into make_range and similar. |
108 | // Plus, we should be able to convert it to a reverse iterator and use that. |
109 | simple_ilist<Node, ilist_iterator_bits<true>> L; |
110 | Node A; |
111 | L.insert(I: L.end(), Node&: A); |
112 | |
113 | for (Node &N : make_range(x: L.begin(), y: L.end())) |
114 | (void)N; |
115 | |
116 | simple_ilist<Node, ilist_iterator_bits<true>>::iterator It = |
117 | L.begin()->getIterator(); |
118 | auto RevIt = It.getReverse(); |
119 | |
120 | for (Node &N : make_range(x: RevIt, y: L.rend())) |
121 | (void)N; |
122 | } |
123 | |
124 | } // end namespace |
125 | |