File indexing completed on 2026-05-10 08:43:06
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_ADT_ILIST_ITERATOR_H
0010 #define LLVM_ADT_ILIST_ITERATOR_H
0011
0012 #include "llvm/ADT/ilist_node.h"
0013 #include <cassert>
0014 #include <cstddef>
0015 #include <iterator>
0016 #include <type_traits>
0017
0018 namespace llvm {
0019
0020 namespace ilist_detail {
0021
0022
0023 template <class OptionsT, bool IsConst> struct IteratorTraits;
0024 template <class OptionsT> struct IteratorTraits<OptionsT, false> {
0025 using value_type = typename OptionsT::value_type;
0026 using pointer = typename OptionsT::pointer;
0027 using reference = typename OptionsT::reference;
0028 using node_pointer = ilist_node_impl<OptionsT> *;
0029 using node_reference = ilist_node_impl<OptionsT> &;
0030 };
0031 template <class OptionsT> struct IteratorTraits<OptionsT, true> {
0032 using value_type = const typename OptionsT::value_type;
0033 using pointer = typename OptionsT::const_pointer;
0034 using reference = typename OptionsT::const_reference;
0035 using node_pointer = const ilist_node_impl<OptionsT> *;
0036 using node_reference = const ilist_node_impl<OptionsT> &;
0037 };
0038
0039 template <bool IsReverse> struct IteratorHelper;
0040 template <> struct IteratorHelper<false> : ilist_detail::NodeAccess {
0041 using Access = ilist_detail::NodeAccess;
0042
0043 template <class T> static void increment(T *&I) { I = Access::getNext(*I); }
0044 template <class T> static void decrement(T *&I) { I = Access::getPrev(*I); }
0045 };
0046 template <> struct IteratorHelper<true> : ilist_detail::NodeAccess {
0047 using Access = ilist_detail::NodeAccess;
0048
0049 template <class T> static void increment(T *&I) { I = Access::getPrev(*I); }
0050 template <class T> static void decrement(T *&I) { I = Access::getNext(*I); }
0051 };
0052
0053
0054
0055
0056 template <class IteratorTy, class ParentTy, bool IsConst>
0057 class iterator_parent_access;
0058 template <class IteratorTy, class ParentTy>
0059 class iterator_parent_access<IteratorTy, ParentTy, true> {
0060 public:
0061 inline const ParentTy *getNodeParent() const {
0062 return static_cast<IteratorTy *>(this)->NodePtr->getParent();
0063 }
0064 };
0065 template <class IteratorTy, class ParentTy>
0066 class iterator_parent_access<IteratorTy, ParentTy, false> {
0067 public:
0068 inline ParentTy *getNodeParent() {
0069 return static_cast<IteratorTy *>(this)->NodePtr->getParent();
0070 }
0071 };
0072 template <class IteratorTy>
0073 class iterator_parent_access<IteratorTy, void, true> {};
0074 template <class IteratorTy>
0075 class iterator_parent_access<IteratorTy, void, false> {};
0076
0077 }
0078
0079
0080 template <class OptionsT, bool IsReverse, bool IsConst>
0081 class ilist_iterator : ilist_detail::SpecificNodeAccess<OptionsT>,
0082 public ilist_detail::iterator_parent_access<
0083 ilist_iterator<OptionsT, IsReverse, IsConst>,
0084 typename OptionsT::parent_ty, IsConst> {
0085 friend ilist_iterator<OptionsT, IsReverse, !IsConst>;
0086 friend ilist_iterator<OptionsT, !IsReverse, IsConst>;
0087 friend ilist_iterator<OptionsT, !IsReverse, !IsConst>;
0088 friend ilist_detail::iterator_parent_access<
0089 ilist_iterator<OptionsT, IsReverse, IsConst>,
0090 typename OptionsT::parent_ty, IsConst>;
0091
0092 using Traits = ilist_detail::IteratorTraits<OptionsT, IsConst>;
0093 using Access = ilist_detail::SpecificNodeAccess<OptionsT>;
0094
0095 public:
0096 using value_type = typename Traits::value_type;
0097 using pointer = typename Traits::pointer;
0098 using reference = typename Traits::reference;
0099 using difference_type = ptrdiff_t;
0100 using iterator_category = std::bidirectional_iterator_tag;
0101 using const_pointer = typename OptionsT::const_pointer;
0102 using const_reference = typename OptionsT::const_reference;
0103
0104 private:
0105 using node_pointer = typename Traits::node_pointer;
0106 using node_reference = typename Traits::node_reference;
0107
0108 node_pointer NodePtr = nullptr;
0109
0110 public:
0111
0112 explicit ilist_iterator(node_reference N) : NodePtr(&N) {}
0113
0114 explicit ilist_iterator(pointer NP) : NodePtr(Access::getNodePtr(NP)) {}
0115 explicit ilist_iterator(reference NR) : NodePtr(Access::getNodePtr(&NR)) {}
0116 ilist_iterator() = default;
0117
0118
0119
0120 template <bool RHSIsConst>
0121 ilist_iterator(const ilist_iterator<OptionsT, IsReverse, RHSIsConst> &RHS,
0122 std::enable_if_t<IsConst || !RHSIsConst, void *> = nullptr)
0123 : NodePtr(RHS.NodePtr) {}
0124
0125
0126
0127 template <bool RHSIsConst>
0128 std::enable_if_t<IsConst || !RHSIsConst, ilist_iterator &>
0129 operator=(const ilist_iterator<OptionsT, IsReverse, RHSIsConst> &RHS) {
0130 NodePtr = RHS.NodePtr;
0131 return *this;
0132 }
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 explicit ilist_iterator(
0143 const ilist_iterator<OptionsT, !IsReverse, IsConst> &RHS)
0144 : ilist_iterator(++RHS.getReverse()) {}
0145
0146
0147
0148
0149
0150
0151 ilist_iterator<OptionsT, !IsReverse, IsConst> getReverse() const {
0152 if (NodePtr)
0153 return ilist_iterator<OptionsT, !IsReverse, IsConst>(*NodePtr);
0154 return ilist_iterator<OptionsT, !IsReverse, IsConst>();
0155 }
0156
0157
0158 ilist_iterator<OptionsT, IsReverse, false> getNonConst() const {
0159 if (NodePtr)
0160 return ilist_iterator<OptionsT, IsReverse, false>(
0161 const_cast<typename ilist_iterator<OptionsT, IsReverse,
0162 false>::node_reference>(*NodePtr));
0163 return ilist_iterator<OptionsT, IsReverse, false>();
0164 }
0165
0166
0167 reference operator*() const {
0168 assert(!NodePtr->isKnownSentinel());
0169 return *Access::getValuePtr(NodePtr);
0170 }
0171 pointer operator->() const { return &operator*(); }
0172
0173
0174 friend bool operator==(const ilist_iterator &LHS, const ilist_iterator &RHS) {
0175 return LHS.NodePtr == RHS.NodePtr;
0176 }
0177 friend bool operator!=(const ilist_iterator &LHS, const ilist_iterator &RHS) {
0178 return LHS.NodePtr != RHS.NodePtr;
0179 }
0180
0181
0182 ilist_iterator &operator--() {
0183 NodePtr = IsReverse ? NodePtr->getNext() : NodePtr->getPrev();
0184 return *this;
0185 }
0186 ilist_iterator &operator++() {
0187 NodePtr = IsReverse ? NodePtr->getPrev() : NodePtr->getNext();
0188 return *this;
0189 }
0190 ilist_iterator operator--(int) {
0191 ilist_iterator tmp = *this;
0192 --*this;
0193 return tmp;
0194 }
0195 ilist_iterator operator++(int) {
0196 ilist_iterator tmp = *this;
0197 ++*this;
0198 return tmp;
0199 }
0200
0201 bool isValid() const { return NodePtr; }
0202
0203
0204 node_pointer getNodePtr() const { return static_cast<node_pointer>(NodePtr); }
0205
0206
0207 bool isEnd() const { return NodePtr ? NodePtr->isSentinel() : false; }
0208 };
0209
0210
0211
0212
0213 template <class OptionsT, bool IsReverse, bool IsConst>
0214 class ilist_iterator_w_bits
0215 : ilist_detail::SpecificNodeAccess<OptionsT>,
0216 public ilist_detail::iterator_parent_access<
0217 ilist_iterator_w_bits<OptionsT, IsReverse, IsConst>,
0218 typename OptionsT::parent_ty, IsConst> {
0219 friend ilist_iterator_w_bits<OptionsT, IsReverse, !IsConst>;
0220 friend ilist_iterator_w_bits<OptionsT, !IsReverse, IsConst>;
0221 friend ilist_iterator<OptionsT, !IsReverse, !IsConst>;
0222 friend ilist_detail::iterator_parent_access<
0223 ilist_iterator_w_bits<OptionsT, IsReverse, IsConst>,
0224 typename OptionsT::parent_ty, IsConst>;
0225
0226 using Traits = ilist_detail::IteratorTraits<OptionsT, IsConst>;
0227 using Access = ilist_detail::SpecificNodeAccess<OptionsT>;
0228
0229 public:
0230 using value_type = typename Traits::value_type;
0231 using pointer = typename Traits::pointer;
0232 using reference = typename Traits::reference;
0233 using difference_type = ptrdiff_t;
0234 using iterator_category = std::bidirectional_iterator_tag;
0235 using const_pointer = typename OptionsT::const_pointer;
0236 using const_reference = typename OptionsT::const_reference;
0237
0238 private:
0239 using node_pointer = typename Traits::node_pointer;
0240 using node_reference = typename Traits::node_reference;
0241
0242 node_pointer NodePtr = nullptr;
0243
0244
0245
0246 mutable bool HeadInclusiveBit = false;
0247
0248
0249 mutable bool TailInclusiveBit = false;
0250
0251 public:
0252
0253 explicit ilist_iterator_w_bits(node_reference N) : NodePtr(&N) {}
0254
0255 explicit ilist_iterator_w_bits(pointer NP)
0256 : NodePtr(Access::getNodePtr(NP)) {}
0257 explicit ilist_iterator_w_bits(reference NR)
0258 : NodePtr(Access::getNodePtr(&NR)) {}
0259 ilist_iterator_w_bits() = default;
0260
0261
0262
0263 template <bool RHSIsConst>
0264 ilist_iterator_w_bits(
0265 const ilist_iterator_w_bits<OptionsT, IsReverse, RHSIsConst> &RHS,
0266 std::enable_if_t<IsConst || !RHSIsConst, void *> = nullptr)
0267 : NodePtr(RHS.NodePtr) {
0268 HeadInclusiveBit = RHS.HeadInclusiveBit;
0269 TailInclusiveBit = RHS.TailInclusiveBit;
0270 }
0271
0272
0273
0274 template <bool RHSIsConst>
0275 std::enable_if_t<IsConst || !RHSIsConst, ilist_iterator_w_bits &>
0276 operator=(const ilist_iterator_w_bits<OptionsT, IsReverse, RHSIsConst> &RHS) {
0277 NodePtr = RHS.NodePtr;
0278 HeadInclusiveBit = RHS.HeadInclusiveBit;
0279 TailInclusiveBit = RHS.TailInclusiveBit;
0280 return *this;
0281 }
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291 explicit ilist_iterator_w_bits(
0292 const ilist_iterator_w_bits<OptionsT, !IsReverse, IsConst> &RHS)
0293 : ilist_iterator_w_bits(++RHS.getReverse()) {}
0294
0295
0296
0297
0298
0299
0300 ilist_iterator_w_bits<OptionsT, !IsReverse, IsConst> getReverse() const {
0301 if (NodePtr)
0302 return ilist_iterator_w_bits<OptionsT, !IsReverse, IsConst>(*NodePtr);
0303 return ilist_iterator_w_bits<OptionsT, !IsReverse, IsConst>();
0304 }
0305
0306
0307 ilist_iterator_w_bits<OptionsT, IsReverse, false> getNonConst() const {
0308 if (NodePtr) {
0309 auto New = ilist_iterator_w_bits<OptionsT, IsReverse, false>(
0310 const_cast<typename ilist_iterator_w_bits<OptionsT, IsReverse,
0311 false>::node_reference>(
0312 *NodePtr));
0313 New.HeadInclusiveBit = HeadInclusiveBit;
0314 New.TailInclusiveBit = TailInclusiveBit;
0315 return New;
0316 }
0317 return ilist_iterator_w_bits<OptionsT, IsReverse, false>();
0318 }
0319
0320
0321 reference operator*() const {
0322 assert(!NodePtr->isKnownSentinel());
0323 return *Access::getValuePtr(NodePtr);
0324 }
0325 pointer operator->() const { return &operator*(); }
0326
0327
0328 friend bool operator==(const ilist_iterator_w_bits &LHS,
0329 const ilist_iterator_w_bits &RHS) {
0330 return LHS.NodePtr == RHS.NodePtr;
0331 }
0332 friend bool operator!=(const ilist_iterator_w_bits &LHS,
0333 const ilist_iterator_w_bits &RHS) {
0334 return LHS.NodePtr != RHS.NodePtr;
0335 }
0336
0337
0338 ilist_iterator_w_bits &operator--() {
0339 NodePtr = IsReverse ? NodePtr->getNext() : NodePtr->getPrev();
0340 HeadInclusiveBit = false;
0341 TailInclusiveBit = false;
0342 return *this;
0343 }
0344 ilist_iterator_w_bits &operator++() {
0345 NodePtr = IsReverse ? NodePtr->getPrev() : NodePtr->getNext();
0346 HeadInclusiveBit = false;
0347 TailInclusiveBit = false;
0348 return *this;
0349 }
0350 ilist_iterator_w_bits operator--(int) {
0351 ilist_iterator_w_bits tmp = *this;
0352 --*this;
0353 return tmp;
0354 }
0355 ilist_iterator_w_bits operator++(int) {
0356 ilist_iterator_w_bits tmp = *this;
0357 ++*this;
0358 return tmp;
0359 }
0360
0361 bool isValid() const { return NodePtr; }
0362
0363
0364 node_pointer getNodePtr() const { return static_cast<node_pointer>(NodePtr); }
0365
0366
0367 bool isEnd() const { return NodePtr ? NodePtr->isSentinel() : false; }
0368
0369 bool getHeadBit() const { return HeadInclusiveBit; }
0370 bool getTailBit() const { return TailInclusiveBit; }
0371 void setHeadBit(bool SetBit) const { HeadInclusiveBit = SetBit; }
0372 void setTailBit(bool SetBit) const { TailInclusiveBit = SetBit; }
0373 };
0374
0375 template <typename From> struct simplify_type;
0376
0377
0378
0379
0380
0381 template <class OptionsT, bool IsConst>
0382 struct simplify_type<ilist_iterator<OptionsT, false, IsConst>> {
0383 using iterator = ilist_iterator<OptionsT, false, IsConst>;
0384 using SimpleType = typename iterator::pointer;
0385
0386 static SimpleType getSimplifiedValue(const iterator &Node) { return &*Node; }
0387 };
0388 template <class OptionsT, bool IsConst>
0389 struct simplify_type<const ilist_iterator<OptionsT, false, IsConst>>
0390 : simplify_type<ilist_iterator<OptionsT, false, IsConst>> {};
0391
0392
0393 template <class OptionsT, bool IsConst>
0394 struct simplify_type<ilist_iterator_w_bits<OptionsT, false, IsConst>> {
0395 using iterator = ilist_iterator_w_bits<OptionsT, false, IsConst>;
0396 using SimpleType = typename iterator::pointer;
0397
0398 static SimpleType getSimplifiedValue(const iterator &Node) { return &*Node; }
0399 };
0400 template <class OptionsT, bool IsConst>
0401 struct simplify_type<const ilist_iterator_w_bits<OptionsT, false, IsConst>>
0402 : simplify_type<ilist_iterator_w_bits<OptionsT, false, IsConst>> {};
0403
0404 }
0405
0406 #endif