COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/concept/graph_component.h @ 961:289d80c33f04

Last change on this file since 961:289d80c33f04 was 961:289d80c33f04, checked in by Mihaly Barasz, 15 years ago
  • Somewhat less redundant and a bit more correct graph concepts.
  • graph_wrapper_test does not compile
File size: 21.4 KB
Line 
1/* -*- C++ -*-
2 * src/lemon/concept/graph_component.h - Part of LEMON, a generic C++ optimization library
3 *
4 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
6 *
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
10 *
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
13 * purpose.
14 *
15 */
16
17///\ingroup concept
18///\file
19///\brief The graph components.
20
21
22#ifndef LEMON_CONCEPT_GRAPH_COMPONENT_H
23#define LEMON_CONCEPT_GRAPH_COMPONENT_H
24
25#include <lemon/invalid.h>
26#include <lemon/concept/maps.h>
27
28namespace lemon {
29  namespace concept {
30
31
32    /****************   Graph iterator concepts   ****************/
33
34    /// Skeleton class for graph Node and Edge
35
36    /// \note Because Node and Edge are forbidden to inherit from the same
37    /// base class, this is a template. For Node you shoul instantiate it
38    /// with character 'n' and for Edge with 'e'.
39
40    template<char Ch>
41    class GraphItem {
42    public:
43      GraphItem() {}
44      GraphItem(Invalid) {}
45
46      // We explicitely list these:
47      GraphItem(GraphItem const&) {}
48      GraphItem& operator=(GraphItem const&) { return *this; }
49
50      bool operator==(GraphItem) const { return false; }
51      bool operator!=(GraphItem) const { return false; }
52
53      // Technical requirement. Do we really need this?
54      bool operator<(GraphItem) const { return false; }
55    };
56
57
58    template<typename GI>
59    struct GraphItemConcept {
60      void constraints() {
61        GI i1;
62        GI i2 = i1;
63        GI i3 = INVALID;
64       
65        i1 = i2 = i3;
66
67        bool b;
68        b = (ia == ib) && (ia != ib) && (ia < ib);
69        b = (ia == INVALID) && (ib != INVALID);
70      }
71
72      const GI &ia;
73      const GI &ib;
74    };
75
76
77    template<typename Iter, typename Graph, typename BaseItem>
78    struct GraphIteratorConcept {
79      void constraints() {
80        function_requires< GraphItemConcept<Iter> >();
81        Iter it1(g);
82
83        /// \todo Do we need NodeIt(Node) kind of constructor?
84        //      Iter it2(bj);
85        Iter it2;
86
87        it2 = ++it1;
88        ++it2 = it1;
89        ++(++it1);
90        /// \bug This should be: is_base_and_derived<BaseItem, Iter>
91        BaseItem bi = it1;
92        bi = it2;
93      }
94
95      BaseItem bj;
96      Graph g;
97    };
98
99    template<typename Iter, typename Graph>
100    struct GraphIncIteratorConcept {
101      typedef typename Graph::Node Node;
102      typedef typename Graph::Edge Edge;
103      void constraints() {
104        function_requires< GraphItemConcept<Iter> >();
105        Iter it1(graph, node);
106        /// \todo Do we need OutEdgeIt(Edge) kind of constructor?
107        //      Iter it2(edge);
108        Iter it2;
109
110        it2 = ++it1;
111        ++it2 = it1;
112        ++(++it1);
113        Edge e = it1;
114        e = it2;
115      }
116
117      Edge edge;
118      Node node;
119      Graph graph;
120    };
121
122
123
124    /// An empty base graph class.
125 
126    /// This class provides the minimal set of features needed for a graph
127    /// structure. All graph concepts have to be conform to this base
128    /// graph.
129    ///
130    /// \bug This is not true. The minimal graph concept is the
131    /// BaseIterableGraphComponent.
132
133    class BaseGraphComponent {
134    public:
135
136      typedef BaseGraphComponent Graph;
137     
138      /// Node class of the graph.
139
140      /// This class represents the Nodes of the graph.
141      ///
142      class Node {
143      public:
144
145        /// Default constructor.
146
147        /// @warning The default constructor sets the iterator
148        /// to an undefined value.
149
150        Node() {}
151        /// Copy constructor.
152
153        /// Copy constructor.
154        ///
155        Node(const Node&) {}
156
157        /// Invalid constructor \& conversion.
158
159        /// This constructor initializes the iterator to be invalid.
160        /// \sa Invalid for more details.
161        Node(Invalid) {}
162
163
164        Node& operator=(const Node&) { return *this;}
165
166        /// Equality operator.
167
168        /// Two iterators are equal if and only if they represents the
169        /// same node in the graph or both are invalid.
170        bool operator==(const Node&) const { return true;}
171
172
173        /// Inequality operator.
174       
175        /// \sa operator==(const Node& n)
176        ///
177        bool operator!=(const Node&) const { return true;}
178
179        /// Comparison operator.
180
181        /// This is a strict ordering between the nodes.
182        ///
183        /// This ordering can be different from the iterating order of nodes.
184        /// \todo Possibly we don't need it.
185        bool operator<(const Node&) const { return true;}
186      };
187
188      /// Edge class of the graph.
189
190      /// This class represents the Edges of the graph.
191      ///
192      class Edge {
193      public:
194
195        /// Default constructor.
196
197        /// @warning The default constructor sets the iterator
198        /// to an undefined value.
199
200        Edge() {}
201        /// Copy constructor.
202
203        /// Copy constructor.
204        ///
205        Edge(const Edge&) {}
206
207        /// Invalid constructor \& conversion.
208
209        /// This constructor initializes the iterator to be invalid.
210        /// \sa Invalid for more details.
211        Edge(Invalid) {}
212
213
214        Edge& operator=(const Edge&) { return *this;}
215
216        /// Equality operator.
217
218        /// Two iterators are equal if and only if they represents the
219        /// same edge in the graph or both are invalid.
220        bool operator==(const Edge&) const { return true;}
221
222
223        /// Inequality operator.
224       
225        /// \sa operator==(const Edge& n)
226        ///
227        bool operator!=(const Edge&) const { return true;}
228
229        /// Comparison operator.
230
231        /// This is a strict ordering between the edges.
232        ///
233        /// This ordering can be different from the iterating order of edges.
234        /// \todo Possibly we don't need it.
235        bool operator<(const Edge&) const { return true;}
236      };
237
238      ///Gives back the head node of an edge.
239
240      ///Gives back the head node of an edge.
241      ///
242      Node head(const Edge&) const { return INVALID;}
243
244      ///Gives back the tail node of an edge.
245
246      ///Gives back the tail node of an edge.
247      ///
248      Node tail(const Edge&) const { return INVALID;}
249    };
250
251
252    /// Concept check structure for BaseGraph.
253
254    /// Concept check structure for BaseGraph.
255    ///
256
257    template <typename Graph>
258    struct BaseGraphComponentConcept {
259      typedef typename Graph::Node Node;
260      typedef typename Graph::Edge Edge;
261     
262      void constraints() {
263        function_requires< GraphItemConcept<Node> >();
264        function_requires< GraphItemConcept<Edge> >();
265        {
266          const Graph& const_graph = graph;
267          Node n;
268          Edge e;
269          n = const_graph.tail(e);
270          n = const_graph.head(e);
271        }     
272      }
273     
274      Graph& graph;
275    };
276
277    /// An empty iterable base graph class.
278 
279    /// This class provides beside the core graph features
280    /// core iterable interface for the graph structure.
281    /// Most of the base graphs should be conform to this concept.
282
283    class BaseIterableGraphComponent : virtual public BaseGraphComponent {
284    public:
285
286      typedef BaseGraphComponent::Node Node;
287      typedef BaseGraphComponent::Edge Edge;
288
289      /// Gives back the first Node in the iterating order.
290     
291      /// Gives back the first Node in the iterating order.
292      ///     
293      void first(Node&) const {}
294
295      /// Gives back the next Node in the iterating order.
296     
297      /// Gives back the next Node in the iterating order.
298      ///     
299      void next(Node&) const {}
300
301      /// Gives back the first Edge in the iterating order.
302     
303      /// Gives back the first Edge in the iterating order.
304      ///     
305      void first(Edge&) const {}
306      /// Gives back the next Edge in the iterating order.
307     
308      /// Gives back the next Edge in the iterating order.
309      ///     
310      void next(Edge&) const {}
311
312
313      /// Gives back the first of the Edges point to the given Node.
314     
315      /// Gives back the first of the Edges point to the given Node.
316      ///     
317      void firstIn(Edge&, const Node&) const {}
318
319      /// Gives back the next of the Edges points to the given Node.
320
321
322      /// Gives back the next of the Edges points to the given Node.
323      ///
324      void nextIn(Edge&) const {}
325
326      /// Gives back the first of the Edges start from the given Node.
327     
328      /// Gives back the first of the Edges start from the given Node.
329      ///     
330      void firstOut(Edge&, const Node&) const {}
331
332      /// Gives back the next of the Edges start from the given Node.
333     
334      /// Gives back the next of the Edges start from the given Node.
335      ///     
336      void nextOut(Edge&) const {}
337    };
338
339
340    /// Concept check structure for IterableBaseGraph.
341
342    /// Concept check structure for IterableBaseGraph.
343    ///
344    template <typename Graph>
345    struct BaseIterableGraphComponentConcept {
346     
347      void constraints() {
348        function_requires< BaseGraphComponentConcept<Graph> >();
349        typename Graph::Node node;     
350        typename Graph::Edge edge;
351        {
352          graph.first(node);
353          graph.next(node);
354        }
355        {
356          graph.first(edge);
357          graph.next(edge);
358        }
359        {
360          graph.firstIn(edge, node);
361          graph.nextIn(edge);
362        }
363        {
364          graph.firstOut(edge, node);
365          graph.nextOut(edge);
366        }
367      }
368
369      const Graph& graph;
370    };
371
372    /// An empty idable base graph class.
373 
374    /// This class provides beside the core graph features
375    /// core id functions for the graph structure.
376    /// The most of the base graphs should be conform to this concept.
377    /// The id's are unique and immutable.
378
379    class IDableGraphComponent : virtual public BaseGraphComponent {
380    public:
381
382      typedef BaseGraphComponent::Node Node;
383      typedef BaseGraphComponent::Edge Edge;
384
385      /// Gives back an unique integer id for the Node.
386
387      /// Gives back an unique integer id for the Node.
388      ///
389      int id(const Node&) const { return -1;}
390
391      /// Gives back an unique integer id for the Edge.
392
393      /// Gives back an unique integer id for the Edge.
394      ///
395      int id(const Edge&) const { return -1;}
396    };
397
398
399    /// Concept check structure for IdableBaseGraph.
400
401    /// Concept check structure for IdableBaseGraph.
402    ///
403    template <typename Graph>
404    struct IDableGraphComponentConcept {
405
406      void constraints() {
407        function_requires< BaseGraphComponentConcept<Graph> >();
408        typename Graph::Node node;
409        int nid = graph.id(node);
410        nid = graph.id(node);
411        typename Graph::Edge edge;
412        int eid = graph.id(edge);
413        eid = graph.id(edge);
414      }
415
416      const Graph& graph;
417    };
418
419
420    /// An empty max-idable base graph class.
421 
422    /// This class provides beside the core graph features
423    /// core max id functions for the graph structure.
424    /// The most of the base graphs should be conform to this concept.
425    /// The id's are unique and immutable.
426    class MaxIDableGraphComponent : virtual public BaseGraphComponent {
427    public:
428
429      /// Gives back an integer greater or equal to the maximum Node id.
430
431      /// Gives back an integer greater or equal to the maximum Node id.
432      ///
433      int maxEdgeId() const { return -1;}
434
435      /// Gives back an integer greater or equal to the maximum Edge id.
436
437      /// Gives back an integer greater or equal to the maximum Edge id.
438      ///
439      int maxNodeId() const { return -1;}
440    };
441
442    /// Concept check structure for MaxIdableBaseGraph.
443
444    /// Concept check structure for MaxIdableBaseGraph.
445    ///
446    template <typename Graph>
447    struct MaxIDableGraphComponentConcept {
448
449      void constraints() {
450        function_requires< BaseGraphComponentConcept<Graph> >();
451        int nid = graph.maxEdgeId();
452        ignore_unused_variable_warning(nid);
453        int eid = graph.maxNodeId();
454        ignore_unused_variable_warning(eid);
455      }
456
457      const Graph& graph;
458    };
459
460    /// An empty extendable base graph class.
461 
462    /// This class provides beside the core graph features
463    /// core graph extend interface for the graph structure.
464    /// The most of the base graphs should be conform to this concept.
465    class BaseExtendableGraphComponent : virtual public BaseGraphComponent {
466    public:
467
468      typedef BaseGraphComponent::Node Node;
469      typedef BaseGraphComponent::Edge Edge;
470
471      /// Adds a new Node to the graph.
472
473      /// Adds a new Node to the graph.
474      ///
475      Node addNode() {
476        return INVALID;
477      }
478   
479      /// Adds a new Edge connects the two Nodes to the graph.
480
481      /// Adds a new Edge connects the two Nodes to the graph.
482      ///
483      Edge addEdge(const Node& from, const Node& to) {
484        return INVALID;
485      }
486
487    };
488
489    /// Concept check structure for ExtendableBaseGraph.
490
491    /// Concept check structure for ExtendableBaseGraph.
492    ///
493    template <typename Graph>
494    struct BaseExtendableGraphComponentConcept {
495      void constraints() {
496        function_requires< BaseGraphComponentConcept<Graph> >();
497        typename Graph::Node node_a, node_b;
498        node_a = graph.addNode();
499        typename Graph::Edge edge;
500        edge = graph.addEdge(node_a, node_b);
501      }
502
503      Graph& graph;
504    };
505
506    /// An empty erasable base graph class.
507 
508    /// This class provides beside the core graph features
509    /// core erase functions for the graph structure.
510    /// The most of the base graphs should be conform to this concept.
511    class BaseErasableGraphComponent : virtual public BaseGraphComponent {
512    public:
513
514      typedef BaseGraphComponent::Node Node;
515      typedef BaseGraphComponent::Edge Edge;
516
517      /// Erase a Node from the graph.
518     
519      /// Erase a Node from the graph. This function should not
520      /// erase edges connecting to the Node.
521      void erase(const Node&) {}   
522
523      /// Erase an Edge from the graph.
524
525      /// Erase an Edge from the graph.
526      ///
527      void erase(const Edge&) {}
528
529    };
530
531    /// Concept check structure for ErasableBaseGraph.
532
533    /// Concept check structure for ErasableBaseGraph.
534    ///
535    template <typename Graph>
536    struct BaseErasableGraphComponentConcept {
537      void constraints() {
538        function_requires< BaseGraphComponentConcept<Graph> >();
539        typename Graph::Node node;
540        graph.erase(node);
541        typename Graph::Edge edge;
542        graph.erase(edge);
543      }
544
545      Graph& graph;
546    };
547
548    /// An empty clearable base graph class.
549 
550    /// This class provides beside the core graph features
551    /// core clear functions for the graph structure.
552    /// The most of the base graphs should be conform to this concept.
553    class BaseClearableGraphComponent : virtual public BaseGraphComponent {
554    public:
555
556      /// Erase all the Nodes and Edges from the graph.
557
558      /// Erase all the Nodes and Edges from the graph.
559      ///
560      void clear() {}   
561    };
562
563    /// Concept check function for ErasableBaseGraph.
564
565    /// Concept check function for ErasableBaseGraph.
566    ///
567    template <typename Graph>
568    struct BaseClearableGraphComponentConcept {
569      void constraints() {
570        function_requires< BaseGraphComponentConcept<Graph> >();
571        graph.clear();
572      }
573
574      Graph& graph;
575    };
576
577
578    class IterableGraphComponent :
579      virtual public BaseIterableGraphComponent {
580
581    public:
582   
583      typedef IterableGraphComponent Graph;
584
585      typedef BaseGraphComponent::Node Node;
586      typedef BaseGraphComponent::Edge Edge;
587
588      class NodeIt : public Node {
589      public:
590        NodeIt() {}
591        NodeIt(Invalid) {}
592        // explicit NodeIt(Node) {}
593        explicit NodeIt(const Graph&) {}
594
595        NodeIt& operator++() { return *this; }
596        //      Node operator*() const { return INVALID; }
597
598        bool operator==(const NodeIt&) const { return true;}
599        bool operator!=(const NodeIt&) const { return true;}
600      };
601
602      class EdgeIt : public Edge {
603      public:
604        EdgeIt() {}
605        EdgeIt(Invalid) {}
606        // explicit EdgeIt(Edge) {}
607        explicit EdgeIt(const Graph&) {}
608
609        EdgeIt& operator++() { return *this; }
610        //      Edge operator*() const { return INVALID; }
611
612        bool operator==(const EdgeIt&) const { return true;}
613        bool operator!=(const EdgeIt&) const { return true;}
614      };
615
616      class InEdgeIt : public Edge {
617      public:
618        InEdgeIt() {}
619        InEdgeIt(Invalid) {}
620        // explicit InEdgeIt(Edge) {}
621        explicit InEdgeIt(const Graph&, const Node&) {}
622
623        InEdgeIt& operator++() { return *this; }
624        //      Edge operator*() const { return INVALID; }
625
626        bool operator==(const InEdgeIt&) const { return true;}
627        bool operator!=(const InEdgeIt&) const { return true;}
628      };
629
630      class OutEdgeIt : public Edge {
631      public:
632        OutEdgeIt() {}
633        OutEdgeIt(Invalid) {}
634        // explicit OutEdgeIt(Edge) {}
635        explicit OutEdgeIt(const Graph&, const Node&) {}
636
637        OutEdgeIt& operator++() { return *this; }
638        //      Edge operator*() const { return INVALID; }
639
640        bool operator==(const OutEdgeIt&) const { return true;}
641        bool operator!=(const OutEdgeIt&) const { return true;}
642      };
643
644    };
645   
646    template <typename Graph>
647    struct IterableGraphComponentConcept {
648
649      void constraints() {
650        function_requires< BaseIterableGraphComponentConcept<Graph> >();
651
652        typedef typename Graph::Node Node;
653        typedef typename Graph::NodeIt NodeIt;
654        typedef typename Graph::Edge Edge;
655        typedef typename Graph::EdgeIt EdgeIt;
656        typedef typename Graph::InEdgeIt InEdgeIt;
657        typedef typename Graph::OutEdgeIt OutEdgeIt;
658 
659        function_requires< GraphIteratorConcept<NodeIt, Graph, Node> >();
660        function_requires< GraphIteratorConcept<EdgeIt, Graph, Edge> >();
661        function_requires< GraphIncIteratorConcept<OutEdgeIt, Graph> >();
662        function_requires< GraphIncIteratorConcept<InEdgeIt, Graph> >();
663      }
664      Graph& graph;
665    };
666
667
668    class IdMappableGraphComponent : virtual public BaseGraphComponent {
669
670      typedef IdMappableGraphComponent Graph;
671
672    public:
673
674      typedef BaseGraphComponent::Node Node;
675      typedef BaseGraphComponent::Edge Edge;
676
677      class NodeIdMap : public ReadMap<Node, int> {
678      public:
679        NodeIdMap(const Graph&) {}
680        int maxId() const { return -1;}
681      };
682
683      class EdgeIdMap : public ReadMap<Edge, int> {
684      public:
685        EdgeIdMap(const Graph&) {}
686        int maxId() const { return -1;}
687      };
688
689    };
690   
691    template <typename Graph>
692    struct IdMappableGraphComponentConcept {
693      void constraints() {     
694        function_requires< BaseGraphComponentConcept<Graph> >();
695        {
696          typedef typename Graph::EdgeIdMap EdgeIdMap;
697          function_requires<ReadMapConcept<EdgeIdMap> >();
698          EdgeIdMap edge_map(graph);
699          int n = edge_map.maxId();
700          ignore_unused_variable_warning(n);
701        }
702        {
703          typedef typename Graph::NodeIdMap NodeIdMap;
704          function_requires<ReadMapConcept<NodeIdMap> >();
705          NodeIdMap node_map(graph);
706          int n = node_map.maxId();
707          ignore_unused_variable_warning(n);
708        }
709      }
710      Graph& graph;
711    };
712
713
714    class MappableGraphComponent : virtual public BaseGraphComponent {
715    public:
716
717      typedef MappableGraphComponent Graph;
718
719      typedef BaseGraphComponent::Node Node;
720      typedef BaseGraphComponent::Edge Edge;
721
722      template <typename Value>
723      class NodeMap : public ReferenceMap<Node, Value> {
724      public:
725        NodeMap(const Graph&) {}
726        NodeMap(const Graph&, const Value&) {}
727        NodeMap(const NodeMap&) {}
728
729        NodeMap& operator=(const NodeMap&) { return *this;}
730       
731      };
732
733      template <typename Value>
734      class EdgeMap : public ReferenceMap<Edge, Value> {
735      public:
736        EdgeMap(const Graph&) {}
737        EdgeMap(const Graph&, const Value&) {}
738        EdgeMap(const EdgeMap&) {}
739
740        EdgeMap& operator=(const EdgeMap&) { return *this;}
741       
742      };
743
744    };
745
746    template <typename Graph>
747    struct MappableGraphComponentConcept {
748
749      struct Type {
750        int value;
751        Type() : value(0) {}
752        Type(int _v) : value(_v) {}
753      };
754
755      void constraints() {
756        function_requires< BaseGraphComponentConcept<Graph> >();
757        { // int map test
758          typedef typename Graph::template NodeMap<int> IntNodeMap;
759          function_requires<GraphMapConcept<IntNodeMap,Graph> >();
760        } { // bool map test
761          typedef typename Graph::template NodeMap<bool> BoolNodeMap;
762          function_requires<GraphMapConcept<BoolNodeMap,Graph> >();
763        } { // Type map test
764          typedef typename Graph::template NodeMap<Type> TypeNodeMap;
765          function_requires<GraphMapConcept<TypeNodeMap,Graph> >();
766        }
767
768        { // int map test
769          typedef typename Graph::template EdgeMap<int> IntEdgeMap;
770          function_requires<GraphMapConcept<IntEdgeMap,Graph> >();
771        } { // bool map test
772          typedef typename Graph::template EdgeMap<bool> BoolEdgeMap;
773          function_requires<GraphMapConcept<BoolEdgeMap,Graph> >();
774        } { // Type map test
775          typedef typename Graph::template EdgeMap<Type> TypeEdgeMap;
776          function_requires<GraphMapConcept<TypeEdgeMap,Graph> >();
777        }
778      }
779
780      Graph& graph;
781    };
782
783
784    class ExtendableGraphComponent : virtual public BaseGraphComponent {
785    public:
786
787      typedef ExtendableGraphComponent Graph;
788
789      typedef BaseGraphComponent::Node Node;
790      typedef BaseGraphComponent::Edge Edge;
791
792      Node addNode() {
793        return INVALID;
794      }
795   
796      Edge addEdge(const Node& from, const Node& to) {
797        return INVALID;
798      }
799
800    };
801
802    template <typename Graph>
803    struct ExtendableGraphComponentConcept {
804      void constraints() {
805        function_requires< BaseGraphComponentConcept<Graph> >();
806        typename Graph::Node node_a, node_b;
807        node_a = graph.addNode();
808        typename Graph::Edge edge;
809        edge = graph.addEdge(node_a, node_b);     
810      }
811      Graph& graph;
812    };
813
814    class ErasableGraphComponent : virtual public BaseGraphComponent {
815    public:
816
817      typedef ErasableGraphComponent Graph;
818
819      typedef BaseGraphComponent::Node Node;
820      typedef BaseGraphComponent::Edge Edge;
821
822      void erase(const Node&) {}   
823      void erase(const Edge&) {}
824
825    };
826
827    template <typename Graph>
828    struct ErasableGraphComponentConcept {
829      void constraints() {
830        function_requires< BaseGraphComponentConcept<Graph> >();
831        typename Graph::Node node;
832        graph.erase(node);
833        typename Graph::Edge edge;
834        graph.erase(edge);     
835      }
836
837      Graph& graph;
838    };
839
840    class ClearableGraphComponent : virtual public BaseGraphComponent {
841    public:
842
843      typedef ClearableGraphComponent Graph;
844
845      typedef BaseGraphComponent::Node Node;
846      typedef BaseGraphComponent::Edge Edge;
847
848      void clear() {}   
849
850    };
851
852    template <typename Graph>
853    struct ClearableGraphComponentConcept {
854      void constraints() {
855        function_requires< BaseGraphComponentConcept<Graph> >();
856        graph.clear();
857      }
858      Graph& graph;
859    };
860
861  }
862
863}
864
865#endif
Note: See TracBrowser for help on using the repository browser.