LCOV - code coverage report
Current view: top level - include/llvm/ADT - ilist_iterator.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 80 136 58.8 %
Date: 2018-10-20 13:21:21 Functions: 0 287 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- llvm/ADT/ilist_iterator.h - Intrusive List Iterator ------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #ifndef LLVM_ADT_ILIST_ITERATOR_H
      11             : #define LLVM_ADT_ILIST_ITERATOR_H
      12             : 
      13             : #include "llvm/ADT/ilist_node.h"
      14             : #include <cassert>
      15             : #include <cstddef>
      16             : #include <iterator>
      17             : #include <type_traits>
      18             : 
      19             : namespace llvm {
      20             : 
      21             : namespace ilist_detail {
      22             : 
      23             : /// Find const-correct node types.
      24             : template <class OptionsT, bool IsConst> struct IteratorTraits;
      25             : template <class OptionsT> struct IteratorTraits<OptionsT, false> {
      26             :   using value_type = typename OptionsT::value_type;
      27             :   using pointer = typename OptionsT::pointer;
      28             :   using reference = typename OptionsT::reference;
      29             :   using node_pointer = ilist_node_impl<OptionsT> *;
      30             :   using node_reference = ilist_node_impl<OptionsT> &;
      31             : };
      32             : template <class OptionsT> struct IteratorTraits<OptionsT, true> {
      33             :   using value_type = const typename OptionsT::value_type;
      34             :   using pointer = typename OptionsT::const_pointer;
      35             :   using reference = typename OptionsT::const_reference;
      36             :   using node_pointer = const ilist_node_impl<OptionsT> *;
      37             :   using node_reference = const ilist_node_impl<OptionsT> &;
      38             : };
      39             : 
      40             : template <bool IsReverse> struct IteratorHelper;
      41             : template <> struct IteratorHelper<false> : ilist_detail::NodeAccess {
      42             :   using Access = ilist_detail::NodeAccess;
      43             : 
      44             :   template <class T> static void increment(T *&I) { I = Access::getNext(*I); }
      45             :   template <class T> static void decrement(T *&I) { I = Access::getPrev(*I); }
      46             : };
      47             : template <> struct IteratorHelper<true> : ilist_detail::NodeAccess {
      48             :   using Access = ilist_detail::NodeAccess;
      49             : 
      50             :   template <class T> static void increment(T *&I) { I = Access::getPrev(*I); }
      51             :   template <class T> static void decrement(T *&I) { I = Access::getNext(*I); }
      52             : };
      53             : 
      54             : } // end namespace ilist_detail
      55             : 
      56             : /// Iterator for intrusive lists  based on ilist_node.
      57             : template <class OptionsT, bool IsReverse, bool IsConst>
      58             : class ilist_iterator : ilist_detail::SpecificNodeAccess<OptionsT> {
      59             :   friend ilist_iterator<OptionsT, IsReverse, !IsConst>;
      60             :   friend ilist_iterator<OptionsT, !IsReverse, IsConst>;
      61             :   friend ilist_iterator<OptionsT, !IsReverse, !IsConst>;
      62             : 
      63             :   using Traits = ilist_detail::IteratorTraits<OptionsT, IsConst>;
      64             :   using Access = ilist_detail::SpecificNodeAccess<OptionsT>;
      65             : 
      66             : public:
      67             :   using value_type = typename Traits::value_type;
      68             :   using pointer = typename Traits::pointer;
      69             :   using reference = typename Traits::reference;
      70             :   using difference_type = ptrdiff_t;
      71             :   using iterator_category = std::bidirectional_iterator_tag;
      72             :   using const_pointer = typename OptionsT::const_pointer;
      73             :   using const_reference = typename OptionsT::const_reference;
      74             : 
      75             : private:
      76             :   using node_pointer = typename Traits::node_pointer;
      77             :   using node_reference = typename Traits::node_reference;
      78             : 
      79             :   node_pointer NodePtr = nullptr;
      80             : 
      81             : public:
      82             :   /// Create from an ilist_node.
      83             :   explicit ilist_iterator(node_reference N) : NodePtr(&N) {}
      84             : 
      85    25431188 :   explicit ilist_iterator(pointer NP) : NodePtr(Access::getNodePtr(NP)) {}
      86    35568599 :   explicit ilist_iterator(reference NR) : NodePtr(Access::getNodePtr(&NR)) {}
      87    28992854 :   ilist_iterator() = default;
      88             : 
      89             :   // This is templated so that we can allow constructing a const iterator from
      90             :   // a nonconst iterator...
      91             :   template <bool RHSIsConst>
      92     5218650 :   ilist_iterator(
      93             :       const ilist_iterator<OptionsT, IsReverse, RHSIsConst> &RHS,
      94             :       typename std::enable_if<IsConst || !RHSIsConst, void *>::type = nullptr)
      95     5072766 :       : NodePtr(RHS.NodePtr) {}
      96           0 : 
      97             :   // This is templated so that we can allow assigning to a const iterator from
      98             :   // a nonconst iterator...
      99           0 :   template <bool RHSIsConst>
     100           0 :   typename std::enable_if<IsConst || !RHSIsConst, ilist_iterator &>::type
     101             :   operator=(const ilist_iterator<OptionsT, IsReverse, RHSIsConst> &RHS) {
     102             :     NodePtr = RHS.NodePtr;
     103           0 :     return *this;
     104           0 :   }
     105             : 
     106             :   /// Explicit conversion between forward/reverse iterators.
     107           0 :   ///
     108             :   /// Translate between forward and reverse iterators without changing range
     109             :   /// boundaries.  The resulting iterator will dereference (and have a handle)
     110             :   /// to the previous node, which is somewhat unexpected; but converting the
     111             :   /// two endpoints in a range will give the same range in reverse.
     112             :   ///
     113             :   /// This matches std::reverse_iterator conversions.
     114             :   explicit ilist_iterator(
     115             :       const ilist_iterator<OptionsT, !IsReverse, IsConst> &RHS)
     116             :       : ilist_iterator(++RHS.getReverse()) {}
     117             : 
     118             :   /// Get a reverse iterator to the same node.
     119             :   ///
     120             :   /// Gives a reverse iterator that will dereference (and have a handle) to the
     121             :   /// same node.  Converting the endpoint iterators in a range will give a
     122           5 :   /// different range; for range operations, use the explicit conversions.
     123           0 :   ilist_iterator<OptionsT, !IsReverse, IsConst> getReverse() const {
     124    41937782 :     if (NodePtr)
     125           0 :       return ilist_iterator<OptionsT, !IsReverse, IsConst>(*NodePtr);
     126           0 :     return ilist_iterator<OptionsT, !IsReverse, IsConst>();
     127             :   }
     128           0 : 
     129           0 :   /// Const-cast.
     130           0 :   ilist_iterator<OptionsT, IsReverse, false> getNonConst() const {
     131     4238747 :     if (NodePtr)
     132          12 :       return ilist_iterator<OptionsT, IsReverse, false>(
     133           0 :           const_cast<typename ilist_iterator<OptionsT, IsReverse,
     134           0 :                                              false>::node_reference>(*NodePtr));
     135           0 :     return ilist_iterator<OptionsT, IsReverse, false>();
     136           7 :   }
     137           0 : 
     138           0 :   // Accessors...
     139           0 :   reference operator*() const {
     140           0 :     assert(!NodePtr->isKnownSentinel());
     141           0 :     return *Access::getValuePtr(NodePtr);
     142           0 :   }
     143          28 :   pointer operator->() const { return &operator*(); }
     144           0 : 
     145           0 :   // Comparison operators
     146           0 :   friend bool operator==(const ilist_iterator &LHS, const ilist_iterator &RHS) {
     147          48 :     return LHS.NodePtr == RHS.NodePtr;
     148           0 :   }
     149           0 :   friend bool operator!=(const ilist_iterator &LHS, const ilist_iterator &RHS) {
     150           0 :     return LHS.NodePtr != RHS.NodePtr;
     151   111472060 :   }
     152           0 : 
     153           0 :   // Increment and decrement operators...
     154           0 :   ilist_iterator &operator--() {
     155    43117309 :     NodePtr = IsReverse ? NodePtr->getNext() : NodePtr->getPrev();
     156           0 :     return *this;
     157           0 :   }
     158           0 :   ilist_iterator &operator++() {
     159    75482464 :     NodePtr = IsReverse ? NodePtr->getPrev() : NodePtr->getNext();
     160           0 :     return *this;
     161           0 :   }
     162           0 :   ilist_iterator operator--(int) {
     163    12405571 :     ilist_iterator tmp = *this;
     164           0 :     --*this;
     165    10235266 :     return tmp;
     166           0 :   }
     167    18064346 :   ilist_iterator operator++(int) {
     168       23137 :     ilist_iterator tmp = *this;
     169      665140 :     ++*this;
     170           0 :     return tmp;
     171      155412 :   }
     172           0 : 
     173   169382747 :   /// Get the underlying ilist_node.
     174     8322023 :   node_pointer getNodePtr() const { return static_cast<node_pointer>(NodePtr); }
     175     3449964 : 
     176     4618172 :   /// Check for end.  Only valid if ilist_sentinel_tracking<true>.
     177     7481947 :   bool isEnd() const { return NodePtr ? NodePtr->isSentinel() : false; }
     178       33424 : };
     179    92052709 : 
     180      688997 : template <typename From> struct simplify_type;
     181           1 : 
     182    11487749 : /// Allow ilist_iterators to convert into pointers to a node automatically when
     183      163548 : /// used by the dyn_cast, cast, isa mechanisms...
     184        3514 : ///
     185    96260305 : /// FIXME: remove this, since there is no implicit conversion to NodeTy.
     186     2698716 : template <class OptionsT, bool IsConst>
     187      152467 : struct simplify_type<ilist_iterator<OptionsT, false, IsConst>> {
     188          62 :   using iterator = ilist_iterator<OptionsT, false, IsConst>;
     189    19607868 :   using SimpleType = typename iterator::pointer;
     190   106278095 : 
     191   147840564 :   static SimpleType getSimplifiedValue(const iterator &Node) { return &*Node; }
     192         467 : };
     193    77695517 : template <class OptionsT, bool IsConst>
     194     2649192 : struct simplify_type<const ilist_iterator<OptionsT, false, IsConst>>
     195    10600862 :     : simplify_type<ilist_iterator<OptionsT, false, IsConst>> {};
     196    33841048 : 
     197     7282032 : } // end namespace llvm
     198       55068 : 
     199    28664641 : #endif // LLVM_ADT_ILIST_ITERATOR_H

Generated by: LCOV version 1.13