Sequoia
Loading...
Searching...
No Matches
Edge.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2018. //
3// Distributed under the GNU GENERAL PUBLIC LICENSE, Version 3.0. //
4// (See accompanying file LICENSE.md or copy at //
5// https://www.gnu.org/licenses/gpl-3.0.en.html) //
7
8#pragma once
9
30
31#include <stdexcept>
32
33namespace sequoia
34{
35 namespace maths
36 {
48 template<class WeightHandler, std::integral IndexType>
49 requires object::handler<WeightHandler>
51 {
52 public:
53 using weight_handler_type = WeightHandler;
54 using weight_type = typename WeightHandler::value_type;
55
56 [[nodiscard]]
57 constexpr const weight_type& weight() const noexcept { return WeightHandler::get(m_Weight); }
58
59 [[nodiscard]]
60 constexpr weight_type& weight() noexcept { return WeightHandler::get(m_Weight); }
61
62 constexpr void weight(weight_type w)
63 {
64 WeightHandler::get(m_Weight) = std::move(w);
65 }
66
67 template<class... Args>
68 requires ((sizeof...(Args) > 0) && is_initializable_v<weight_type, Args...>)
69 constexpr void weight(Args&&... args)
70 {
71 WeightHandler::get(m_Weight) = weight_type{std::forward<Args>(args)...};
72 }
73
74 template<std::invocable<weight_type&> Fn>
75 constexpr std::invoke_result_t<Fn, weight_type&> mutate_weight(Fn fn)
76 {
77 return fn(WeightHandler::get(m_Weight));
78 }
79
80 [[nodiscard]]
81 friend constexpr bool operator==(const weighting& lhs, const weighting& rhs) noexcept
82 requires is_deep_equality_comparable_v<weight_type>
83 {
84 return lhs.weight() == rhs.weight();
85 }
86 protected:
87 ~weighting() = default;
88
89 template<class... Args>
90 requires (!resolve_to_copy_v<weighting, Args...>)
91 constexpr explicit(sizeof...(Args) == 1) weighting(Args&&... args)
92 : m_Weight{WeightHandler::producer_type::make(std::forward<Args>(args)...)}
93 {}
94
95 constexpr weighting(const weighting& other)
96 : m_Weight{WeightHandler::producer_type::make(WeightHandler::get(other.m_Weight))}
97 {}
98
99 template<class Other>
100 requires std::is_base_of_v<weighting, std::remove_cvref_t<Other>>
101 constexpr weighting(Other&& other) : m_Weight{other.m_Weight}
102 {}
103
104 constexpr weighting(weighting&&) noexcept = default;
105
106 constexpr weighting& operator=(const weighting& other)
107 {
108 if(&other != this) m_Weight = WeightHandler::producer_type::make(WeightHandler::get(other.m_Weight));
109 return *this;
110 }
111
112 constexpr weighting& operator=(weighting&&) noexcept = default;
113 private:
114 typename WeightHandler::product_type m_Weight;
115 };
116
122 template<class WeightHandler, std::integral IndexType>
123 requires (object::handler<WeightHandler> && std::is_empty_v<typename WeightHandler::value_type>)
125 {
126 public:
127 using weight_handler_type = WeightHandler;
128 using weight_type = typename WeightHandler::value_type;
129
130 [[nodiscard]]
131 friend constexpr bool operator==(const weighting&, const weighting&) noexcept = default;
132 protected:
133 constexpr weighting() noexcept = default;
134 ~weighting() = default;
135
136 constexpr weighting(const weighting&) noexcept = default;
137 constexpr weighting(weighting&&) noexcept = default;
138 constexpr weighting& operator=(const weighting&) noexcept = default;
139 constexpr weighting& operator=(weighting&&) noexcept = default;
140 constexpr weighting(const weighting&, const IndexType) noexcept {}
141 };
142
143 //===================================Partial Edge Base===================================//
144
150 template<class WeightHandler, std::integral IndexType>
152 class partial_edge_base : public weighting<WeightHandler, IndexType>
153 {
154 public:
155 using index_type = IndexType;
156 using weight_type = typename weighting<WeightHandler, IndexType>::weight_type;
157
158 template<class... Args>
159 requires (!resolve_to_copy_v<partial_edge_base, Args...>)
160 constexpr explicit(sizeof...(Args) == 0) partial_edge_base(const index_type target, Args&&... args)
161 : weighting<WeightHandler, IndexType>{std::forward<Args>(args)...}
162 , m_Target{target}
163 {}
164
165 constexpr partial_edge_base(const index_type target, const partial_edge_base& other)
167 , m_Target{target}
168 {}
169
170 constexpr partial_edge_base(const partial_edge_base&) = default;
171 constexpr partial_edge_base(partial_edge_base&&) noexcept = default;
172
173 [[nodiscard]]
174 constexpr IndexType target_node() const noexcept { return m_Target; }
175
176 constexpr void target_node(const index_type target) noexcept { m_Target = target; }
177
178 [[nodiscard]]
179 friend constexpr bool operator==(const partial_edge_base&, const partial_edge_base&) noexcept = default;
180 protected:
181 ~partial_edge_base() = default;
182
183 constexpr partial_edge_base& operator=(const partial_edge_base&) = default;
184 constexpr partial_edge_base& operator=(partial_edge_base&&) noexcept = default;
185 private:
186 IndexType m_Target;
187 };
188
189 //===================================Decorated Partial Edge Base===================================//
190
191 template<class WeightHandler, class MetaData, std::integral IndexType>
193 class decorated_partial_edge_base : public partial_edge_base<WeightHandler, IndexType>
194 {
195 public:
196 using partial_edge_base<WeightHandler, IndexType>::partial_edge_base;
197
198 template<class OtherHandler>
199 requires (object::handler<OtherHandler> && !std::is_same_v<WeightHandler, OtherHandler> && std::is_same_v<typename OtherHandler::value_type, typename WeightHandler::value_type>)
201 : partial_edge_base<WeightHandler, IndexType>{other.target_node(), other.weight()}
202 {}
203
205 constexpr decorated_partial_edge_base& operator=(const decorated_partial_edge_base&) = default;
206
207 protected:
209
210 constexpr decorated_partial_edge_base(decorated_partial_edge_base&&) noexcept = default;
211 constexpr decorated_partial_edge_base& operator=(decorated_partial_edge_base&&) noexcept = default;
212 };
213
214 template<class WeightHandler, class MetaData, std::integral IndexType>
215 requires object::handler<WeightHandler> && (!std::is_empty_v<MetaData>)
217 {
218 public:
219 using index_type = IndexType;
220 using meta_data_type = MetaData;
221 using weight_type = typename partial_edge_base<WeightHandler, IndexType>::weight_type;
222
223 constexpr explicit decorated_partial_edge_base(const index_type target)
224 requires is_initializable_v<MetaData> && is_initializable_v<weight_type>
226 , m_MetaData{}
227 {}
228
229 constexpr decorated_partial_edge_base(const index_type target, meta_data_type m)
230 requires (std::is_empty_v<weight_type> && !std::is_empty_v<meta_data_type>)
232 , m_MetaData{std::move(m)}
233 {}
234
235 constexpr decorated_partial_edge_base(const index_type target, meta_data_type m, weight_type w)
236 requires (!std::is_empty_v<weight_type> && !std::is_empty_v<meta_data_type>)
237 : partial_edge_base<WeightHandler, IndexType>{target, std::move(w)}
238 , m_MetaData{std::move(m)}
239 {}
240
241 constexpr decorated_partial_edge_base(const index_type target, meta_data_type m, const decorated_partial_edge_base& other)
243 , m_MetaData{std::move(m)}
244 {}
245
246
247 template<class OtherHandler>
248 requires (object::handler<OtherHandler> && !std::is_same_v<WeightHandler, OtherHandler> && std::is_same_v<typename OtherHandler::value_type, typename WeightHandler::value_type>)
250 : partial_edge_base<WeightHandler, IndexType>{other.target_node(), other.weight()}
251 , m_MetaData{other.meta_data()}
252 {}
253
255 constexpr decorated_partial_edge_base& operator=(const decorated_partial_edge_base&) = default;
256
257
258 [[nodiscard]]
259 constexpr const MetaData& meta_data() const noexcept { return m_MetaData; }
260
261 constexpr void meta_data(MetaData m) { m_MetaData = std::move(m); }
262
263 template<class... Args>
264 requires ((sizeof...(Args) > 0) && is_initializable_v<meta_data_type, Args...>)
265 constexpr void meta_data(Args&&... args)
266 {
267 m_MetaData = {std::forward<Args>(args)...};
268 }
269
270 template<std::invocable<meta_data_type&> Fn>
271 constexpr std::invoke_result_t<Fn, meta_data_type&> mutate_meta_data(Fn fn)
272 {
273 return fn(m_MetaData);
274 }
275
276 [[nodiscard]]
277 friend constexpr bool operator==(const decorated_partial_edge_base&, const decorated_partial_edge_base&) noexcept = default;
278 protected:
280
281 constexpr decorated_partial_edge_base(decorated_partial_edge_base&&) noexcept = default;
282 constexpr decorated_partial_edge_base& operator=(decorated_partial_edge_base&&) noexcept = default;
283 private:
284 MetaData m_MetaData;
285 };
286
287 struct null_meta_data {};
288
289 //===================================Helper Enum===================================//
290
291 enum class edge_flavour : bool { partial, partial_embedded };
292
293 //===================================Partial Edge===================================//
294
300 template<class WeightHandler, class MetaData, std::integral IndexType=std::size_t>
302 class partial_edge : public decorated_partial_edge_base<WeightHandler, MetaData, IndexType>
303 {
304 public:
305 constexpr static edge_flavour flavour{edge_flavour::partial};
306
307 using weight_type = typename decorated_partial_edge_base<WeightHandler, MetaData, IndexType>::weight_type;
308 using meta_data_type = MetaData;
309 using index_type = IndexType;
310
311 using decorated_partial_edge_base<WeightHandler, MetaData, IndexType>::decorated_partial_edge_base;
312
313 [[nodiscard]]
314 friend constexpr bool operator==(const partial_edge&, const partial_edge&) noexcept = default;
315 };
316
317 //===================================Embedded Partial Edge===================================//
318
325 template<class WeightHandler, class MetaData, std::integral IndexType=std::size_t>
327 class embedded_partial_edge : public decorated_partial_edge_base<WeightHandler, MetaData, IndexType>
328 {
329 public:
330 constexpr static edge_flavour flavour{edge_flavour::partial_embedded};
331
332 using weight_type = typename decorated_partial_edge_base<WeightHandler, MetaData, IndexType>::weight_type;
333 using meta_data_type = MetaData;
334 using index_type = IndexType;
335
336 template<class... Args>
337 requires (!resolve_to_copy_v<embedded_partial_edge, Args...>)
338 constexpr embedded_partial_edge(const index_type target, const index_type complimentaryIndex, Args&&... args)
339 : decorated_partial_edge_base<WeightHandler, MetaData, IndexType>{target, std::forward<Args>(args)...}
340 , m_ComplementaryIndex{complimentaryIndex}
341 {}
342
343 constexpr embedded_partial_edge(const index_type target, const index_type complimentaryIndex, const embedded_partial_edge& other)
344 requires std::is_empty_v<meta_data_type>
346 , m_ComplementaryIndex{complimentaryIndex}
347 {}
348
349 constexpr embedded_partial_edge(const index_type target, const index_type complimentaryIndex, meta_data_type m, const embedded_partial_edge& other)
351 , m_ComplementaryIndex{complimentaryIndex}
352 {}
353
354 template<class OtherHandler>
355 requires (object::handler<OtherHandler> && !std::is_same_v<WeightHandler, OtherHandler> && std::is_same_v<typename OtherHandler::value_type, typename WeightHandler::value_type>)
358 , m_ComplementaryIndex{other.complementary_index()}
359 {}
360
361 constexpr embedded_partial_edge(const embedded_partial_edge&) = default;
362 constexpr embedded_partial_edge(embedded_partial_edge&&) noexcept = default;
363
364 constexpr embedded_partial_edge& operator=(const embedded_partial_edge&) = default;
365 constexpr embedded_partial_edge& operator=(embedded_partial_edge&&) noexcept = default;
366
367 [[nodiscard]]
368 constexpr index_type complementary_index() const noexcept { return m_ComplementaryIndex; }
369 constexpr void complementary_index(const index_type index) noexcept { m_ComplementaryIndex = index; }
370
371 [[nodiscard]]
372 friend constexpr bool operator==(const embedded_partial_edge&, const embedded_partial_edge&) noexcept = default;
373 private:
374 IndexType m_ComplementaryIndex;
375 };
376 }
377}
Concepts which are sufficiently general to appear in the sequoia namespace.
Utilities for both edges and nodes.
Traits and Concepts for Sharing Policies.
Traits which are sufficiently general to appear in the sequoia namespace.
Decoration of a partial_edge to record the location on the target node into which the edge is embedde...
Definition: Edge.hpp:328
Combines the edge_base and weighting class.
Definition: Edge.hpp:153
A concrete edge containing a target index and, optionally, a weight.
Definition: Edge.hpp:303
A class to store non-trivial edge weights.
Definition: Edge.hpp:51
Definition: HandlerTraits.hpp:20
Definition: Edge.hpp:287