NEURON
non_owning_soa_identifier.hpp
Go to the documentation of this file.
1 #pragma once
2 #include <cassert>
3 #include <cstddef>
4 #include <limits>
5 #include <memory>
6 #include <ostream>
7 #include <vector>
8 
9 namespace neuron::container {
10 /**
11  * @brief Struct used to index SoAoS data, such as array range variables.
12  */
13 struct field_index {
14  int field{}, array_index{};
15 };
16 
17 inline constexpr std::size_t invalid_row = std::numeric_limits<std::size_t>::max();
18 
19 /**
20  * @brief A non-owning permutation-stable identifier for an entry in a container.
21  *
22  * The container type is not specified. This is essentially a wrapper for
23  * std::size_t* that avoids using that naked type in too many places.
24  */
26  /**
27  * @brief Create a null identifier.
28  */
30 
32  default;
34  default;
35 
39  default;
40 
42 
43 
44  /**
45  * @brief Does the identifier refer to a valid entry?
46  *
47  * The row can be invalid because the identifier was always null, or it can
48  * have become invalid if the relevant entry was deleted after the
49  * identifier was created.
50  */
51  [[nodiscard]] explicit operator bool() const {
52  return m_ptr && (*m_ptr != invalid_row);
53  }
54 
55  /**
56  * @brief What is the current row?
57  *
58  * The returned value is invalidated by any deletions from the underlying
59  * container, and by any permutations of the underlying container.
60  */
61  [[nodiscard]] std::size_t current_row() const {
62  assert(m_ptr);
63  auto const value = *m_ptr;
65  return value;
66  }
67 
68  /**
69  * @brief Did the identifier use to refer to a valid entry?
70  */
71  [[nodiscard]] bool was_once_valid() const {
72  return m_ptr && *m_ptr == invalid_row;
73  }
74 
75  /**
76  * @brief Has the identifier always been null.
77  *
78  * has_always_been_null() --> "null"
79  * !has_always_been_null && was_once_valid --> "died"
80  * !has_always_been_null && !was_once_valid --> "row=X"
81  */
82  [[nodiscard]] bool has_always_been_null() const {
83  return !m_ptr;
84  }
85 
86  friend std::ostream& operator<<(std::ostream& os,
88  if (!id.m_ptr) {
89  return os << "null";
90  } else if (*id.m_ptr == invalid_row) {
91  return os << "died";
92  } else {
93  return os << "row=" << *id.m_ptr;
94  }
95  }
96 
97  /** @brief Test if two handles are both null or refer to the same valid row.
98  */
101  return lhs.m_ptr == rhs.m_ptr || (!lhs && !rhs);
102  }
103 
106  return !(lhs == rhs);
107  }
108 
111  return lhs.m_ptr < rhs.m_ptr;
112  }
113 
114  protected:
115  // Needed to convert owning_identifier<T> to non_owning_identifier<T>
116  template <typename>
117  friend struct owning_identifier;
118 
119  template <typename, typename...>
120  friend struct soa;
121  friend struct std::hash<non_owning_identifier_without_container>;
122  explicit non_owning_identifier_without_container(std::shared_ptr<std::size_t> ptr)
123  : m_ptr{std::move(ptr)} {}
124  void set_current_row(std::size_t row) {
125  assert(m_ptr);
126  *m_ptr = row;
127  }
128 
130  : m_ptr(std::make_shared<size_t>(row)) {}
131 
132  private:
133  std::shared_ptr<std::size_t> m_ptr{};
134 };
135 } // namespace neuron::container
136 template <>
138  std::size_t operator()(
140  return reinterpret_cast<std::size_t>(h.m_ptr.get());
141  }
142 };
#define assert(ex)
Definition: hocassrt.h:24
#define rhs
Definition: lineq.h:6
void move(Item *q1, Item *q2, Item *q3)
Definition: list.cpp:200
constexpr std::size_t invalid_row
static unsigned row
Definition: nonlin.cpp:78
static uint32_t value
Definition: scoprand.cpp:25
Struct used to index SoAoS data, such as array range variables.
A non-owning permutation-stable identifier for an entry in a container.
bool was_once_valid() const
Did the identifier use to refer to a valid entry?
friend bool operator<(non_owning_identifier_without_container lhs, non_owning_identifier_without_container rhs)
friend bool operator==(non_owning_identifier_without_container lhs, non_owning_identifier_without_container rhs)
Test if two handles are both null or refer to the same valid row.
non_owning_identifier_without_container & operator=(const non_owning_identifier_without_container &)=default
friend bool operator!=(non_owning_identifier_without_container lhs, non_owning_identifier_without_container rhs)
non_owning_identifier_without_container(non_owning_identifier_without_container &&other)=default
friend std::ostream & operator<<(std::ostream &os, non_owning_identifier_without_container const &id)
non_owning_identifier_without_container & operator=(non_owning_identifier_without_container &&)=default
non_owning_identifier_without_container()=default
Create a null identifier.
bool has_always_been_null() const
Has the identifier always been null.
non_owning_identifier_without_container(const non_owning_identifier_without_container &other)=default
An owning permutation-stable identifier for a entry in a container.
std::size_t operator()(neuron::container::non_owning_identifier_without_container const &h) noexcept