llvm/llvm/include/llvm/ADT/ilist_iterator.h

//===- llvm/ADT/ilist_iterator.h - Intrusive List Iterator ------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ADT_ILIST_ITERATOR_H
#define LLVM_ADT_ILIST_ITERATOR_H

#include "llvm/ADT/ilist_node.h"
#include <cassert>
#include <cstddef>
#include <iterator>
#include <type_traits>

namespace llvm {

namespace ilist_detail {

/// Find const-correct node types.
template <class OptionsT, bool IsConst> struct IteratorTraits;
IteratorTraits<OptionsT, false>;
IteratorTraits<OptionsT, true>;

template <bool IsReverse> struct IteratorHelper;
template <> struct IteratorHelper<false> : ilist_detail::NodeAccess {};
template <> struct IteratorHelper<true> : ilist_detail::NodeAccess {};

/// Mixin class used to add a \a getNodeParent() function to iterators iff the
/// list uses \a ilist_parent, calling through to the node's \a getParent(). For
/// more details see \a ilist_node.
template <class IteratorTy, class ParentTy, bool IsConst>
class iterator_parent_access;
iterator_parent_access<IteratorTy, ParentTy, true>;
iterator_parent_access<IteratorTy, ParentTy, false>;
iterator_parent_access<IteratorTy, void, true>;
iterator_parent_access<IteratorTy, void, false>;

} // end namespace ilist_detail

/// Iterator for intrusive lists  based on ilist_node.
template <class OptionsT, bool IsReverse, bool IsConst>
class ilist_iterator : ilist_detail::SpecificNodeAccess<OptionsT>,
                       public ilist_detail::iterator_parent_access<
                           ilist_iterator<OptionsT, IsReverse, IsConst>,
                           typename OptionsT::parent_ty, IsConst> {};

/// Iterator for intrusive lists  based on ilist_node. Much like ilist_iterator,
/// but with the addition of two bits recording whether this position (when in
/// a range) is half or fully open.
template <class OptionsT, bool IsReverse, bool IsConst>
class ilist_iterator_w_bits
    : ilist_detail::SpecificNodeAccess<OptionsT>,
      public ilist_detail::iterator_parent_access<
          ilist_iterator_w_bits<OptionsT, IsReverse, IsConst>,
          typename OptionsT::parent_ty, IsConst> {};

template <typename From> struct simplify_type;

/// Allow ilist_iterators to convert into pointers to a node automatically when
/// used by the dyn_cast, cast, isa mechanisms...
///
/// FIXME: remove this, since there is no implicit conversion to NodeTy.
simplify_type<ilist_iterator<OptionsT, false, IsConst>>;
simplify_type<const ilist_iterator<OptionsT, false, IsConst>>;

// ilist_iterator_w_bits should also be accessible via isa/dyn_cast.
simplify_type<ilist_iterator_w_bits<OptionsT, false, IsConst>>;
simplify_type<const ilist_iterator_w_bits<OptionsT, false, IsConst>>;

} // end namespace llvm

#endif // LLVM_ADT_ILIST_ITERATOR_H