26namespace sequoia::maths
31 inline constexpr bool has_get_allocator{
32 requires(
const T& t) { t.get_allocator(); }
35 template<
class Weight,
class Container>
39 using weight_type = Weight;
40 using node_weight_container_type = Container;
41 using size_type =
typename node_weight_container_type::size_type;
43 using iterator =
typename node_weight_container_type::iterator;
44 using reverse_iterator =
typename node_weight_container_type::reverse_iterator;
45 using node_weights_range = std::ranges::subrange<iterator>;
47 using const_iterator =
typename node_weight_container_type::const_iterator;
48 using const_reverse_iterator =
typename node_weight_container_type::const_reverse_iterator;
49 using const_node_weights_range = std::ranges::subrange<const_iterator>;
52 constexpr auto size()
const noexcept {
return m_NodeWeights.size(); }
55 constexpr iterator begin_node_weights()
noexcept
56 requires std::indirectly_writable<iterator, std::iter_value_t<iterator>>
58 return m_NodeWeights.begin();
62 constexpr reverse_iterator rbegin_node_weights()
noexcept
63 requires std::indirectly_writable<iterator, std::iter_value_t<iterator>>
65 return m_NodeWeights.rbegin();
69 constexpr const_iterator cbegin_node_weights()
const noexcept
71 return m_NodeWeights.cbegin();
75 constexpr const_reverse_iterator crbegin_node_weights()
const noexcept
77 return m_NodeWeights.crbegin();
81 constexpr iterator end_node_weights()
noexcept
82 requires std::indirectly_writable<iterator, std::iter_value_t<iterator>>
84 return m_NodeWeights.end();
88 constexpr reverse_iterator rend_node_weights()
noexcept
89 requires std::indirectly_writable<iterator, std::iter_value_t<iterator>>
91 return m_NodeWeights.rend();
95 constexpr const_iterator cend_node_weights()
const noexcept
97 return m_NodeWeights.cend();
101 constexpr const_reverse_iterator crend_node_weights()
const noexcept
103 return m_NodeWeights.crend();
107 constexpr node_weights_range node_weights()
noexcept
108 requires std::indirectly_writable<iterator, std::iter_value_t<iterator>>
110 return {begin_node_weights(), end_node_weights()};
114 constexpr const_node_weights_range node_weights()
const noexcept
116 return {cbegin_node_weights(), cend_node_weights()};
120 constexpr const_node_weights_range cnode_weights()
const noexcept
122 return node_weights();
126 constexpr void set_node_weight(const_iterator pos, W w)
128 if(pos == cend_node_weights())
throw std::out_of_range(
"node_storage::set_node_weight - index out of range!\n");
130 const auto index{std::ranges::distance(cbegin_node_weights(), pos)};
131 m_NodeWeights[index] = std::move(w);
135 constexpr decltype(
auto) mutate_node_weight(const_iterator pos, Fn fn)
137 if(pos == cend_node_weights())
throw std::out_of_range(
"node_storage::mutate_node_weight - index out of range!\n");
139 const auto index{std::ranges::distance(cbegin_node_weights(), pos)};
140 return fn(m_NodeWeights[index]);
154 template<std::
size_t N>
156 : m_NodeWeights{weights}
160 : m_NodeWeights{weights}
163 template<alloc Allocator>
165 : m_NodeWeights(allocator)
168 template<alloc Allocator>
170 : m_NodeWeights(n, allocator)
173 template<alloc Allocator>
174 constexpr node_storage_base(std::initializer_list<weight_type> weights,
const Allocator& allocator)
175 : m_NodeWeights{weights, allocator}
180 template<alloc Allocator>
182 : m_NodeWeights{other.m_NodeWeights, allocator}
187 template<alloc Allocator>
189 : m_NodeWeights{std::move(s.m_NodeWeights), allocator}
198 noexcept(
noexcept(std::ranges::swap(this->m_NodeWeights, rhs.m_NodeWeights)))
200 std::ranges::swap(m_NodeWeights, rhs.m_NodeWeights);
204 constexpr void swap_nodes(
const size_type i,
const size_type j)
206 if((i >= size()) || (j >= size()))
207 throw std::out_of_range(
"node_storage::swap - index out of range");
209 std::ranges::swap(m_NodeWeights[i], m_NodeWeights[j]);
212 auto get_node_allocator()
const
213 requires has_get_allocator<node_weight_container_type>
215 return m_NodeWeights.get_allocator();
218 void reserve(
const size_type newCapacity)
220 m_NodeWeights.reserve(newCapacity);
223 size_type capacity()
const noexcept
225 return m_NodeWeights.capacity();
230 m_NodeWeights.shrink_to_fit();
233 template<
class... Args>
234 void add_node(Args&&... args)
236 m_NodeWeights.emplace_back(std::forward<Args>(args)...);
239 template<
class... Args>
240 const_iterator insert_node(const_iterator pos, Args&&... args)
242 auto iter = m_NodeWeights.emplace(pos, std::forward<Args>(args)...);
244 return cbegin_node_weights() + std::ranges::distance(m_NodeWeights.begin(), iter);
247 const_iterator erase_node(const_iterator pos)
249 if(pos == cend_node_weights())
throw std::out_of_range(
"Attempting to erase a node which does not exist");
251 return const_iterator{m_NodeWeights.erase(pos)};
254 const_iterator erase_nodes(const_iterator first, const_iterator last)
256 if(first > last)
throw std::out_of_range(
"Attempting to erase a range of nodes with first > last");
258 return const_iterator{m_NodeWeights.erase(first, last)};
261 void clear()
noexcept
263 m_NodeWeights.clear();
267 node_weight_container_type m_NodeWeights;
270 template<
class Weight,
class Container = std::vector<Weight>>
275 using size_type =
typename base_t::size_type;
276 using weight_type =
typename base_t::weight_type;
290 template<alloc Allocator>
292 :
base_t{std::move(s), allocator}
296 template<
class Weight,
class Container>
297 requires std::is_empty_v<Weight>
301 using weight_type = Weight;
302 using size_type = std::size_t;
Utilities for both edges and nodes.
Implementation for an iterator with policies controlling dereferencing and auxiliary data.
Definition: NodeStorage.hpp:37
Definition: NodeStorage.hpp:272
Concept to work around the fact that currently the stl typically underconstrains operator==.
Definition: Concepts.hpp:105