//==- unittests/ADT/IListIteratorBitsTest.cpp - ilist_iterator_w_bits tests -=//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/simple_ilist.h"
#include "gtest/gtest.h"

// Test that ilist_iterator_w_bits can be used to store extra information about
// what we're iterating over, that it's only enabled when given the relevant
// option, and it can be fed into various iteration utilities.

using namespace llvm;

namespace {

class dummy;

struct Node : ilist_node<Node, ilist_iterator_bits<true>> {
  friend class dummy;
};

struct PlainNode : ilist_node<PlainNode> {
  friend class dummy;
};

class Parent {};
struct ParentNode
    : ilist_node<ParentNode, ilist_iterator_bits<true>, ilist_parent<Parent>> {
};

TEST(IListIteratorBitsTest, DefaultConstructor) {
  simple_ilist<Node, ilist_iterator_bits<true>>::iterator I;
  simple_ilist<Node, ilist_iterator_bits<true>>::reverse_iterator RI;
  simple_ilist<Node, ilist_iterator_bits<true>>::const_iterator CI;
  simple_ilist<Node, ilist_iterator_bits<true>>::const_reverse_iterator CRI;
  EXPECT_EQ(nullptr, I.getNodePtr());
  EXPECT_EQ(nullptr, CI.getNodePtr());
  EXPECT_EQ(nullptr, RI.getNodePtr());
  EXPECT_EQ(nullptr, CRI.getNodePtr());
  EXPECT_EQ(I, I);
  EXPECT_EQ(I, CI);
  EXPECT_EQ(CI, I);
  EXPECT_EQ(CI, CI);
  EXPECT_EQ(RI, RI);
  EXPECT_EQ(RI, CRI);
  EXPECT_EQ(CRI, RI);
  EXPECT_EQ(CRI, CRI);
  EXPECT_EQ(I, RI.getReverse());
  EXPECT_EQ(RI, I.getReverse());
}

TEST(IListIteratorBitsTest, ConsAndAssignment) {
  simple_ilist<Node, ilist_iterator_bits<true>> L;
  Node A;
  L.insert(L.end(), A);

  simple_ilist<Node, ilist_iterator_bits<true>>::iterator I, I2;

  // Check that HeadInclusiveBit and TailInclusiveBit are preserved on
  // assignment and copy construction, but not on other operations.
  I = L.begin();
  EXPECT_FALSE(I.getHeadBit());
  EXPECT_FALSE(I.getTailBit());
  I.setHeadBit(true);
  I.setTailBit(true);
  EXPECT_TRUE(I.getHeadBit());
  EXPECT_TRUE(I.getTailBit());

  ++I;

  EXPECT_FALSE(I.getHeadBit());
  EXPECT_FALSE(I.getTailBit());

  I = L.begin();
  I.setHeadBit(true);
  I.setTailBit(true);
  I2 = I;
  EXPECT_TRUE(I2.getHeadBit());
  EXPECT_TRUE(I2.getTailBit());

  I = L.begin();
  I.setHeadBit(true);
  I.setTailBit(true);
  simple_ilist<Node, ilist_iterator_bits<true>>::iterator I3(I);
  EXPECT_TRUE(I3.getHeadBit());
  EXPECT_TRUE(I3.getTailBit());
}

class dummy {
  // Test that we get an ilist_iterator_w_bits out of the node given that the
  // options are enabled.
  using node_options = typename ilist_detail::compute_node_options<
      Node, ilist_iterator_bits<true>>::type;
  static_assert(std::is_same<Node::self_iterator,
                             llvm::ilist_iterator_w_bits<node_options, false,
                                                         false>>::value);

  // Now test that a plain node, without the option, gets a plain
  // ilist_iterator.
  using plain_node_options =
      typename ilist_detail::compute_node_options<PlainNode>::type;
  static_assert(std::is_same<
                PlainNode::self_iterator,
                llvm::ilist_iterator<plain_node_options, false, false>>::value);
};

TEST(IListIteratorBitsTest, RangeIteration) {
  // Check that we can feed ilist_iterator_w_bits into make_range and similar.
  // Plus, we should be able to convert it to a reverse iterator and use that.
  simple_ilist<Node, ilist_iterator_bits<true>> L;
  Node A;
  L.insert(L.end(), A);

  for (Node &N : make_range(L.begin(), L.end()))
    (void)N;

  simple_ilist<Node, ilist_iterator_bits<true>>::iterator It =
      L.begin()->getIterator();
  auto RevIt = It.getReverse();

  for (Node &N : make_range(RevIt, L.rend()))
    (void)N;
}

TEST(IListIteratorBitsTest, GetParent) {
  simple_ilist<ParentNode, ilist_iterator_bits<true>, ilist_parent<Parent>> L;
  Parent P;
  ParentNode A;

  // Parents are not set automatically.
  A.setParent(&P);
  L.insert(L.end(), A);
  L.end().getNodePtr()->setParent(&P);

  // Check we can get the node parent from all iterators, including for the
  // sentinel.
  EXPECT_EQ(&P, L.begin().getNodeParent());
  EXPECT_EQ(&P, L.end().getNodeParent());
  EXPECT_EQ(&P, L.rbegin().getNodeParent());
  EXPECT_EQ(&P, L.rend().getNodeParent());
}

} // end namespace
