Identifier.hpp
1 #pragma once
2 #include <score/tools/std/Optional.hpp>
3 
4 #include <QPointer>
5 
6 #include <type_traits>
7 
8 namespace score
9 {
10 template <typename T, bool Order>
11 class EntityMap;
12 }
13 template <typename Element, typename Model, bool Order>
14 class IdContainer;
15 template <typename T>
16 class IdentifiedObject;
55 template <typename tag, typename impl>
56 class id_base_t
57 {
58  friend tag;
59  friend class score::EntityMap<tag, false>;
60  friend class score::EntityMap<tag, true>;
61  friend class IdentifiedObject<tag>;
62 
63  // TODO Try to only have Map as a template type here
64  template <typename Element, typename Model, bool Order>
65  friend class IdContainer;
66 
67 public:
68  using value_type = impl;
69  explicit id_base_t() noexcept { }
70 
71  id_base_t(const id_base_t& other) noexcept
72  : m_id{other.m_id}
73  {
74  }
75 
76  id_base_t(id_base_t&& other) noexcept
77  : m_id{std::move(other.m_id)}
78  {
79  }
80  template <typename other>
81  requires(std::is_base_of_v<tag, other>)
82  id_base_t(const id_base_t<other, impl>& oid) noexcept
83  : m_id{oid.val()}
84  {
85  }
86 
87  template <typename other>
88  requires(std::is_base_of_v<tag, other>)
89  id_base_t(id_base_t&& oid) noexcept
90  : m_id{oid.val()}
91  {
92  }
93 
94  id_base_t& operator=(const id_base_t& other) noexcept
95  {
96  m_id = other.m_id;
97  m_ptr.clear();
98  return *this;
99  }
100 
101  id_base_t& operator=(id_base_t&& other) noexcept
102  {
103  m_id = other.m_id;
104  m_ptr.clear();
105  return *this;
106  }
107 
108  // TODO check if when an id is returned by value,
109  // the pointer gets copied correctly
110  explicit id_base_t(value_type val) noexcept
111  : m_id{std::move(val)}
112  {
113  }
114 
115  explicit id_base_t(tag& element) noexcept
116  : m_ptr{&element}
117  , m_id{element.id()}
118  {
119  }
120 
121  id_base_t& operator=(tag& element) noexcept
122  {
123  m_ptr = &element;
124  m_id = element.id();
125 
126  return *this;
127  }
128 
129  friend bool operator==(const id_base_t& lhs, const id_base_t& rhs) noexcept
130  {
131  return lhs.m_id == rhs.m_id;
132  }
133 
134  friend bool operator!=(const id_base_t& lhs, const id_base_t& rhs) noexcept
135  {
136  return lhs.m_id != rhs.m_id;
137  }
138 
139  friend bool operator<(const id_base_t& lhs, const id_base_t& rhs) noexcept
140  {
141  return lhs.val() < rhs.val();
142  }
143 
144  explicit operator value_type() const noexcept { return m_id; }
145 
146  const value_type& val() const noexcept { return m_id; }
147 
148  void setVal(value_type val) noexcept { m_id = val; }
149 
150 private:
151  mutable QPointer<QObject> m_ptr;
152  value_type m_id{};
153 };
154 
158 template <typename tag>
160 
164 template <typename tag>
165 using OptionalId = std::optional<Id<tag>>;
166 
167 namespace std
168 {
169 template <typename tag>
170 struct hash<Id<tag>>
171 {
172  std::size_t operator()(const Id<tag>& id) const
173  {
174  return std::hash<int32_t>{}(id.val());
175  }
176 };
177 }
178 template <typename T>
179 uint qHash(const Id<T>& id, uint seed)
180 {
181  return qHash(*id.val(), seed);
182 }
A map to access child objects through their id.
Definition: IdentifiedObjectMap.hpp:16
The IdentifiedObject class.
Definition: IdentifiedObject.hpp:19
The id_base_t class.
Definition: Identifier.hpp:57
The EntityMap class.
Definition: EntityMap.hpp:36
Base toolkit upon which the software is built.
Definition: Application.cpp:90