NuriKit v0.1.0b2
Loading...
Searching...
No Matches
adaptor.h
Go to the documentation of this file.
1//
2// Project NuriKit - Copyright 2025 SNU Compbio Lab.
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#ifndef NURI_CORE_GRAPH_ADAPTOR_H_
7#define NURI_CORE_GRAPH_ADAPTOR_H_
8
10#include <utility>
11
12#include <boost/graph/graph_concepts.hpp>
13#include <boost/graph/properties.hpp>
14#include <boost/property_map/property_map.hpp>
15#include <boost/property_map/transform_value_property_map.hpp>
17
19#include "nuri/iterator.h"
20
21namespace nuri {
23 int id;
24 int src;
25 int dst;
26
27 friend bool operator==(const BoostEdgeDesc &lhs, const BoostEdgeDesc &rhs) {
28 return lhs.id == rhs.id;
29 }
30
31 friend bool operator!=(const BoostEdgeDesc &lhs, const BoostEdgeDesc &rhs) {
32 return lhs.id != rhs.id;
33 }
34};
35
36namespace internal {
37 struct nuri_graph_traversal_tag: virtual boost::incidence_graph_tag,
38 virtual boost::adjacency_graph_tag,
39 virtual boost::bidirectional_graph_tag,
40 virtual boost::vertex_list_graph_tag,
41 virtual boost::edge_list_graph_tag { };
42
43 template <class Impl, class VT, class Iterator>
44 class BoostGraphIteratorAdaptorBase
45 : public ProxyIterator<Impl, VT, typename Iterator::iterator_category,
46 typename Iterator::difference_type> {
47 public:
48 BoostGraphIteratorAdaptorBase() = default;
49
50 BoostGraphIteratorAdaptorBase(Iterator it): it_(it) { }
51
52 protected:
53 using Base = BoostGraphIteratorAdaptorBase;
54
55 private:
56 VT dereference() const {
57 return static_cast<const Impl &>(*this).dereference_impl(it_);
58 }
59
60 bool equal(const BoostGraphIteratorAdaptorBase &rhs) const {
61 return it_ == rhs.it_;
62 }
63
64 typename Iterator::difference_type
65 distance_to(const BoostGraphIteratorAdaptorBase &rhs) const {
66 return rhs.it_ - it_;
67 }
68
69 void increment() { ++it_; }
70 void decrement() { --it_; }
71
72 void advance(int n) { it_ += n; }
73
74 Iterator it_;
75
76 friend class boost::iterator_core_access;
77 };
78
79 template <class GT>
80 struct BoostGraphTraits {
81 private:
82 using Graph = GT;
83 using nuri_cnode_iter = typename Graph::const_node_iterator;
84 using nuri_cedge_iter = typename Graph::const_edge_iterator;
85 using nuri_cadj_iter = typename Graph::const_adjacency_iterator;
86
87 public:
88 using vertex_descriptor = int;
89 using edge_descriptor = BoostEdgeDesc;
90
91 class adjacency_iterator
92 : public BoostGraphIteratorAdaptorBase<
93 adjacency_iterator, vertex_descriptor, nuri_cadj_iter> {
94 using Base = typename adjacency_iterator::Base;
95
96 public:
97 using Base::Base;
98
99 private:
100 static vertex_descriptor dereference_impl(nuri_cadj_iter it) {
101 return it->dst().id();
102 }
103
104 friend Base;
105 };
106
107 class out_edge_iterator
108 : public BoostGraphIteratorAdaptorBase<
109 out_edge_iterator, edge_descriptor, nuri_cadj_iter> {
110 using Base = typename out_edge_iterator::Base;
111
112 public:
113 using Base::Base;
114
115 private:
116 static edge_descriptor dereference_impl(nuri_cadj_iter it) {
117 return { it->eid(), it->src().id(), it->dst().id() };
118 }
119
120 friend Base;
121 };
122
123 class in_edge_iterator
124 : public BoostGraphIteratorAdaptorBase<
125 in_edge_iterator, edge_descriptor, nuri_cadj_iter> {
126 using Base = typename in_edge_iterator::Base;
127
128 public:
129 using Base::Base;
130
131 private:
132 static edge_descriptor dereference_impl(nuri_cadj_iter it) {
133 return { it->eid(), it->dst().id(), it->src().id() };
134 }
135
136 friend Base;
137 };
138
139 class vertex_iterator
140 : public BoostGraphIteratorAdaptorBase<
141 vertex_iterator, vertex_descriptor, nuri_cnode_iter> {
142 using Base = typename vertex_iterator::Base;
143
144 public:
145 using Base::Base;
146
147 private:
148 static vertex_descriptor dereference_impl(nuri_cnode_iter it) {
149 return it->id();
150 }
151
152 friend Base;
153 };
154
155 class edge_iterator
156 : public BoostGraphIteratorAdaptorBase<edge_iterator, edge_descriptor,
157 nuri_cedge_iter> {
158 using Base = typename edge_iterator::Base;
159
160 public:
161 using Base::Base;
162
163 private:
164 static edge_descriptor dereference_impl(nuri_cedge_iter it) {
165 return { it->id(), it->src().id(), it->dst().id() };
166 }
167
168 friend Base;
169 };
170
171 using directed_category = boost::undirected_tag;
172 using edge_parallel_category = boost::allow_parallel_edge_tag;
173 using traversal_category = nuri_graph_traversal_tag;
174
175 using vertices_size_type = int;
176 using edges_size_type = int;
177 using degree_size_type = int;
178
179 static vertex_descriptor null_vertex() { return -1; }
180 };
181} // namespace internal
182} // namespace nuri
183
184namespace boost {
185template <class NT, class ET>
186struct graph_traits<nuri::Graph<NT, ET>>
187 : nuri::internal::BoostGraphTraits<nuri::Graph<NT, ET>> { };
188
189template <class NT, class ET, bool is_const>
190struct graph_traits<nuri::Subgraph<NT, ET, is_const>>
191 : nuri::internal::BoostGraphTraits<nuri::Subgraph<NT, ET, is_const>> { };
192} // namespace boost
193
194// These functions must be put here for ADL
195namespace nuri {
198
199template <class NT, class ET>
200auto out_edges(typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor v,
201 const Graph<NT, ET> &g) {
202 using Iter = typename boost::graph_traits<Graph<NT, ET>>::out_edge_iterator;
203 return std::make_pair(Iter(g[v].begin()), Iter(g[v].end()));
204}
205
206template <class NT, class ET>
207typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor
208source(typename boost::graph_traits<Graph<NT, ET>>::edge_descriptor e,
209 const Graph<NT, ET> & /* g */) {
210 return e.src;
211}
212
213template <class NT, class ET>
214typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor
215target(typename boost::graph_traits<Graph<NT, ET>>::edge_descriptor e,
216 const Graph<NT, ET> & /* g */) {
217 return e.dst;
218}
219
220template <class NT, class ET>
221auto out_degree(typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor v,
222 const Graph<NT, ET> &g) {
223 return g.degree(v);
224}
225
227
228template <class NT, class ET>
229auto in_edges(typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor v,
230 const Graph<NT, ET> &g) {
231 using Iter = typename boost::graph_traits<Graph<NT, ET>>::in_edge_iterator;
232 return std::make_pair(Iter(g[v].begin()), Iter(g[v].end()));
233}
234
235template <class NT, class ET>
236auto in_degree(typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor v,
237 const Graph<NT, ET> &g) {
238 return g.degree(v);
239}
240
241template <class NT, class ET>
242auto degree(typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor v,
243 const Graph<NT, ET> &g) {
244 return g.degree(v);
245}
246
248
249template <class NT, class ET>
251 typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor v,
252 const Graph<NT, ET> &g) {
253 using Iter = typename boost::graph_traits<Graph<NT, ET>>::adjacency_iterator;
254 return std::make_pair(Iter(g[v].begin()), Iter(g[v].end()));
255}
256
258
259template <class NT, class ET>
260auto vertices(const Graph<NT, ET> &g) {
261 using Iter = typename boost::graph_traits<Graph<NT, ET>>::vertex_iterator;
262 return std::make_pair(Iter(g.begin()), Iter(g.end()));
263}
264
265template <class NT, class ET>
267 return g.size();
268}
269
271
272template <class NT, class ET>
273auto edges(const Graph<NT, ET> &g) {
274 using Iter = typename boost::graph_traits<Graph<NT, ET>>::edge_iterator;
275 return std::make_pair(Iter(g.edge_begin()), Iter(g.edge_end()));
276}
277
278template <class NT, class ET>
279auto num_edges(const Graph<NT, ET> &g) {
280 return g.num_edges();
281}
282
284
285template <class NT, class ET>
287 return g.add_node({});
288}
289
290template <class NT, class ET>
292 typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor v,
293 Graph<NT, ET> &g) {
294 auto extract_eid = [](auto adj) { return adj.eid(); };
295 g.erase_edges(internal::make_transform_iterator(g[v].begin(), extract_eid),
296 internal::make_transform_iterator(g[v].end(), extract_eid));
297}
298
299template <class NT, class ET>
301 typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor v,
302 Graph<NT, ET> &g) {
303 g.erase_nodes(g.begin() + v, g.begin() + v + 1);
304}
305
306#pragma GCC diagnostic push
307#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
308
309template <class NT, class ET>
310auto add_edge(typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor u,
311 typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor v,
312 Graph<NT, ET> &g) {
313 int e = g.add_edge(u, v, {});
314 return std::make_pair(
315 typename boost::graph_traits<Graph<NT, ET>>::edge_descriptor { e, u, v },
316 true);
317}
318
319#pragma GCC diagnostic pop
320
321template <class NT, class ET>
323 typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor u,
324 typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor v,
325 Graph<NT, ET> &g) {
326 g.erase_edge_between(u, v);
327}
328
329template <class NT, class ET>
330void remove_edge(typename boost::graph_traits<Graph<NT, ET>>::edge_descriptor e,
331 Graph<NT, ET> &g) {
332 g.erase_edge(e.id);
333}
334
335template <class NT, class ET>
336void remove_edge(typename boost::graph_traits<Graph<NT, ET>>::edge_iterator it,
337 Graph<NT, ET> &g) {
338 remove_edge(*it, g);
339}
340
342
343template <class NT, class ET>
344auto get(boost::vertex_index_t /* tag */, const Graph<NT, ET> & /* g */) {
345 return boost::typed_identity_property_map<
346 typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor> {};
347}
348
349template <class NT, class ET>
350auto get(boost::vertex_index_t /* tag */, const Graph<NT, ET> & /* g */,
351 typename boost::graph_traits<Graph<NT, ET>>::vertex_descriptor v) {
352 return v;
353}
354
355template <class NT, class ET>
356auto get(boost::edge_index_t /* tag */, const Graph<NT, ET> & /* g */) {
357 return boost::make_transform_value_property_map(
358 [](auto e) { return e.id; },
359 boost::typed_identity_property_map<
360 typename boost::graph_traits<Graph<NT, ET>>::edge_descriptor>());
361}
362
363template <class NT, class ET>
364auto get(boost::edge_index_t /* tag */, const Graph<NT, ET> & /* g */,
365 typename boost::graph_traits<Graph<NT, ET>>::edge_descriptor e) {
366 return e.id;
367}
368
371
372template <class NT, class ET, bool is_const>
373auto out_edges(typename boost::graph_traits<
374 Subgraph<NT, ET, is_const>>::vertex_descriptor v,
376 using Iter =
377 typename boost::graph_traits<Subgraph<NT, ET, is_const>>::out_edge_iterator;
378 return std::make_pair(Iter(g[v].begin()), Iter(g[v].end()));
379}
380
381template <class NT, class ET, bool is_const>
382typename boost::graph_traits<Subgraph<NT, ET, is_const>>::vertex_descriptor
384 typename boost::graph_traits<Subgraph<NT, ET, is_const>>::edge_descriptor e,
385 const Subgraph<NT, ET, is_const> & /* g */) {
386 return e.src;
387}
388
389template <class NT, class ET, bool is_const>
390typename boost::graph_traits<Subgraph<NT, ET, is_const>>::vertex_descriptor
392 typename boost::graph_traits<Subgraph<NT, ET, is_const>>::edge_descriptor e,
393 const Subgraph<NT, ET, is_const> & /* g */) {
394 return e.dst;
395}
396
397template <class NT, class ET, bool is_const>
398auto out_degree(typename boost::graph_traits<
399 Subgraph<NT, ET, is_const>>::vertex_descriptor v,
401 return g.degree(v);
402}
403
405
406template <class NT, class ET, bool is_const>
407auto in_edges(typename boost::graph_traits<
408 Subgraph<NT, ET, is_const>>::vertex_descriptor v,
410 using Iter =
411 typename boost::graph_traits<Subgraph<NT, ET, is_const>>::in_edge_iterator;
412 return std::make_pair(Iter(g[v].begin()), Iter(g[v].end()));
413}
414
415template <class NT, class ET, bool is_const>
416auto in_degree(typename boost::graph_traits<
417 Subgraph<NT, ET, is_const>>::vertex_descriptor v,
419 return g.degree(v);
420}
421
422template <class NT, class ET, bool is_const>
423auto degree(typename boost::graph_traits<
424 Subgraph<NT, ET, is_const>>::vertex_descriptor v,
426 return g.degree(v);
427}
428
430
431template <class NT, class ET, bool is_const>
432auto adjacent_vertices(typename boost::graph_traits<
433 Subgraph<NT, ET, is_const>>::vertex_descriptor v,
435 using Iter = typename boost::graph_traits<
436 Subgraph<NT, ET, is_const>>::adjacency_iterator;
437 return std::make_pair(Iter(g[v].begin()), Iter(g[v].end()));
438}
439
441
442template <class NT, class ET, bool is_const>
444 using Iter =
445 typename boost::graph_traits<Subgraph<NT, ET, is_const>>::vertex_iterator;
446 return std::make_pair(Iter(g.begin()), Iter(g.end()));
447}
448
449template <class NT, class ET, bool is_const>
451 return g.size();
452}
453
455
456template <class NT, class ET, bool is_const>
458 using Iter =
459 typename boost::graph_traits<Subgraph<NT, ET, is_const>>::edge_iterator;
460 return std::make_pair(Iter(g.edge_begin()), Iter(g.edge_end()));
461}
462
463template <class NT, class ET, bool is_const>
465 return g.num_edges();
466}
467
469
470template <class NT, class ET, bool is_const>
471auto get(boost::vertex_index_t /* tag */,
472 const Subgraph<NT, ET, is_const> & /* g */) {
473 return boost::typed_identity_property_map<typename boost::graph_traits<
474 Subgraph<NT, ET, is_const>>::vertex_descriptor> {};
475}
476
477template <class NT, class ET, bool is_const>
478auto get(
479 boost::vertex_index_t /* tag */, const Subgraph<NT, ET, is_const> & /* g */,
480 typename boost::graph_traits<Subgraph<NT, ET, is_const>>::vertex_descriptor
481 v) {
482 return v;
483}
484
485template <class NT, class ET, bool is_const>
486auto get(boost::edge_index_t /* tag */,
487 const Subgraph<NT, ET, is_const> & /* g */) {
488 return boost::make_transform_value_property_map(
489 [](auto e) { return e.id; },
490 boost::typed_identity_property_map<typename boost::graph_traits<
491 Subgraph<NT, ET, is_const>>::edge_descriptor>());
492}
493
494template <class NT, class ET, bool is_const>
495auto get(
496 boost::edge_index_t /* tag */, const Subgraph<NT, ET, is_const> & /* g */,
497 typename boost::graph_traits<Subgraph<NT, ET, is_const>>::edge_descriptor e) {
498 return e.id;
499}
500} // namespace nuri
501
502#endif /* NURI_CORE_GRAPH_ADAPTOR_H_ */
Class for very sparse graphs, especially designed for the molecular graphs.
Definition graph.h:475
int add_node(const NT &data)
Add a node to the graph.
Definition graph.h:581
int degree(int id) const
Definition graph.h:563
void erase_edge(int id)
Erase an edge from the graph.
Definition graph.h:865
int size() const
Definition graph.h:550
bool erase_edge_between(int src, int dst)
Erase an edge from the graph between two nodes.
Definition graph.h:1380
iterator begin()
Definition graph.h:778
internal::EdgeIterator< Graph, true > const_edge_iterator
Definition graph.h:500
edge_iterator edge_end()
Definition graph.h:980
iterator end()
Definition graph.h:779
int add_edge(int src, int dst, const ET &data)
Add an edge to the graph.
Definition graph.h:635
int num_edges() const
Definition graph.h:561
std::pair< int, std::vector< int > > erase_edges(const_edge_iterator begin, const_edge_iterator end)
Erase edges from the graph.
Definition graph.h:919
edge_iterator edge_begin()
Definition graph.h:979
NodesErased erase_nodes(const_iterator begin, const_iterator end)
Erase nodes and all its associated edge(s) from the graph.
Definition graph.h:724
internal::AdjIterator< Graph, true > const_adjacency_iterator
Definition graph.h:505
const_iterator const_node_iterator
Definition graph.h:495
A subgraph of a graph.
Definition subgraph.h:575
int size() const
Count number of nodes in the subgraph.
Definition subgraph.h:746
int degree(int idx) const
Count in-subgraph neighbors of a node.
Definition subgraph.h:1443
edge_iterator edge_end()
Definition subgraph.h:1413
edge_iterator edge_begin()
Definition subgraph.h:1412
iterator end()
Definition subgraph.h:1391
iterator begin()
Definition subgraph.h:1390
int num_edges() const
Count number of edges in the subgraph.
Definition subgraph.h:760
Definition adaptor.h:184
Definition crdgen.h:16
auto num_vertices(const Graph< NT, ET > &g)
Definition adaptor.h:266
auto vertices(const Graph< NT, ET > &g)
Definition adaptor.h:260
auto add_vertex(Graph< NT, ET > &g)
Definition adaptor.h:286
auto out_edges(typename boost::graph_traits< Graph< NT, ET > >::vertex_descriptor v, const Graph< NT, ET > &g)
Definition adaptor.h:200
auto get(boost::vertex_index_t, const Graph< NT, ET > &)
Definition adaptor.h:344
auto edges(const Graph< NT, ET > &g)
Definition adaptor.h:273
void clear_vertex(typename boost::graph_traits< Graph< NT, ET > >::vertex_descriptor v, Graph< NT, ET > &g)
Definition adaptor.h:291
auto add_edge(typename boost::graph_traits< Graph< NT, ET > >::vertex_descriptor u, typename boost::graph_traits< Graph< NT, ET > >::vertex_descriptor v, Graph< NT, ET > &g)
Definition adaptor.h:310
auto degree(typename boost::graph_traits< Graph< NT, ET > >::vertex_descriptor v, const Graph< NT, ET > &g)
Definition adaptor.h:242
void remove_edge(typename boost::graph_traits< Graph< NT, ET > >::vertex_descriptor u, typename boost::graph_traits< Graph< NT, ET > >::vertex_descriptor v, Graph< NT, ET > &g)
Definition adaptor.h:322
boost::graph_traits< Graph< NT, ET > >::vertex_descriptor target(typename boost::graph_traits< Graph< NT, ET > >::edge_descriptor e, const Graph< NT, ET > &)
Definition adaptor.h:215
auto out_degree(typename boost::graph_traits< Graph< NT, ET > >::vertex_descriptor v, const Graph< NT, ET > &g)
Definition adaptor.h:221
auto in_edges(typename boost::graph_traits< Graph< NT, ET > >::vertex_descriptor v, const Graph< NT, ET > &g)
Definition adaptor.h:229
boost::graph_traits< Graph< NT, ET > >::vertex_descriptor source(typename boost::graph_traits< Graph< NT, ET > >::edge_descriptor e, const Graph< NT, ET > &)
Definition adaptor.h:208
auto adjacent_vertices(typename boost::graph_traits< Graph< NT, ET > >::vertex_descriptor v, const Graph< NT, ET > &g)
Definition adaptor.h:250
void remove_vertex(typename boost::graph_traits< Graph< NT, ET > >::vertex_descriptor v, Graph< NT, ET > &g)
Definition adaptor.h:300
auto in_degree(typename boost::graph_traits< Graph< NT, ET > >::vertex_descriptor v, const Graph< NT, ET > &g)
Definition adaptor.h:236
auto num_edges(const Graph< NT, ET > &g)
Definition adaptor.h:279
Definition adaptor.h:22
friend bool operator!=(const BoostEdgeDesc &lhs, const BoostEdgeDesc &rhs)
Definition adaptor.h:31
int src
Definition adaptor.h:24
int id
Definition adaptor.h:23
int dst
Definition adaptor.h:25
friend bool operator==(const BoostEdgeDesc &lhs, const BoostEdgeDesc &rhs)
Definition adaptor.h:27