File: List.h

package info (click to toggle)
pymol 3.1.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 74,084 kB
  • sloc: cpp: 482,660; python: 89,328; ansic: 29,512; javascript: 6,792; sh: 84; makefile: 25
file content (110 lines) | stat: -rw-r--r-- 2,718 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#pragma once
#include <cassert>
#include <iterator>

namespace pymol
{

/**
 * Non-owning view into PyMOL's singly linked list.
 */

template <typename T> class ListAdapter
{
  /**
   * Iterator for pymol::ListAdapter
   * Not really  aiming to satisfy any of the standard
   * named requirements for iterators, but to only implement
   * ones that will likely be used.
   * Uses IsConst pattern to avoid having to define non-const and const iterator
   * versions
   */

  template <bool IsConst> class ListAdapterIterator
  {
  public:
    using iterator_category = std::forward_iterator_tag;
    using difference_type = std::ptrdiff_t;
    using value_type = std::conditional_t<IsConst, const T, T>;
    using pointer = value_type*;
    using reference = value_type&;

    ListAdapterIterator() = default;
    explicit ListAdapterIterator(pointer ptr)
        : m_ptr(ptr)
    {
    }

    /**
     * Creates a const_iterator from iterator but not the other way around
     * @param other non const iterator
     */
    template <bool InnerIsConst = IsConst,
        typename = std::enable_if_t<InnerIsConst>>
    ListAdapterIterator(const ListAdapterIterator<false>& other)
        : m_ptr(other.m_ptr)
    {
    }

    reference operator*() { return *m_ptr; }
    reference operator*() const { return *m_ptr; }

    pointer operator->() { return m_ptr; }

    ListAdapterIterator& operator++()
    {
      if (m_ptr) {
        m_ptr = m_ptr->next;
      }
      return *this;
    }

    ListAdapterIterator operator++(int)
    {
      ListAdapterIterator tmp(*this);
      operator++();
      return tmp;
    }

    bool operator==(const ListAdapterIterator& iter) const
    {
      return m_ptr == iter.m_ptr;
    }

    bool operator!=(const ListAdapterIterator& iter) const
    {
      return !(m_ptr == iter.m_ptr);
    }

    friend class ListAdapterIterator<true>;

  private:
    pointer m_ptr{};
  };

public:
  using type = T;
  using pointer = T*;
  using iterator = ListAdapterIterator<false>;
  using const_iterator = ListAdapterIterator<true>;
  ListAdapter() = default;
  explicit ListAdapter(T* list)
      : m_list(list)
  {
  }
  iterator begin() noexcept { return iterator(m_list); }
  iterator end() noexcept { return iterator(nullptr); }
  const_iterator begin() const noexcept { return const_iterator(m_list); }
  const_iterator end() const noexcept { return const_iterator(nullptr); }
  const_iterator cbegin() const noexcept { return const_iterator(m_list); }
  const_iterator cend() const noexcept { return const_iterator(nullptr); }

private:
  pointer m_list{};
};

template <typename T> ListAdapter<T> make_list_adapter(T *list) {
  return ListAdapter<T>(list);
}

} // namespace pymol