File: List.h

package info (click to toggle)
pymol 2.4.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 43,312 kB
  • sloc: cpp: 480,106; python: 79,860; ansic: 28,343; javascript: 6,792; sh: 47; makefile: 30; csh: 8
file content (106 lines) | stat: -rw-r--r-- 2,607 bytes parent folder | download | duplicates (2)
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
#pragma once
#include <cassert>
#include <iostream>
#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 = typename std::conditional<IsConst, const T, T>::type;
    using pointer = value_type*;
    using reference = value_type&;

    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 = typename std::enable_if<InnerIsConst>>
    ListAdapterIterator(const ListAdapterIterator<false>& other)
        : m_ptr(other.m_ptr)
    {
    }

    reference operator*() { return *m_ptr; }

    pointer operator->() { return m_ptr; }

    ListAdapterIterator& operator++()
    {
      assert(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 iterator = ListAdapterIterator<false>;
  using const_iterator = ListAdapterIterator<true>;
  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:
  type* m_list;
};

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

} // namespace pymol