mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
ae65e281f3
to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. llvm-svn: 351636
199 lines
7.2 KiB
C++
199 lines
7.2 KiB
C++
//===- 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;
|
|
template <class OptionsT> struct IteratorTraits<OptionsT, false> {
|
|
using value_type = typename OptionsT::value_type;
|
|
using pointer = typename OptionsT::pointer;
|
|
using reference = typename OptionsT::reference;
|
|
using node_pointer = ilist_node_impl<OptionsT> *;
|
|
using node_reference = ilist_node_impl<OptionsT> &;
|
|
};
|
|
template <class OptionsT> struct IteratorTraits<OptionsT, true> {
|
|
using value_type = const typename OptionsT::value_type;
|
|
using pointer = typename OptionsT::const_pointer;
|
|
using reference = typename OptionsT::const_reference;
|
|
using node_pointer = const ilist_node_impl<OptionsT> *;
|
|
using node_reference = const ilist_node_impl<OptionsT> &;
|
|
};
|
|
|
|
template <bool IsReverse> struct IteratorHelper;
|
|
template <> struct IteratorHelper<false> : ilist_detail::NodeAccess {
|
|
using Access = ilist_detail::NodeAccess;
|
|
|
|
template <class T> static void increment(T *&I) { I = Access::getNext(*I); }
|
|
template <class T> static void decrement(T *&I) { I = Access::getPrev(*I); }
|
|
};
|
|
template <> struct IteratorHelper<true> : ilist_detail::NodeAccess {
|
|
using Access = ilist_detail::NodeAccess;
|
|
|
|
template <class T> static void increment(T *&I) { I = Access::getPrev(*I); }
|
|
template <class T> static void decrement(T *&I) { I = Access::getNext(*I); }
|
|
};
|
|
|
|
} // 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> {
|
|
friend ilist_iterator<OptionsT, IsReverse, !IsConst>;
|
|
friend ilist_iterator<OptionsT, !IsReverse, IsConst>;
|
|
friend ilist_iterator<OptionsT, !IsReverse, !IsConst>;
|
|
|
|
using Traits = ilist_detail::IteratorTraits<OptionsT, IsConst>;
|
|
using Access = ilist_detail::SpecificNodeAccess<OptionsT>;
|
|
|
|
public:
|
|
using value_type = typename Traits::value_type;
|
|
using pointer = typename Traits::pointer;
|
|
using reference = typename Traits::reference;
|
|
using difference_type = ptrdiff_t;
|
|
using iterator_category = std::bidirectional_iterator_tag;
|
|
using const_pointer = typename OptionsT::const_pointer;
|
|
using const_reference = typename OptionsT::const_reference;
|
|
|
|
private:
|
|
using node_pointer = typename Traits::node_pointer;
|
|
using node_reference = typename Traits::node_reference;
|
|
|
|
node_pointer NodePtr = nullptr;
|
|
|
|
public:
|
|
/// Create from an ilist_node.
|
|
explicit ilist_iterator(node_reference N) : NodePtr(&N) {}
|
|
|
|
explicit ilist_iterator(pointer NP) : NodePtr(Access::getNodePtr(NP)) {}
|
|
explicit ilist_iterator(reference NR) : NodePtr(Access::getNodePtr(&NR)) {}
|
|
ilist_iterator() = default;
|
|
|
|
// This is templated so that we can allow constructing a const iterator from
|
|
// a nonconst iterator...
|
|
template <bool RHSIsConst>
|
|
ilist_iterator(
|
|
const ilist_iterator<OptionsT, IsReverse, RHSIsConst> &RHS,
|
|
typename std::enable_if<IsConst || !RHSIsConst, void *>::type = nullptr)
|
|
: NodePtr(RHS.NodePtr) {}
|
|
|
|
// This is templated so that we can allow assigning to a const iterator from
|
|
// a nonconst iterator...
|
|
template <bool RHSIsConst>
|
|
typename std::enable_if<IsConst || !RHSIsConst, ilist_iterator &>::type
|
|
operator=(const ilist_iterator<OptionsT, IsReverse, RHSIsConst> &RHS) {
|
|
NodePtr = RHS.NodePtr;
|
|
return *this;
|
|
}
|
|
|
|
/// Explicit conversion between forward/reverse iterators.
|
|
///
|
|
/// Translate between forward and reverse iterators without changing range
|
|
/// boundaries. The resulting iterator will dereference (and have a handle)
|
|
/// to the previous node, which is somewhat unexpected; but converting the
|
|
/// two endpoints in a range will give the same range in reverse.
|
|
///
|
|
/// This matches std::reverse_iterator conversions.
|
|
explicit ilist_iterator(
|
|
const ilist_iterator<OptionsT, !IsReverse, IsConst> &RHS)
|
|
: ilist_iterator(++RHS.getReverse()) {}
|
|
|
|
/// Get a reverse iterator to the same node.
|
|
///
|
|
/// Gives a reverse iterator that will dereference (and have a handle) to the
|
|
/// same node. Converting the endpoint iterators in a range will give a
|
|
/// different range; for range operations, use the explicit conversions.
|
|
ilist_iterator<OptionsT, !IsReverse, IsConst> getReverse() const {
|
|
if (NodePtr)
|
|
return ilist_iterator<OptionsT, !IsReverse, IsConst>(*NodePtr);
|
|
return ilist_iterator<OptionsT, !IsReverse, IsConst>();
|
|
}
|
|
|
|
/// Const-cast.
|
|
ilist_iterator<OptionsT, IsReverse, false> getNonConst() const {
|
|
if (NodePtr)
|
|
return ilist_iterator<OptionsT, IsReverse, false>(
|
|
const_cast<typename ilist_iterator<OptionsT, IsReverse,
|
|
false>::node_reference>(*NodePtr));
|
|
return ilist_iterator<OptionsT, IsReverse, false>();
|
|
}
|
|
|
|
// Accessors...
|
|
reference operator*() const {
|
|
assert(!NodePtr->isKnownSentinel());
|
|
return *Access::getValuePtr(NodePtr);
|
|
}
|
|
pointer operator->() const { return &operator*(); }
|
|
|
|
// Comparison operators
|
|
friend bool operator==(const ilist_iterator &LHS, const ilist_iterator &RHS) {
|
|
return LHS.NodePtr == RHS.NodePtr;
|
|
}
|
|
friend bool operator!=(const ilist_iterator &LHS, const ilist_iterator &RHS) {
|
|
return LHS.NodePtr != RHS.NodePtr;
|
|
}
|
|
|
|
// Increment and decrement operators...
|
|
ilist_iterator &operator--() {
|
|
NodePtr = IsReverse ? NodePtr->getNext() : NodePtr->getPrev();
|
|
return *this;
|
|
}
|
|
ilist_iterator &operator++() {
|
|
NodePtr = IsReverse ? NodePtr->getPrev() : NodePtr->getNext();
|
|
return *this;
|
|
}
|
|
ilist_iterator operator--(int) {
|
|
ilist_iterator tmp = *this;
|
|
--*this;
|
|
return tmp;
|
|
}
|
|
ilist_iterator operator++(int) {
|
|
ilist_iterator tmp = *this;
|
|
++*this;
|
|
return tmp;
|
|
}
|
|
|
|
/// Get the underlying ilist_node.
|
|
node_pointer getNodePtr() const { return static_cast<node_pointer>(NodePtr); }
|
|
|
|
/// Check for end. Only valid if ilist_sentinel_tracking<true>.
|
|
bool isEnd() const { return NodePtr ? NodePtr->isSentinel() : false; }
|
|
};
|
|
|
|
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.
|
|
template <class OptionsT, bool IsConst>
|
|
struct simplify_type<ilist_iterator<OptionsT, false, IsConst>> {
|
|
using iterator = ilist_iterator<OptionsT, false, IsConst>;
|
|
using SimpleType = typename iterator::pointer;
|
|
|
|
static SimpleType getSimplifiedValue(const iterator &Node) { return &*Node; }
|
|
};
|
|
template <class OptionsT, bool IsConst>
|
|
struct simplify_type<const ilist_iterator<OptionsT, false, IsConst>>
|
|
: simplify_type<ilist_iterator<OptionsT, false, IsConst>> {};
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif // LLVM_ADT_ILIST_ITERATOR_H
|