42 template<
typename PAIR>
43 bool invalid_extremities(
const PAIR& p) {
return p.first ==
nullptr || p.second ==
nullptr;}
45 template<
typename PAIR>
46 auto& other_extremity(
const PAIR& p,
const typename PAIR::first_type& me) {
52 template<
typename VERTEX_VALUE,
typename EDGE_VALUE>
class graph;
53 template<
typename VERTEX_VALUE,
typename EDGE_VALUE>
class graph_;
54 template<
typename VERTEX_VALUE,
typename EDGE_VALUE>
class vertex;
55 template<
typename VERTEX_VALUE,
typename EDGE_VALUE>
class edge;
57 template<
typename VERTEX_VALUE,
typename EDGE_VALUE>
61 friend class graph_<VERTEX_VALUE, EDGE_VALUE>;
63 std::atomic_bool killed;
76 void kill() {killed =
true;}
84 template<
typename VALUE,
typename VERTEX_VALUE,
typename EDGE_VALUE>
95 using value_type = VALUE;
100 VALUE& operator()() {
return v;}
101 const VALUE& operator()()
const {
return v;}
104 template<
typename VERTEX_VALUE,
typename EDGE_VALUE>
112 using value_type = void;
119 template<
typename VERTEX_VALUE,
typename EDGE_VALUE>
123 friend class graph_<VERTEX_VALUE, EDGE_VALUE>;
124 friend class graph<VERTEX_VALUE, EDGE_VALUE>;
126 std::list<std::weak_ptr<edge<VERTEX_VALUE, EDGE_VALUE> > > E;
127 bool garbaging =
true;
132 template<
typename EDGE_FUN>
133 void foreach_edge_garbaging_on(
const EDGE_FUN& fun) {
135 while(it != E.end()) {
137 if(e ==
nullptr || e->is_killed())
149 template<
typename EDGE_FUN>
150 void foreach_edge_garbaging_off(
const EDGE_FUN& fun) {
152 if(
auto e = wp.lock(); e && !(e->is_killed()))
158 using edge_val_type = EDGE_VALUE;
159 using ref_edge_type = std::shared_ptr<edge<VERTEX_VALUE, EDGE_VALUE> >;
162 vertex(
const vertex&) =
delete;
163 vertex& operator=(
const vertex&) =
delete;
165 template<
typename EDGE_FUN>
166 void foreach_edge(
const EDGE_FUN& fun) {
167 if(garbaging) foreach_edge_garbaging_on(fun);
168 else foreach_edge_garbaging_off(fun);
172 template<
typename VERTEX_VALUE,
typename EDGE_VALUE>
173 class edge :
public valued_graph_element<EDGE_VALUE, VERTEX_VALUE, EDGE_VALUE> {
176 friend class graph<VERTEX_VALUE, EDGE_VALUE>;
177 friend class graph_<VERTEX_VALUE, EDGE_VALUE>;
179 std::weak_ptr<vertex<VERTEX_VALUE, EDGE_VALUE> > v1, v2;
181 edge(
const std::shared_ptr<vertex<VERTEX_VALUE, EDGE_VALUE> >& v1,
const std::shared_ptr<vertex<VERTEX_VALUE, EDGE_VALUE> >& v2,
const EDGE_VALUE& v) : valued_graph_element<EDGE_VALUE, VERTEX_VALUE, EDGE_VALUE>(v), v1(v1), v2(v2) {}
185 using vertex_val_type = VERTEX_VALUE;
188 edge(
const edge&) =
delete;
189 edge& operator=(
const edge&) =
delete;
192 auto res = std::make_pair(v1.lock(), v2.lock());
193 if(res.first !=
nullptr && res.first->is_killed())
195 if(res.second !=
nullptr && res.second->is_killed())
196 res.second =
nullptr;
201 template<
typename VERTEX_VALUE>
205 friend class graph_<VERTEX_VALUE, void>;
206 friend class graph<VERTEX_VALUE, void>;
208 std::weak_ptr<vertex<VERTEX_VALUE, void> > v1, v2;
214 using vertex_val_type = VERTEX_VALUE;
218 edge& operator=(
const edge&) =
delete;
221 auto res = std::make_pair(v1.lock(), v2.lock());
222 if(res.first !=
nullptr && res.first->is_killed())
224 if(res.second !=
nullptr && res.second->is_killed())
225 res.second =
nullptr;
231 template<
typename VERTEX_VALUE,
typename EDGE_VALUE>
236 using vertex_value_type = VERTEX_VALUE;
237 using ref_vertex = std::shared_ptr<vertex_type>;
240 using edge_value_type = EDGE_VALUE;
241 using ref_edge = std::shared_ptr<edge_type>;
243 using wref_vertex = std::weak_ptr<vertex_type>;
244 using wref_edge = std::weak_ptr<edge_type>;
245 using vertices = std::list<ref_vertex>;
246 using edges = std::list<ref_edge>;
247 using weak_vertices = std::list<wref_vertex>;
248 using weak_edges = std::list<wref_edge>;
260 bool garbaging =
true;
262 template<
typename VERTEX_FUN>
263 void foreach_vertex_garbaging_on(
const VERTEX_FUN& fun) {
265 while(it != V.end()) {
267 if(v ==
nullptr || v->is_killed())
279 template<
typename VERTEX_FUN>
280 void foreach_vertex_garbaging_off(
const VERTEX_FUN& fun) {
282 if(v && !(v->is_killed()))
286 template<
typename EDGE_FUN>
287 void foreach_edge_garbaging_on(
const EDGE_FUN& fun) {
289 while(it != E.end()) {
291 if(e ==
nullptr || e->is_killed())
303 template<
typename EDGE_FUN>
304 void foreach_edge_garbaging_off(
const EDGE_FUN& fun) {
306 if(e && !(e->is_killed()))
325 unsigned int res = 0;
326 this->foreach_vertex([&res](
const ref_vertex&) {++res;});
334 unsigned int res = 0;
335 this->foreach_edge([&res](
const ref_edge& ref_e) {
336 auto extr_pair = ref_e->extremities();
337 if(vq3::invalid_extremities(extr_pair)) {
359 ref_edge
get_edge(
const ref_vertex& v1,
const ref_vertex& v2)
const {
362 if(v1->E.size() > v2->E.size()) {
371 for(
auto& we : v->E) {
374 auto ref_v1 = e->v1.lock();
375 if(ref_v1 !=
nullptr) {
376 auto ref_v2 = e->v2.lock();
377 if(ref_v2 !=
nullptr && (ref_v1 == vv || ref_v2 == vv))
386 template<
typename VERTEX_FUN>
387 void foreach_vertex(
const VERTEX_FUN& fun) {
388 if(garbaging) foreach_vertex_garbaging_on(fun);
389 else foreach_vertex_garbaging_off(fun);
392 template<
typename EDGE_FUN>
393 void foreach_edge(
const EDGE_FUN& fun) {
394 if(garbaging) foreach_edge_garbaging_on(fun);
395 else foreach_edge_garbaging_off(fun);
404 foreach_vertex_garbaging_on([](
const ref_vertex& ref_v) {ref_v->garbaging =
false;});
416 foreach_vertex_garbaging_on([](
const ref_vertex& ref_v) {ref_v->garbaging =
true;});
430 foreach_edge_garbaging_on([](
const ref_edge& ref_e) {
431 if(
auto extr_pair = ref_e->extremities(); vq3::invalid_extremities(extr_pair))
435 foreach_vertex_garbaging_on([](
const ref_vertex& ref_v) {
436 ref_v->foreach_edge_garbaging_on([](
const ref_edge&) {});
445 template<
typename VERTEX_VALUE,
447 class graph :
public graph_<VERTEX_VALUE, EDGE_VALUE> {
452 std::function<void (std::ostream&,
const VERTEX_VALUE&)> vertex_to_stream;
453 std::function<void (std::ostream&,
const EDGE_VALUE&)> edge_to_stream;
454 std::function<void (std::istream&, VERTEX_VALUE&)> vertex_from_stream;
455 std::function<void (std::istream&, EDGE_VALUE&)> edge_from_stream;
458 graph(
const graph&) =
delete;
459 graph& operator=(
const graph&) =
delete;
465 typename graph_<VERTEX_VALUE, EDGE_VALUE>::ref_edge
connect(
const typename graph_<VERTEX_VALUE, EDGE_VALUE>::ref_vertex& v1,
const typename graph_<VERTEX_VALUE, EDGE_VALUE>::ref_vertex& v2,
const typename graph_<VERTEX_VALUE, EDGE_VALUE>::edge_value_type& v) {
467 v1->E.push_back(res);
468 v2->E.push_back(res);
469 this->E.push_back(res);
477 typename graph_<VERTEX_VALUE, EDGE_VALUE>::ref_edge
connect(
const typename graph_<VERTEX_VALUE, EDGE_VALUE>::ref_vertex& v1,
const typename graph_<VERTEX_VALUE, EDGE_VALUE>::ref_vertex& v2) {
479 v1->E.push_back(res);
480 v2->E.push_back(res);
481 this->E.push_back(res);
489 std::map<typename graph_<VERTEX_VALUE, EDGE_VALUE>::ref_vertex,
unsigned int> vertex_idf;
490 unsigned int idf = 0;
492 os << this->nb_vertices() << std::endl;
493 this->foreach_vertex([&idf, &vertex_idf, &os,
this](
auto& ref_v){
494 vertex_idf[ref_v] = idf++;
495 vertex_to_stream(os, (*ref_v)());
499 os << this->nb_edges() << std::endl;
500 this->foreach_edge([&vertex_idf, &os,
this](
auto& ref_e){
501 auto extr_pair = ref_e->extremities();
502 os << vertex_idf[extr_pair.first] <<
' ' << vertex_idf[extr_pair.second] << std::endl;
503 edge_to_stream(os, (*ref_e)());
513 this->foreach_vertex([](
auto ref_v){ref_v->kill();});
514 this->foreach_edge ([](
auto ref_e){ref_e->kill();});
518 typename graph_<VERTEX_VALUE, EDGE_VALUE>::vertex_value_type v {};
519 typename graph_<VERTEX_VALUE, EDGE_VALUE>::edge_value_type e {};
522 std::vector<typename graph_<VERTEX_VALUE, EDGE_VALUE>::ref_vertex> vtx(nb);
523 for(
auto& ref_v : vtx) {
524 vertex_from_stream(is, v);
526 ref_v = ((*this) += v);
530 for(
unsigned int i=0; i < nb; ++i) {
532 is >> v1 >> v2; is.get(c);
533 edge_from_stream(is, e);
536 this->
connect(vtx[v1], vtx[v2], e);
541 template<
typename VERTEX_VALUE>
542 class graph<VERTEX_VALUE, void> :
public graph_<VERTEX_VALUE, void> {
548 std::function<void (std::ostream&,
const VERTEX_VALUE&)> vertex_to_stream;
549 std::function<void (std::istream&, VERTEX_VALUE&)> vertex_from_stream;
564 v1->E.push_back(res);
565 v2->E.push_back(res);
566 this->E.push_back(res);
574 std::map<typename graph_<VERTEX_VALUE, void>::ref_vertex,
unsigned int> vertex_idf;
575 unsigned int idf = 0;
577 os << this->nb_vertices() << std::endl;
578 this->foreach_vertex([&idf, &vertex_idf, &os,
this](
auto& ref_v){
579 vertex_idf[ref_v] = idf++;
580 vertex_to_stream(os, (*ref_v)());
584 os << this->nb_edges() << std::endl;
585 this->foreach_edge([&vertex_idf, &os](
auto& ref_e){
586 auto extr_pair = ref_e->extremities();
587 os << vertex_idf[extr_pair.first] <<
' ' << vertex_idf[extr_pair.second] << std::endl;
596 this->foreach_vertex([](
auto ref_v){ref_v->kill();});
597 this->foreach_edge ([](
auto ref_e){ref_e->kill();});
604 std::vector<typename graph_<VERTEX_VALUE, void>::ref_vertex> vtx(nb);
605 for(
auto& ref_v : vtx) {
606 vertex_from_stream(is, v);
608 ref_v = ((*this) += v);
612 for(
unsigned int i=0; i < nb; ++i) {
614 is >> v1 >> v2; is.get(c);
615 this->
connect(vtx[v1], vtx[v2]);
621 template<
typename VERTEX_VALUE,
typename EDGE_VALUE>
622 std::ostream& operator<<(std::ostream& os, graph<VERTEX_VALUE, EDGE_VALUE>& g) {
627 template<
typename VERTEX_VALUE,
typename EDGE_VALUE>
628 std::istream& operator>>(std::istream& is, graph<VERTEX_VALUE, EDGE_VALUE>& g) {