148 lines · cpp
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-exception6//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 about13// what we're iterating over, that it's only enabled when given the relevant14// option, and it can be fed into various iteration utilities.15 16using namespace llvm;17 18namespace {19 20class dummy;21 22struct Node : ilist_node<Node, ilist_iterator_bits<true>> {23 friend class dummy;24};25 26struct PlainNode : ilist_node<PlainNode> {27 friend class dummy;28};29 30class Parent {};31struct ParentNode32 : ilist_node<ParentNode, ilist_iterator_bits<true>, ilist_parent<Parent>> {33};34 35TEST(IListIteratorBitsTest, DefaultConstructor) {36 simple_ilist<Node, ilist_iterator_bits<true>>::iterator I;37 simple_ilist<Node, ilist_iterator_bits<true>>::reverse_iterator RI;38 simple_ilist<Node, ilist_iterator_bits<true>>::const_iterator CI;39 simple_ilist<Node, ilist_iterator_bits<true>>::const_reverse_iterator CRI;40 EXPECT_EQ(nullptr, I.getNodePtr());41 EXPECT_EQ(nullptr, CI.getNodePtr());42 EXPECT_EQ(nullptr, RI.getNodePtr());43 EXPECT_EQ(nullptr, CRI.getNodePtr());44 EXPECT_EQ(I, I);45 EXPECT_EQ(I, CI);46 EXPECT_EQ(CI, I);47 EXPECT_EQ(CI, CI);48 EXPECT_EQ(RI, RI);49 EXPECT_EQ(RI, CRI);50 EXPECT_EQ(CRI, RI);51 EXPECT_EQ(CRI, CRI);52 EXPECT_EQ(I, RI.getReverse());53 EXPECT_EQ(RI, I.getReverse());54}55 56TEST(IListIteratorBitsTest, ConsAndAssignment) {57 simple_ilist<Node, ilist_iterator_bits<true>> L;58 Node A;59 L.insert(L.end(), A);60 61 simple_ilist<Node, ilist_iterator_bits<true>>::iterator I, I2;62 63 // Check that HeadInclusiveBit and TailInclusiveBit are preserved on64 // assignment and copy construction, but not on other operations.65 I = L.begin();66 EXPECT_FALSE(I.getHeadBit());67 EXPECT_FALSE(I.getTailBit());68 I.setHeadBit(true);69 I.setTailBit(true);70 EXPECT_TRUE(I.getHeadBit());71 EXPECT_TRUE(I.getTailBit());72 73 ++I;74 75 EXPECT_FALSE(I.getHeadBit());76 EXPECT_FALSE(I.getTailBit());77 78 I = L.begin();79 I.setHeadBit(true);80 I.setTailBit(true);81 I2 = I;82 EXPECT_TRUE(I2.getHeadBit());83 EXPECT_TRUE(I2.getTailBit());84 85 I = L.begin();86 I.setHeadBit(true);87 I.setTailBit(true);88 simple_ilist<Node, ilist_iterator_bits<true>>::iterator I3(I);89 EXPECT_TRUE(I3.getHeadBit());90 EXPECT_TRUE(I3.getTailBit());91}92 93class dummy {94 // Test that we get an ilist_iterator_w_bits out of the node given that the95 // options are enabled.96 using node_options =97 ilist_detail::compute_node_options<Node, ilist_iterator_bits<true>>::type;98 static_assert(std::is_same<Node::self_iterator,99 llvm::ilist_iterator_w_bits<node_options, false,100 false>>::value);101 102 // Now test that a plain node, without the option, gets a plain103 // ilist_iterator.104 using plain_node_options =105 ilist_detail::compute_node_options<PlainNode>::type;106 static_assert(std::is_same<107 PlainNode::self_iterator,108 llvm::ilist_iterator<plain_node_options, false, false>>::value);109};110 111TEST(IListIteratorBitsTest, RangeIteration) {112 // Check that we can feed ilist_iterator_w_bits into make_range and similar.113 // Plus, we should be able to convert it to a reverse iterator and use that.114 simple_ilist<Node, ilist_iterator_bits<true>> L;115 Node A;116 L.insert(L.end(), A);117 118 for (Node &N : make_range(L.begin(), L.end()))119 (void)N;120 121 simple_ilist<Node, ilist_iterator_bits<true>>::iterator It =122 L.begin()->getIterator();123 auto RevIt = It.getReverse();124 125 for (Node &N : make_range(RevIt, L.rend()))126 (void)N;127}128 129TEST(IListIteratorBitsTest, GetParent) {130 simple_ilist<ParentNode, ilist_iterator_bits<true>, ilist_parent<Parent>> L;131 Parent P;132 ParentNode A;133 134 // Parents are not set automatically.135 A.setParent(&P);136 L.insert(L.end(), A);137 L.end().getNodePtr()->setParent(&P);138 139 // Check we can get the node parent from all iterators, including for the140 // sentinel.141 EXPECT_EQ(&P, L.begin().getNodeParent());142 EXPECT_EQ(&P, L.end().getNodeParent());143 EXPECT_EQ(&P, L.rbegin().getNodeParent());144 EXPECT_EQ(&P, L.rend().getNodeParent());145}146 147} // end namespace148