lemongraph 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +8 -0
  3. data/LICENSE +674 -0
  4. data/README.md +6 -0
  5. data/ext/lemon-1.3.1/AUTHORS +26 -0
  6. data/ext/lemon-1.3.1/CMakeLists.txt +371 -0
  7. data/ext/lemon-1.3.1/INSTALL +167 -0
  8. data/ext/lemon-1.3.1/LICENSE +32 -0
  9. data/ext/lemon-1.3.1/NEWS +337 -0
  10. data/ext/lemon-1.3.1/README +50 -0
  11. data/ext/lemon-1.3.1/cmake/FindCOIN.cmake +110 -0
  12. data/ext/lemon-1.3.1/cmake/FindGLPK.cmake +55 -0
  13. data/ext/lemon-1.3.1/cmake/FindGhostscript.cmake +10 -0
  14. data/ext/lemon-1.3.1/cmake/FindILOG.cmake +102 -0
  15. data/ext/lemon-1.3.1/cmake/FindSOPLEX.cmake +23 -0
  16. data/ext/lemon-1.3.1/cmake/LEMONConfig.cmake.in +13 -0
  17. data/ext/lemon-1.3.1/cmake/nsis/lemon.ico +0 -0
  18. data/ext/lemon-1.3.1/cmake/nsis/uninstall.ico +0 -0
  19. data/ext/lemon-1.3.1/cmake/version.cmake +1 -0
  20. data/ext/lemon-1.3.1/cmake/version.cmake.in +1 -0
  21. data/ext/lemon-1.3.1/contrib/CMakeLists.txt +19 -0
  22. data/ext/lemon-1.3.1/lemon/CMakeLists.txt +91 -0
  23. data/ext/lemon-1.3.1/lemon/adaptors.h +3638 -0
  24. data/ext/lemon-1.3.1/lemon/arg_parser.cc +474 -0
  25. data/ext/lemon-1.3.1/lemon/arg_parser.h +440 -0
  26. data/ext/lemon-1.3.1/lemon/assert.h +214 -0
  27. data/ext/lemon-1.3.1/lemon/base.cc +37 -0
  28. data/ext/lemon-1.3.1/lemon/bellman_ford.h +1116 -0
  29. data/ext/lemon-1.3.1/lemon/bfs.h +1754 -0
  30. data/ext/lemon-1.3.1/lemon/bin_heap.h +347 -0
  31. data/ext/lemon-1.3.1/lemon/binomial_heap.h +445 -0
  32. data/ext/lemon-1.3.1/lemon/bits/alteration_notifier.h +472 -0
  33. data/ext/lemon-1.3.1/lemon/bits/array_map.h +351 -0
  34. data/ext/lemon-1.3.1/lemon/bits/bezier.h +174 -0
  35. data/ext/lemon-1.3.1/lemon/bits/default_map.h +182 -0
  36. data/ext/lemon-1.3.1/lemon/bits/edge_set_extender.h +627 -0
  37. data/ext/lemon-1.3.1/lemon/bits/enable_if.h +131 -0
  38. data/ext/lemon-1.3.1/lemon/bits/graph_adaptor_extender.h +401 -0
  39. data/ext/lemon-1.3.1/lemon/bits/graph_extender.h +1332 -0
  40. data/ext/lemon-1.3.1/lemon/bits/lock.h +65 -0
  41. data/ext/lemon-1.3.1/lemon/bits/map_extender.h +332 -0
  42. data/ext/lemon-1.3.1/lemon/bits/path_dump.h +177 -0
  43. data/ext/lemon-1.3.1/lemon/bits/solver_bits.h +194 -0
  44. data/ext/lemon-1.3.1/lemon/bits/traits.h +388 -0
  45. data/ext/lemon-1.3.1/lemon/bits/variant.h +494 -0
  46. data/ext/lemon-1.3.1/lemon/bits/vector_map.h +244 -0
  47. data/ext/lemon-1.3.1/lemon/bits/windows.cc +166 -0
  48. data/ext/lemon-1.3.1/lemon/bits/windows.h +44 -0
  49. data/ext/lemon-1.3.1/lemon/bucket_heap.h +594 -0
  50. data/ext/lemon-1.3.1/lemon/capacity_scaling.h +1014 -0
  51. data/ext/lemon-1.3.1/lemon/cbc.cc +460 -0
  52. data/ext/lemon-1.3.1/lemon/cbc.h +129 -0
  53. data/ext/lemon-1.3.1/lemon/christofides_tsp.h +254 -0
  54. data/ext/lemon-1.3.1/lemon/circulation.h +807 -0
  55. data/ext/lemon-1.3.1/lemon/clp.cc +464 -0
  56. data/ext/lemon-1.3.1/lemon/clp.h +164 -0
  57. data/ext/lemon-1.3.1/lemon/color.cc +44 -0
  58. data/ext/lemon-1.3.1/lemon/color.h +204 -0
  59. data/ext/lemon-1.3.1/lemon/concept_check.h +77 -0
  60. data/ext/lemon-1.3.1/lemon/concepts/bpgraph.h +1029 -0
  61. data/ext/lemon-1.3.1/lemon/concepts/digraph.h +491 -0
  62. data/ext/lemon-1.3.1/lemon/concepts/graph.h +788 -0
  63. data/ext/lemon-1.3.1/lemon/concepts/graph_components.h +2134 -0
  64. data/ext/lemon-1.3.1/lemon/concepts/heap.h +324 -0
  65. data/ext/lemon-1.3.1/lemon/concepts/maps.h +223 -0
  66. data/ext/lemon-1.3.1/lemon/concepts/path.h +312 -0
  67. data/ext/lemon-1.3.1/lemon/config.h.in +22 -0
  68. data/ext/lemon-1.3.1/lemon/connectivity.h +1688 -0
  69. data/ext/lemon-1.3.1/lemon/core.h +2506 -0
  70. data/ext/lemon-1.3.1/lemon/cost_scaling.h +1607 -0
  71. data/ext/lemon-1.3.1/lemon/counter.h +249 -0
  72. data/ext/lemon-1.3.1/lemon/cplex.cc +994 -0
  73. data/ext/lemon-1.3.1/lemon/cplex.h +292 -0
  74. data/ext/lemon-1.3.1/lemon/cycle_canceling.h +1230 -0
  75. data/ext/lemon-1.3.1/lemon/dfs.h +1637 -0
  76. data/ext/lemon-1.3.1/lemon/dheap.h +352 -0
  77. data/ext/lemon-1.3.1/lemon/dijkstra.h +1303 -0
  78. data/ext/lemon-1.3.1/lemon/dim2.h +726 -0
  79. data/ext/lemon-1.3.1/lemon/dimacs.h +448 -0
  80. data/ext/lemon-1.3.1/lemon/edge_set.h +1420 -0
  81. data/ext/lemon-1.3.1/lemon/edmonds_karp.h +556 -0
  82. data/ext/lemon-1.3.1/lemon/elevator.h +982 -0
  83. data/ext/lemon-1.3.1/lemon/error.h +276 -0
  84. data/ext/lemon-1.3.1/lemon/euler.h +287 -0
  85. data/ext/lemon-1.3.1/lemon/fib_heap.h +475 -0
  86. data/ext/lemon-1.3.1/lemon/fractional_matching.h +2139 -0
  87. data/ext/lemon-1.3.1/lemon/full_graph.h +1082 -0
  88. data/ext/lemon-1.3.1/lemon/glpk.cc +1012 -0
  89. data/ext/lemon-1.3.1/lemon/glpk.h +263 -0
  90. data/ext/lemon-1.3.1/lemon/gomory_hu.h +568 -0
  91. data/ext/lemon-1.3.1/lemon/graph_to_eps.h +1186 -0
  92. data/ext/lemon-1.3.1/lemon/greedy_tsp.h +251 -0
  93. data/ext/lemon-1.3.1/lemon/grid_graph.h +699 -0
  94. data/ext/lemon-1.3.1/lemon/grosso_locatelli_pullan_mc.h +840 -0
  95. data/ext/lemon-1.3.1/lemon/hao_orlin.h +1015 -0
  96. data/ext/lemon-1.3.1/lemon/hartmann_orlin_mmc.h +654 -0
  97. data/ext/lemon-1.3.1/lemon/howard_mmc.h +651 -0
  98. data/ext/lemon-1.3.1/lemon/hypercube_graph.h +459 -0
  99. data/ext/lemon-1.3.1/lemon/insertion_tsp.h +533 -0
  100. data/ext/lemon-1.3.1/lemon/karp_mmc.h +590 -0
  101. data/ext/lemon-1.3.1/lemon/kruskal.h +324 -0
  102. data/ext/lemon-1.3.1/lemon/lemon.pc.in +10 -0
  103. data/ext/lemon-1.3.1/lemon/lgf_reader.h +3854 -0
  104. data/ext/lemon-1.3.1/lemon/lgf_writer.h +2687 -0
  105. data/ext/lemon-1.3.1/lemon/list_graph.h +2510 -0
  106. data/ext/lemon-1.3.1/lemon/lp.h +95 -0
  107. data/ext/lemon-1.3.1/lemon/lp_base.cc +30 -0
  108. data/ext/lemon-1.3.1/lemon/lp_base.h +2147 -0
  109. data/ext/lemon-1.3.1/lemon/lp_skeleton.cc +143 -0
  110. data/ext/lemon-1.3.1/lemon/lp_skeleton.h +234 -0
  111. data/ext/lemon-1.3.1/lemon/maps.h +4057 -0
  112. data/ext/lemon-1.3.1/lemon/matching.h +3505 -0
  113. data/ext/lemon-1.3.1/lemon/math.h +77 -0
  114. data/ext/lemon-1.3.1/lemon/max_cardinality_search.h +794 -0
  115. data/ext/lemon-1.3.1/lemon/min_cost_arborescence.h +808 -0
  116. data/ext/lemon-1.3.1/lemon/nagamochi_ibaraki.h +702 -0
  117. data/ext/lemon-1.3.1/lemon/nauty_reader.h +113 -0
  118. data/ext/lemon-1.3.1/lemon/nearest_neighbor_tsp.h +238 -0
  119. data/ext/lemon-1.3.1/lemon/network_simplex.h +1659 -0
  120. data/ext/lemon-1.3.1/lemon/opt2_tsp.h +367 -0
  121. data/ext/lemon-1.3.1/lemon/pairing_heap.h +474 -0
  122. data/ext/lemon-1.3.1/lemon/path.h +1164 -0
  123. data/ext/lemon-1.3.1/lemon/planarity.h +2754 -0
  124. data/ext/lemon-1.3.1/lemon/preflow.h +985 -0
  125. data/ext/lemon-1.3.1/lemon/quad_heap.h +343 -0
  126. data/ext/lemon-1.3.1/lemon/radix_heap.h +438 -0
  127. data/ext/lemon-1.3.1/lemon/radix_sort.h +487 -0
  128. data/ext/lemon-1.3.1/lemon/random.cc +29 -0
  129. data/ext/lemon-1.3.1/lemon/random.h +1005 -0
  130. data/ext/lemon-1.3.1/lemon/smart_graph.h +1344 -0
  131. data/ext/lemon-1.3.1/lemon/soplex.cc +465 -0
  132. data/ext/lemon-1.3.1/lemon/soplex.h +158 -0
  133. data/ext/lemon-1.3.1/lemon/static_graph.h +476 -0
  134. data/ext/lemon-1.3.1/lemon/suurballe.h +776 -0
  135. data/ext/lemon-1.3.1/lemon/time_measure.h +610 -0
  136. data/ext/lemon-1.3.1/lemon/tolerance.h +242 -0
  137. data/ext/lemon-1.3.1/lemon/unionfind.h +1824 -0
  138. data/ext/lemon-1.3.1/scripts/unify-sources.sh +390 -0
  139. data/ext/lemon-1.3.1/scripts/valgrind-wrapper.sh +22 -0
  140. data/ext/lemongraph/arc_map.cc +1007 -0
  141. data/ext/lemongraph/digraph.cc +282 -0
  142. data/ext/lemongraph/digraph_arc.cc +153 -0
  143. data/ext/lemongraph/digraph_node.cc +277 -0
  144. data/ext/lemongraph/edge_map.cc +770 -0
  145. data/ext/lemongraph/extconf.rb +53 -0
  146. data/ext/lemongraph/graph.cc +351 -0
  147. data/ext/lemongraph/graph_arc.cc +95 -0
  148. data/ext/lemongraph/graph_edge.cc +153 -0
  149. data/ext/lemongraph/graph_item.cc +76 -0
  150. data/ext/lemongraph/graph_node.cc +321 -0
  151. data/ext/lemongraph/lemongraph.cc +260 -0
  152. data/ext/lemongraph/lemongraph.hh +295 -0
  153. data/ext/lemongraph/lemongraph.map +6 -0
  154. data/ext/lemongraph/lemongraph_export.hh +31 -0
  155. data/ext/lemongraph/node_map.cc +1011 -0
  156. data/lemongraph.gemspec +176 -0
  157. data/lib/lemongraph/graphviz.rb +240 -0
  158. data/lib/lemongraph/version.rb +4 -0
  159. data/lib/lemongraph.rb +21 -0
  160. data/samples/lemondeps.rb +38 -0
  161. metadata +202 -0
@@ -0,0 +1,1011 @@
1
+ /* Copyright (C) 2022 Théotime Bollengier <theotime.bollengier@ensta-bretagne.fr>
2
+ *
3
+ * This file is part of LemonGraph. <https://gitlab.ensta-bretagne.fr/bollenth/lemongraph>
4
+ *
5
+ * LemonGraph is free software: you can redistribute it and/or modify it
6
+ * under the terms of the GNU General Public License as published
7
+ * by the Free Software Foundation, either version 3 of the License,
8
+ * or (at your option) any later version.
9
+ *
10
+ * LemonGraph is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+ * See the GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with LemonGraph. If not, see <https://www.gnu.org/licenses/>. 
17
+ */
18
+
19
+
20
+ /* TODO:
21
+ * select, select!, reject, reject!
22
+ */
23
+
24
+
25
+ #include <ruby.h>
26
+ #include "lemongraph.hh"
27
+
28
+
29
+ VALUE c_NodeMap;
30
+
31
+
32
+ namespace LemonGraph {
33
+
34
+ class NodeMap {
35
+ private:
36
+ VALUE m_self;
37
+ VALUE m_graph;
38
+ VALUE m_default_value;
39
+ VALUE m_default_proc;
40
+ union {
41
+ lemon::ListDigraph::NodeMap<RBValue> *m_dinodemap;
42
+ lemon::ListGraph::NodeMap<RBValue> *m_unnodemap;
43
+ void *m_ptr;
44
+ };
45
+ bool m_diunbar;
46
+ public:
47
+ NodeMap();
48
+ ~NodeMap();
49
+ void initialize(VALUE self, VALUE graph, VALUE default_value, VALUE default_proc);
50
+ void mark();
51
+ bool is_for_directed_graph() const { return m_diunbar; }
52
+ VALUE graph() const { return m_graph; }
53
+ VALUE default_value() const { return m_default_value; }
54
+ void set_default_value(VALUE dflt) { m_default_value = dflt; }
55
+ VALUE default_proc() const { return m_default_proc; }
56
+ void set_default_proc(VALUE prc);
57
+ RBValue& operator[](lemon::ListDigraph::Node& n);
58
+ RBValue& operator[](lemon::ListGraph::Node& n);
59
+ VALUE get(VALUE node);
60
+ void set(VALUE node, VALUE value);
61
+ VALUE keys();
62
+ VALUE values();
63
+ VALUE length();
64
+ VALUE is_empty();
65
+ VALUE each_node();
66
+ VALUE each_value();
67
+ VALUE each_pair();
68
+ void clear();
69
+ VALUE del(VALUE node);
70
+ VALUE del_if();
71
+ VALUE has_node(VALUE node);
72
+ VALUE has_value(VALUE val);
73
+ bool is_equal(const NodeMap& other);
74
+ VALUE hash();
75
+
76
+ private:
77
+ void check_key_di(VALUE node);
78
+ void check_key_un(VALUE node);
79
+ VALUE value_or_default(VALUE val, VALUE nodekey);
80
+ };
81
+
82
+
83
+ NodeMap::NodeMap() :
84
+ m_self(Qnil),
85
+ m_graph(Qnil),
86
+ m_default_value(Qnil),
87
+ m_default_proc(Qnil),
88
+ m_ptr(NULL),
89
+ m_diunbar(false)
90
+ {
91
+ }
92
+
93
+
94
+ NodeMap::~NodeMap()
95
+ {
96
+ if (m_ptr) {
97
+ if (m_diunbar)
98
+ delete m_dinodemap;
99
+ else if (rb_class_of(m_graph) == c_Graph)
100
+ delete m_unnodemap;
101
+ }
102
+ m_ptr = NULL;
103
+ }
104
+
105
+
106
+ void NodeMap::mark()
107
+ {
108
+ rb_gc_mark(m_graph);
109
+ rb_gc_mark(m_default_value);
110
+ rb_gc_mark(m_default_proc);
111
+ if (!m_ptr)
112
+ return;
113
+ if (m_diunbar) {
114
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
115
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n)
116
+ rb_gc_mark((*m_dinodemap)[n].value);
117
+ }
118
+ else if (rb_class_of(m_graph) == c_Graph) {
119
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
120
+ for (lemon::ListGraph::NodeIt n(g); n != lemon::INVALID; ++n)
121
+ rb_gc_mark((*m_unnodemap)[n].value);
122
+ }
123
+ }
124
+
125
+
126
+ void NodeMap::initialize(VALUE self, VALUE graph, VALUE default_value, VALUE default_proc)
127
+ {
128
+ if (m_self != Qnil)
129
+ rb_raise(rb_eRuntimeError, "NodeMap already initialized");
130
+ m_self = self;
131
+ m_graph = graph;
132
+ m_default_value = default_value;
133
+ m_default_proc = default_proc;
134
+ if (rb_obj_is_kind_of(m_graph, c_Digraph) == Qtrue) {
135
+ m_diunbar = true;
136
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
137
+ m_dinodemap = new lemon::ListDigraph::NodeMap<RBValue>(g);
138
+ }
139
+ else if (rb_obj_is_kind_of(m_graph, c_Graph) == Qtrue) {
140
+ m_diunbar = false;
141
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
142
+ m_unnodemap = new lemon::ListGraph::NodeMap<RBValue>(g);
143
+ }
144
+ else {
145
+ rb_raise(rb_eTypeError, "expecting a %" PRIsVALUE " or a %" PRIsVALUE ", not a %s",
146
+ rb_class_name(c_Digraph), rb_class_name(c_Graph), rb_obj_classname(m_graph));
147
+ }
148
+ }
149
+
150
+
151
+ void NodeMap::set_default_proc(VALUE prc)
152
+ {
153
+ if (!rb_obj_is_kind_of(prc, rb_cProc) && prc != Qnil) {
154
+ rb_raise(rb_eTypeError, "expecting a %" PRIsVALUE ", not a %s",
155
+ rb_class_name(rb_cProc), rb_obj_classname(prc));
156
+ }
157
+ m_default_proc = prc;
158
+ }
159
+
160
+
161
+ VALUE NodeMap::value_or_default(VALUE val, VALUE nodekey)
162
+ {
163
+ if (val == Qundef) {
164
+ if (m_default_proc != Qnil) {
165
+ VALUE args = rb_ary_new_from_args(2, nodekey, m_self);
166
+ val = rb_proc_call(m_default_proc, args);
167
+ }
168
+ else
169
+ val = m_default_value;
170
+ }
171
+ return val;
172
+ }
173
+
174
+
175
+ void NodeMap::check_key_di(VALUE node)
176
+ {
177
+ if (rb_class_of(node) != c_DiNode) {
178
+ rb_raise(rb_eTypeError, "expecting a %" PRIsVALUE " as key, not a %s",
179
+ rb_class_name(c_DiNode), rb_obj_classname(node));
180
+ }
181
+ VALUE rbg = rb_iv_get(node, "@graph");
182
+ if (rbg != m_graph)
183
+ rb_raise(rb_eRuntimeError, "key node and node map do not belong to the same graph");
184
+ }
185
+
186
+
187
+ void NodeMap::check_key_un(VALUE node)
188
+ {
189
+ if (rb_class_of(node) != c_UnNode) {
190
+ rb_raise(rb_eTypeError, "expecting a %" PRIsVALUE " as key, not a %s",
191
+ rb_class_name(c_UnNode), rb_obj_classname(node));
192
+ }
193
+ VALUE rbg = rb_iv_get(node, "@graph");
194
+ if (rbg != m_graph)
195
+ rb_raise(rb_eRuntimeError, "key node and node map do not belong to the same graph");
196
+ }
197
+
198
+
199
+ RBValue& NodeMap::operator[](lemon::ListDigraph::Node& n)
200
+ {
201
+ if (!m_dinodemap)
202
+ rb_raise(rb_eRuntimeError, "accessing empty NodeMap");
203
+ return (*m_dinodemap)[n];
204
+ }
205
+
206
+
207
+ RBValue& NodeMap::operator[](lemon::ListGraph::Node& n)
208
+ {
209
+ if (!m_unnodemap)
210
+ rb_raise(rb_eRuntimeError, "accessing empty NodeMap");
211
+ return (*m_unnodemap)[n];
212
+ }
213
+
214
+
215
+ VALUE NodeMap::get(VALUE node)
216
+ {
217
+ VALUE v = Qundef;
218
+ if (m_diunbar) {
219
+ check_key_di(node);
220
+ lemon::ListDigraph::Node n = lemongraph_rbdinode2dinode(node);
221
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
222
+ if (!g.valid(n))
223
+ rb_raise(rb_eRuntimeError, "key node is not a valid node for its graph");
224
+ v = (*m_dinodemap)[n].value;
225
+ }
226
+ else {
227
+ check_key_un(node);
228
+ lemon::ListGraph::Node n = lemongraph_rbunnode2unnode(node);
229
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
230
+ if (!g.valid(n))
231
+ rb_raise(rb_eRuntimeError, "key node is not a valid node for its graph");
232
+ v = (*m_unnodemap)[n].value;
233
+ }
234
+ return value_or_default(v, node);
235
+ }
236
+
237
+
238
+ void NodeMap::set(VALUE node, VALUE value)
239
+ {
240
+ if (m_diunbar) {
241
+ check_key_di(node);
242
+ lemon::ListDigraph::Node n = lemongraph_rbdinode2dinode(node);
243
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
244
+ if (!g.valid(n))
245
+ rb_raise(rb_eRuntimeError, "key node is not a valid node for its graph");
246
+ m_dinodemap->set(n, RBValue(value));
247
+ }
248
+ else {
249
+ check_key_un(node);
250
+ lemon::ListGraph::Node n = lemongraph_rbunnode2unnode(node);
251
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
252
+ if (!g.valid(n))
253
+ rb_raise(rb_eRuntimeError, "key node is not a valid node for its graph");
254
+ m_unnodemap->set(n, RBValue(value));
255
+ }
256
+ }
257
+
258
+
259
+ VALUE NodeMap::del(VALUE node)
260
+ {
261
+ VALUE v = Qundef;
262
+ if (m_diunbar) {
263
+ check_key_di(node);
264
+ lemon::ListDigraph::Node n = lemongraph_rbdinode2dinode(node);
265
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
266
+ if (!g.valid(n))
267
+ rb_raise(rb_eRuntimeError, "key node is not a valid node for its graph");
268
+ v = (*m_dinodemap)[n].value;
269
+ m_dinodemap->set(n, Qundef);
270
+ }
271
+ else {
272
+ check_key_un(node);
273
+ lemon::ListGraph::Node n = lemongraph_rbunnode2unnode(node);
274
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
275
+ if (!g.valid(n))
276
+ rb_raise(rb_eRuntimeError, "key node is not a valid node for its graph");
277
+ v = (*m_unnodemap)[n].value;
278
+ m_unnodemap->set(n, Qundef);
279
+ }
280
+ return value_or_default(v, node);
281
+ }
282
+
283
+
284
+ VALUE NodeMap::has_node(VALUE node)
285
+ {
286
+ VALUE klass = rb_class_of(node);
287
+ if (m_diunbar) {
288
+ if (klass != c_DiNode)
289
+ return Qfalse;
290
+ if (rb_iv_get(node, "@graph") != m_graph)
291
+ return Qfalse;
292
+ lemon::ListDigraph::Node n = lemongraph_rbdinode2dinode(node);
293
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
294
+ if (!g.valid(n))
295
+ return Qfalse;
296
+ if ((*m_dinodemap)[n].is_valid())
297
+ return Qtrue;
298
+ }
299
+ else {
300
+ if (klass != c_UnNode)
301
+ return Qfalse;
302
+ if (rb_iv_get(node, "@graph") != m_graph)
303
+ return Qfalse;
304
+ lemon::ListGraph::Node n = lemongraph_rbunnode2unnode(node);
305
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
306
+ if (!g.valid(n))
307
+ return Qfalse;
308
+ if ((*m_unnodemap)[n].is_valid())
309
+ return Qtrue;
310
+ }
311
+ return Qfalse;
312
+ }
313
+
314
+
315
+ VALUE NodeMap::has_value(VALUE value)
316
+ {
317
+ if (m_diunbar) {
318
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
319
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n) {
320
+ VALUE v = (*m_dinodemap)[n].value;
321
+ if (v != Qundef) {
322
+ if (rb_funcallv(v, id_eqeq, 1, &value) == Qtrue)
323
+ return Qtrue;
324
+ }
325
+ }
326
+ }
327
+ else {
328
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
329
+ for (lemon::ListGraph::NodeIt n(g); n != lemon::INVALID; ++n) {
330
+ VALUE v = (*m_unnodemap)[n].value;
331
+ if (v != Qundef) {
332
+ if (rb_funcallv(v, id_eqeq, 1, &value) == Qtrue)
333
+ return Qtrue;
334
+ }
335
+ }
336
+ }
337
+ return Qfalse;
338
+ }
339
+
340
+
341
+ VALUE NodeMap::keys()
342
+ {
343
+ int cnt = 0;
344
+ VALUE ar;
345
+ if (m_diunbar) {
346
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
347
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n) {
348
+ if ((*m_dinodemap)[n].is_valid())
349
+ cnt++;
350
+ }
351
+ ar = rb_ary_new_capa(cnt);
352
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n) {
353
+ if ((*m_dinodemap)[n].is_valid())
354
+ rb_ary_push(ar, lemongraph_make_dinode(n, m_graph));
355
+ }
356
+ }
357
+ else {
358
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
359
+ for (lemon::ListGraph::NodeIt n(g); n != lemon::INVALID; ++n) {
360
+ if ((*m_unnodemap)[n].is_valid())
361
+ cnt++;
362
+ }
363
+ ar = rb_ary_new_capa(cnt);
364
+ for (lemon::ListGraph::NodeIt n(g); n != lemon::INVALID; ++n) {
365
+ if ((*m_unnodemap)[n].is_valid())
366
+ rb_ary_push(ar, lemongraph_make_unnode(n, m_graph));
367
+ }
368
+ }
369
+ return ar;
370
+ }
371
+
372
+
373
+ VALUE NodeMap::values()
374
+ {
375
+ int cnt = 0;
376
+ VALUE ar;
377
+ if (m_diunbar) {
378
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
379
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n) {
380
+ if ((*m_dinodemap)[n].is_valid())
381
+ cnt++;
382
+ }
383
+ ar = rb_ary_new_capa(cnt);
384
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n) {
385
+ if ((*m_dinodemap)[n].is_valid())
386
+ rb_ary_push(ar, (*m_dinodemap)[n].value);
387
+ }
388
+ }
389
+ else {
390
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
391
+ for (lemon::ListGraph::NodeIt n(g); n != lemon::INVALID; ++n) {
392
+ if ((*m_unnodemap)[n].is_valid())
393
+ cnt++;
394
+ }
395
+ ar = rb_ary_new_capa(cnt);
396
+ for (lemon::ListGraph::NodeIt n(g); n != lemon::INVALID; ++n) {
397
+ if ((*m_unnodemap)[n].is_valid())
398
+ rb_ary_push(ar, (*m_unnodemap)[n].value);
399
+ }
400
+ }
401
+ return ar;
402
+ }
403
+
404
+
405
+ VALUE NodeMap::length()
406
+ {
407
+ int cnt = 0;
408
+ if (m_diunbar) {
409
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
410
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n) {
411
+ if ((*m_dinodemap)[n].is_valid())
412
+ cnt++;
413
+ }
414
+ }
415
+ else {
416
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
417
+ for (lemon::ListGraph::NodeIt n(g); n != lemon::INVALID; ++n) {
418
+ if ((*m_unnodemap)[n].is_valid())
419
+ cnt++;
420
+ }
421
+ }
422
+ return INT2NUM(cnt);
423
+ }
424
+
425
+
426
+ VALUE NodeMap::is_empty()
427
+ {
428
+ if (m_diunbar) {
429
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
430
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n) {
431
+ if ((*m_dinodemap)[n].is_valid())
432
+ return Qfalse;
433
+ }
434
+ }
435
+ else {
436
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
437
+ for (lemon::ListGraph::NodeIt n(g); n != lemon::INVALID; ++n) {
438
+ if ((*m_unnodemap)[n].is_valid())
439
+ return Qfalse;
440
+ }
441
+ }
442
+ return Qtrue;
443
+ }
444
+
445
+
446
+ static VALUE lemongraph_nodemap_enum_length(VALUE obj, VALUE args, VALUE eobj)
447
+ {
448
+ (void)args;
449
+ (void)eobj;
450
+ return lemongraph_nodemap_length(obj);
451
+ }
452
+
453
+
454
+ VALUE NodeMap::each_node()
455
+ {
456
+ RETURN_SIZED_ENUMERATOR(m_self, 0, 0, lemongraph_nodemap_enum_length);
457
+ if (m_diunbar) {
458
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
459
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n) {
460
+ if ((*m_dinodemap)[n].is_valid())
461
+ rb_yield(lemongraph_make_dinode(n, m_graph));
462
+ }
463
+ }
464
+ else {
465
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
466
+ for (lemon::ListGraph::NodeIt n(g); n != lemon::INVALID; ++n) {
467
+ if ((*m_unnodemap)[n].is_valid())
468
+ rb_yield(lemongraph_make_unnode(n, m_graph));
469
+ }
470
+ }
471
+ return m_self;
472
+ }
473
+
474
+
475
+ VALUE NodeMap::each_value()
476
+ {
477
+ RETURN_SIZED_ENUMERATOR(m_self, 0, 0, lemongraph_nodemap_enum_length);
478
+ if (m_diunbar) {
479
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
480
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n) {
481
+ VALUE v = (*m_dinodemap)[n].value;
482
+ if (v != Qundef)
483
+ rb_yield(v);
484
+ }
485
+ }
486
+ else {
487
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
488
+ for (lemon::ListGraph::NodeIt n(g); n != lemon::INVALID; ++n) {
489
+ VALUE v = (*m_unnodemap)[n].value;
490
+ if (v != Qundef)
491
+ rb_yield(v);
492
+ }
493
+ }
494
+ return m_self;
495
+ }
496
+
497
+
498
+ VALUE NodeMap::each_pair()
499
+ {
500
+ RETURN_SIZED_ENUMERATOR(m_self, 0, 0, lemongraph_nodemap_enum_length);
501
+ if (m_diunbar) {
502
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
503
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n) {
504
+ VALUE v = (*m_dinodemap)[n].value;
505
+ if (v != Qundef)
506
+ rb_yield_values(2, lemongraph_make_dinode(n, m_graph), v);
507
+ }
508
+ }
509
+ else {
510
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
511
+ for (lemon::ListGraph::NodeIt n(g); n != lemon::INVALID; ++n) {
512
+ VALUE v = (*m_unnodemap)[n].value;
513
+ if (v != Qundef)
514
+ rb_yield_values(2, lemongraph_make_unnode(n, m_graph), v);
515
+ }
516
+ }
517
+ return m_self;
518
+ }
519
+
520
+
521
+ VALUE NodeMap::del_if()
522
+ {
523
+ RETURN_SIZED_ENUMERATOR(m_self, 0, 0, lemongraph_nodemap_enum_length);
524
+ if (m_diunbar) {
525
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
526
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n) {
527
+ VALUE v = (*m_dinodemap)[n].value;
528
+ if (v != Qundef) {
529
+ VALUE b = rb_yield_values(2, lemongraph_make_dinode(n, m_graph), v);
530
+ if (b != Qnil && b != Qfalse)
531
+ m_dinodemap->set(n, Qundef);
532
+ }
533
+ }
534
+ }
535
+ else {
536
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
537
+ for (lemon::ListGraph::NodeIt n(g); n != lemon::INVALID; ++n) {
538
+ VALUE v = (*m_unnodemap)[n].value;
539
+ if (v != Qundef) {
540
+ VALUE b = rb_yield_values(2, lemongraph_make_unnode(n, m_graph), v);
541
+ if (b != Qnil && b != Qfalse)
542
+ m_unnodemap->set(n, Qundef);
543
+ }
544
+ }
545
+ }
546
+ return m_self;
547
+ }
548
+
549
+
550
+ void NodeMap::clear()
551
+ {
552
+ if (m_diunbar) {
553
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
554
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n)
555
+ m_dinodemap->set(n, Qundef);
556
+ }
557
+ else {
558
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
559
+ for (lemon::ListGraph::NodeIt n(g); n != lemon::INVALID; ++n)
560
+ m_unnodemap->set(n, Qundef);
561
+ }
562
+ }
563
+
564
+
565
+ bool NodeMap::is_equal(const NodeMap& other)
566
+ {
567
+ if (other.m_graph != m_graph)
568
+ return false;
569
+ if (other.m_diunbar != m_diunbar)
570
+ return false;
571
+ if (rb_funcallv(other.m_default_value, id_eqeq, 1, &m_default_value) != Qtrue)
572
+ return false;
573
+ if (rb_funcallv(other.m_default_proc, id_eqeq, 1, &m_default_proc) != Qtrue)
574
+ return false;
575
+ if (m_diunbar) {
576
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
577
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n) {
578
+ if ((*m_dinodemap)[n].value == Qundef) {
579
+ if ((*other.m_dinodemap)[n].value != Qundef)
580
+ return false;
581
+ }
582
+ else if (rb_funcall((*m_dinodemap)[n].value, id_eqeq, 1, (*other.m_dinodemap)[n].value) != Qtrue)
583
+ return false;
584
+ }
585
+ }
586
+ else {
587
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
588
+ for (lemon::ListGraph::NodeIt n(g); n != lemon::INVALID; ++n) {
589
+ if ((*m_unnodemap)[n].value == Qundef) {
590
+ if ((*other.m_unnodemap)[n].value != Qundef)
591
+ return false;
592
+ }
593
+ else if (rb_funcall((*m_unnodemap)[n].value, id_eqeq, 1, (*other.m_unnodemap)[n].value) != Qtrue)
594
+ return false;
595
+ }
596
+ }
597
+ return true;
598
+ }
599
+
600
+
601
+ VALUE NodeMap::hash()
602
+ {
603
+ st_index_t size = NUM2INT(length());
604
+ st_index_t hval = rb_hash_start(size);
605
+ hval = rb_hash_uint(hval, (st_index_t)lemongraph_nodemap_hash);
606
+ hval = rb_hash_uint(hval, NUM2LONG(rb_hash(m_graph)));
607
+ hval = rb_hash_uint(hval, NUM2LONG(rb_hash(m_default_value)));
608
+ hval = rb_hash_uint(hval, NUM2LONG(rb_hash(m_default_proc)));
609
+ if (m_diunbar) {
610
+ lemon::ListDigraph& g = lemongraph_digraph_rb2ref(m_graph);
611
+ for (lemon::ListDigraph::NodeIt n(g); n != lemon::INVALID; ++n) {
612
+ VALUE v = (*m_dinodemap)[n].value;
613
+ if (v != Qundef) {
614
+ hval = rb_hash_uint(hval, lemon::ListDigraph::id(n));
615
+ hval = rb_hash_uint(hval, NUM2LONG(rb_hash(v)));
616
+ }
617
+ }
618
+ }
619
+ else {
620
+ lemon::ListGraph& g = lemongraph_graph_rb2ref(m_graph);
621
+ for (lemon::ListGraph::NodeIt n(g); n != lemon::INVALID; ++n) {
622
+ VALUE v = (*m_unnodemap)[n].value;
623
+ if (v != Qundef) {
624
+ hval = rb_hash_uint(hval, lemon::ListGraph::id(n));
625
+ hval = rb_hash_uint(hval, NUM2LONG(rb_hash(v)));
626
+ }
627
+ }
628
+ }
629
+ hval = rb_hash_end(hval);
630
+ return ST2FIX(hval);
631
+ }
632
+
633
+
634
+ } // namespace LemonGraph
635
+
636
+
637
+ static void lemongraph_nodemap_mark(void *p)
638
+ {
639
+ LemonGraph::NodeMap *nm = (LemonGraph::NodeMap*)p;
640
+ nm->mark();
641
+ }
642
+
643
+
644
+ static void lemongraph_nodemap_free(void *p)
645
+ {
646
+ LemonGraph::NodeMap *nm = (LemonGraph::NodeMap*)p;
647
+ delete nm;
648
+ }
649
+
650
+
651
+ static size_t lemongraph_nodemap_size(const void* p)
652
+ {
653
+ return 0;
654
+ }
655
+
656
+
657
+ static const rb_data_type_t lemongraph_nodemap_type = {
658
+ .wrap_struct_name = "LemonGraph::NodeMap",
659
+ .function = {
660
+ .dmark = lemongraph_nodemap_mark,
661
+ .dfree = lemongraph_nodemap_free,
662
+ .dsize = lemongraph_nodemap_size,
663
+ },
664
+ .parent = NULL,
665
+ .data = NULL,
666
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
667
+ };
668
+
669
+
670
+ VALUE lemongraph_nodemap_alloc(VALUE klass)
671
+ {
672
+ LemonGraph::NodeMap *nm = new LemonGraph::NodeMap();
673
+ return TypedData_Wrap_Struct(klass, &lemongraph_nodemap_type, nm);
674
+ }
675
+
676
+
677
+ static inline LemonGraph::NodeMap& lemongraph_nodemap_rb2ref(VALUE obj) {
678
+ LemonGraph::NodeMap *nm;
679
+ TypedData_Get_Struct(obj, LemonGraph::NodeMap, &lemongraph_nodemap_type, nm);
680
+ return *nm;
681
+ }
682
+
683
+
684
+ /* Returns a new node map related to _graph_.
685
+ *
686
+ * If no block is given, _default_value_ will be returned when
687
+ * a value is fetched for a node for which no value was set.
688
+ *
689
+ * If a block is given, it will be called if needed
690
+ * to provide values for nodes for which no value was set, instead of returning _default_value_.
691
+ *
692
+ * @return [NodeMap]
693
+ * @overload initialize(graph, default_value = nil)
694
+ * @param graph [Graph, Digraph] the graph this node map is to be bound to
695
+ * @param default_value [Object] the default value returned for nodes with no value.
696
+ * @overload initialize(graph)
697
+ * @param graph [Graph, Digraph] the graph this node map is to be bound to
698
+ * @yieldparam node [Graph::Node,Digraph::Node] the node for which to provide a value
699
+ * @yieldparam nodemap [NodeMap] _self_
700
+ * @yieldreturn [Object] the default value returned for this _node_
701
+ */
702
+ VALUE lemongraph_nodemap_initialize(int argc, VALUE *argv, VALUE self)
703
+ {
704
+ VALUE rbg;
705
+ VALUE dflt = Qnil;
706
+ VALUE proc = Qnil;
707
+ rb_scan_args(argc, argv, "11&", &rbg, &dflt, &proc);
708
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
709
+ nm.initialize(self, rbg, dflt, proc);
710
+ return self;
711
+ }
712
+
713
+
714
+
715
+ /* Method called by _dup_ and _clone_ methods.
716
+ * @return [self]
717
+ */
718
+ VALUE lemongraph_nodemap_initialize_copy(VALUE self, VALUE orig)
719
+ {
720
+ rb_call_super(1, &orig);
721
+ LemonGraph::NodeMap& from = lemongraph_nodemap_rb2ref(orig);
722
+ LemonGraph::NodeMap& to = lemongraph_nodemap_rb2ref(self);
723
+ to.initialize(self, from.graph(), from.default_value(), from.default_proc());
724
+ if (from.is_for_directed_graph()) {
725
+ for (lemon::ListDigraph::NodeIt n(lemongraph_digraph_rb2ref(from.graph())); n != lemon::INVALID; ++n) {
726
+ const LemonGraph::RBValue& v = from[n];
727
+ if (v.is_valid())
728
+ to[n] = v;
729
+ }
730
+ }
731
+ else {
732
+ for (lemon::ListGraph::NodeIt n(lemongraph_graph_rb2ref(from.graph())); n != lemon::INVALID; ++n) {
733
+ const LemonGraph::RBValue& v = from[n];
734
+ if (v.is_valid())
735
+ to[n] = v;
736
+ }
737
+ }
738
+ return self;
739
+ }
740
+
741
+
742
+ /* Returns the graph this node map is related to.
743
+ * @return [Graph,Digraph]
744
+ */
745
+ VALUE lemongraph_nodemap_graph(VALUE self)
746
+ {
747
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
748
+ return nm.graph();
749
+ }
750
+
751
+
752
+ /* Returns the default value set for this node map.
753
+ * @return [Object]
754
+ */
755
+ VALUE lemongraph_nodemap_get_dflt_val(VALUE self)
756
+ {
757
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
758
+ return nm.default_value();
759
+ }
760
+
761
+
762
+ /* Sets the default value for this node map.
763
+ */
764
+ VALUE lemongraph_nodemap_set_dflt_val(VALUE self, VALUE dflt)
765
+ {
766
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
767
+ nm.set_default_value(dflt);
768
+ return self;
769
+ }
770
+
771
+
772
+ /* Returns the default proc set for this node map.
773
+ * @return [Proc, nil]
774
+ */
775
+ VALUE lemongraph_nodemap_get_dflt_proc(VALUE self)
776
+ {
777
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
778
+ return nm.default_proc();
779
+ }
780
+
781
+
782
+ /* Sets the default proc for this node map.
783
+ *
784
+ * If set, the default proc is called when a value is fetched for a node
785
+ * which was not assigned a value.
786
+ * The proc parameters must be the node key and the node map.
787
+ *
788
+ * Set to _nil_ to reset it so that the default value is returned
789
+ * when needed instead of calling the default proc.
790
+ * @param proc [Proc, nil]
791
+ */
792
+ VALUE lemongraph_nodemap_set_dflt_proc(VALUE self, VALUE proc)
793
+ {
794
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
795
+ nm.set_default_proc(proc);
796
+ return self;
797
+ }
798
+
799
+
800
+ /* Returns the value associated with the given node key.
801
+ * @param key [Graph::Node,Digraph::Node]
802
+ * @return [Object]
803
+ */
804
+ VALUE lemongraph_nodemap_get(VALUE self, VALUE key)
805
+ {
806
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
807
+ return nm.get(key);
808
+ }
809
+
810
+
811
+ /* Associates the given value with the given node key; returns value.
812
+ * @param key [Graph::Node, Digraph::Node]
813
+ * @param value [Object]
814
+ */
815
+ VALUE lemongraph_nodemap_set(VALUE self, VALUE key, VALUE value)
816
+ {
817
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
818
+ nm.set(key, value);
819
+ return value;
820
+ }
821
+
822
+
823
+ /* Returns an array containing all node keys for which a value has been set.
824
+ * @return [Array<Graph::Node,Digraph::Node>]
825
+ */
826
+ VALUE lemongraph_nodemap_nodes(VALUE self)
827
+ {
828
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
829
+ return nm.keys();
830
+ }
831
+
832
+
833
+ /* Returns an array containing all values set for nodes.
834
+ * @return [Array<Object>]
835
+ */
836
+ VALUE lemongraph_nodemap_values(VALUE self)
837
+ {
838
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
839
+ return nm.values();
840
+ }
841
+
842
+
843
+ /* Return the count of entries in _slef_ for which a value has been set
844
+ * @return [Integer]
845
+ */
846
+ VALUE lemongraph_nodemap_length(VALUE self)
847
+ {
848
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
849
+ return nm.length();
850
+ }
851
+
852
+
853
+ /* Returns _true_ if there are no entries, _false_ otherwise
854
+ * @return [Boolean]
855
+ */
856
+ VALUE lemongraph_nodemap_is_empty(VALUE self)
857
+ {
858
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
859
+ return nm.is_empty();
860
+ }
861
+
862
+
863
+ /* Calls the block, if given, once for each node key for which a value has been set.
864
+ * The nodes are passed as parameters to the block.
865
+ *
866
+ * Returns _self_, or, if no block is given, an Enumerator is returned.
867
+ * @return [self, Enumerator]
868
+ * @overload each_node
869
+ * @yieldparam node [Graph::Node,Digraph::Node]
870
+ * @return [self]
871
+ * @overload each_node
872
+ * @return [Enumerator]
873
+ */
874
+ VALUE lemongraph_nodemap_each_node(VALUE self)
875
+ {
876
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
877
+ return nm.each_node();
878
+ }
879
+
880
+
881
+ /* Calls the block, if given, once for each value that has been set.
882
+ * The values are passed as parameters to the block.
883
+ *
884
+ * Returns _self_, or, if no block is given, an Enumerator is returned.
885
+ * @return [self, Enumerator]
886
+ * @overload each_value
887
+ * @yieldparam value [Object]
888
+ * @return [self]
889
+ * @overload each_value
890
+ * @return [Enumerator]
891
+ */
892
+ VALUE lemongraph_nodemap_each_value(VALUE self)
893
+ {
894
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
895
+ return nm.each_value();
896
+ }
897
+
898
+
899
+ /* Calls the block, if given, once for each node key and value pair.
900
+ * The nodes and values are passed as parameters to the block.
901
+ *
902
+ * Returns _self_, or, if no block is given, an Enumerator is returned.
903
+ * @return [self, Enumerator]
904
+ * @overload each_pair
905
+ * @yieldparam node [Graph::Node,Digraph::Node]
906
+ * @yieldparam value [Object]
907
+ * @return [self]
908
+ * @overload each_pair
909
+ * @return [Enumerator]
910
+ * @overload each
911
+ * @yieldparam node [Graph::Node,Digraph::Node]
912
+ * @yieldparam value [Object]
913
+ * @return [self]
914
+ * @overload each
915
+ * @return [Enumerator]
916
+ */
917
+ VALUE lemongraph_nodemap_each_pair(VALUE self)
918
+ {
919
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
920
+ return nm.each_pair();
921
+ }
922
+
923
+
924
+ /* Removes all values.
925
+ * @return [self]
926
+ */
927
+ VALUE lemongraph_nodemap_clear(VALUE self)
928
+ {
929
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
930
+ nm.clear();
931
+ return self;
932
+ }
933
+
934
+
935
+ /* Deletes the entry for the given node and returns its associated value, or the default one.
936
+ * @param key [Graph::Node,Digraph::Node]
937
+ */
938
+ VALUE lemongraph_nodemap_delete(VALUE self, VALUE key)
939
+ {
940
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
941
+ return nm.del(key);
942
+ }
943
+
944
+
945
+ /* Delete entries for which the block returns a truthy value.
946
+ * Returns _self_, or, if no block is given, an Enumerator is returned.
947
+ *
948
+ * @return [self, Enumerator]
949
+ * @overload delete_if
950
+ * Calls the block with each node-value pair;
951
+ * deletes each entry for which the block returns a truthy value;
952
+ * returns self
953
+ * @yieldparam node [Graph::Node,Digraph::Node]
954
+ * @yieldparam value [Object]
955
+ * @yieldreturn [Boolean] whether to delete or not the entry
956
+ * @return [self]
957
+ * @overload delete_if
958
+ * @return [Enumerator]
959
+ */
960
+ VALUE lemongraph_nodemap_delete_if(VALUE self)
961
+ {
962
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
963
+ return nm.del_if();
964
+ }
965
+
966
+
967
+ /* Returns _true_ if a value was set for _node_, otherwise _false_.
968
+ * @param node [Graph::Node,Digraph::Node]
969
+ * @return [Boolean]
970
+ */
971
+ VALUE lemongraph_nodemap_has_node(VALUE self, VALUE node)
972
+ {
973
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
974
+ return nm.has_node(node);
975
+ }
976
+
977
+
978
+ /* Returns _true_ if _value_ is a value in _self_, otherwise _false_.
979
+ * @return [Boolean]
980
+ */
981
+ VALUE lemongraph_nodemap_has_value(VALUE self, VALUE value)
982
+ {
983
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
984
+ return nm.has_value(value);
985
+ }
986
+
987
+
988
+ /* Returns _true_ if _other_ is a NodeMap and share the same graph, default value and proc as _self_
989
+ * and and all entries from _other_ and _self_ are equal (==).
990
+ * @return [Boolean]
991
+ */
992
+ VALUE lemongraph_nodemap_is_equal(VALUE self, VALUE other)
993
+ {
994
+ if (rb_obj_is_kind_of(other, c_NodeMap) != Qtrue)
995
+ return Qfalse;
996
+ LemonGraph::NodeMap& m = lemongraph_nodemap_rb2ref(self);
997
+ LemonGraph::NodeMap& o = lemongraph_nodemap_rb2ref(other);
998
+ return o.is_equal(m) ? Qtrue : Qfalse;
999
+ }
1000
+
1001
+
1002
+ /* Returns the integer hash value for _self_.
1003
+ * @return [Integer]
1004
+ */
1005
+ VALUE lemongraph_nodemap_hash(VALUE self)
1006
+ {
1007
+ LemonGraph::NodeMap& nm = lemongraph_nodemap_rb2ref(self);
1008
+ return nm.hash();
1009
+ }
1010
+
1011
+