@@ -201,9 +201,10 @@ class Vector;
201201// strong integer types (e.g. `StrongInt`). Strong integer types are types that
202202// behave like integers (comparison, arithmetic, etc.), and are (explicitly)
203203// constructible/convertible from/to integers.
204- template <typename NodeIndexType = int32_t , typename ArcIndexType = int32_t ,
205- bool HasNegativeReverseArcs = false >
206- class BaseGraph {
204+ template <typename Impl, typename NodeIndexType = int32_t ,
205+ typename ArcIndexType = int32_t , bool HasNegativeReverseArcs = false >
206+ class BaseGraph //
207+ {
207208 public:
208209 // Typedef so you can use Graph::NodeIndex and Graph::ArcIndex to be generic
209210 // but also to improve the readability of your code. We also recommend
@@ -291,6 +292,21 @@ class BaseGraph {
291292 static constexpr ArcIndexType kNilArc =
292293 std::numeric_limits<ArcIndexType>::max();
293294
295+ // Some graph implementations need to be finalized with Build() before they
296+ // can be used. Build() may change the arc indices (which had been the
297+ // return values of previous AddArc() calls): the new index of former arc #i
298+ // will be stored in permutation[i] if #i is smaller than permutation.size(),
299+ // or will be unchanged otherwise. If you don't care about these, just call
300+ // the simple no-output version Build().
301+ //
302+ // Note that some implementations become immutable after calling Build().
303+ // By default, Build() is a no-op.
304+ virtual void Build (std::vector<ArcIndexType>* permutation) {
305+ if (permutation != nullptr ) permutation->clear ();
306+ }
307+ void Build () { Build (nullptr ); }
308+ virtual bool IsBuilt () const { return true ; }
309+
294310 protected:
295311 // Functions commented when defined because they are implementation details.
296312 void ComputeCumulativeSum (internal::Vector<NodeIndexType, ArcIndexType>* v);
@@ -643,8 +659,11 @@ struct GraphTraits {
643659// result in the same order).
644660//
645661template <typename NodeIndexType = int32_t , typename ArcIndexType = int32_t >
646- class ListGraph : public BaseGraph <NodeIndexType, ArcIndexType, false > {
647- typedef BaseGraph<NodeIndexType, ArcIndexType, false > Base;
662+ class ListGraph : public BaseGraph <ListGraph<NodeIndexType, ArcIndexType>,
663+ NodeIndexType, ArcIndexType, false > {
664+ typedef BaseGraph<ListGraph<NodeIndexType, ArcIndexType>, NodeIndexType,
665+ ArcIndexType, false >
666+ Base;
648667 using Base::arc_capacity_;
649668 using Base::const_capacities_;
650669 using Base::node_capacity_;
@@ -679,17 +698,6 @@ class ListGraph : public BaseGraph<NodeIndexType, ArcIndexType, false> {
679698 // Note: Self referencing arcs and duplicate arcs are supported.
680699 ArcIndexType AddArc (NodeIndexType tail, NodeIndexType head);
681700
682- // Some graph implementations need to be finalized with Build() before they
683- // can be used. After Build() is called, the arc indices (which had been the
684- // return values of previous AddArc() calls) may change: the new index of
685- // former arc #i will be stored in permutation[i] if #i is smaller than
686- // permutation.size() or will be unchanged otherwise. If you don't care about
687- // these, just call the simple no-output version Build().
688- //
689- // Note that some implementations become immutable after calling Build().
690- void Build () { Build (nullptr ); }
691- void Build (std::vector<ArcIndexType>* permutation);
692-
693701 // Returns the tail/head of a valid arc.
694702 NodeIndexType Tail (ArcIndexType arc) const ;
695703 NodeIndexType Head (ArcIndexType arc) const ;
@@ -759,8 +767,11 @@ class ListGraph : public BaseGraph<NodeIndexType, ArcIndexType, false> {
759767// StaticGraphWithoutTail<>. This almost corresponds to a past implementation
760768// of StaticGraph<> @CL 116144340.
761769template <typename NodeIndexType = int32_t , typename ArcIndexType = int32_t >
762- class StaticGraph : public BaseGraph <NodeIndexType, ArcIndexType, false > {
763- typedef BaseGraph<NodeIndexType, ArcIndexType, false > Base;
770+ class StaticGraph : public BaseGraph <StaticGraph<NodeIndexType, ArcIndexType>,
771+ NodeIndexType, ArcIndexType, false > {
772+ typedef BaseGraph<StaticGraph<NodeIndexType, ArcIndexType>, NodeIndexType,
773+ ArcIndexType, false >
774+ Base;
764775 using Base::arc_capacity_;
765776 using Base::const_capacities_;
766777 using Base::node_capacity_;
@@ -811,8 +822,9 @@ class StaticGraph : public BaseGraph<NodeIndexType, ArcIndexType, false> {
811822 void AddNode (NodeIndexType node);
812823 ArcIndexType AddArc (NodeIndexType tail, NodeIndexType head);
813824
825+ void Build (std::vector<ArcIndexType>* permutation) final ;
814826 void Build () { Build (nullptr ); }
815- void Build (std::vector<ArcIndexType>* permutation);
827+ bool IsBuilt () const final { return is_built_; }
816828
817829 private:
818830 ArcIndexType DirectArcLimit (NodeIndexType node) const {
@@ -839,11 +851,14 @@ class StaticGraph : public BaseGraph<NodeIndexType, ArcIndexType, false> {
839851// + 2 * (ArcIndexType + NodeIndexType) * arc_capacity() memory.
840852template <typename NodeIndexType = int32_t , typename ArcIndexType = int32_t >
841853class ReverseArcListGraph
842- : public BaseGraph<NodeIndexType, ArcIndexType, true > {
854+ : public BaseGraph<ReverseArcListGraph<NodeIndexType, ArcIndexType>,
855+ NodeIndexType, ArcIndexType, true > {
843856 static_assert (internal::IsSigned<ArcIndexType>(),
844857 " ArcIndexType must be signed" );
845858
846- typedef BaseGraph<NodeIndexType, ArcIndexType, true > Base;
859+ typedef BaseGraph<ReverseArcListGraph<NodeIndexType, ArcIndexType>,
860+ NodeIndexType, ArcIndexType, true >
861+ Base;
847862 using Base::arc_capacity_;
848863 using Base::const_capacities_;
849864 using Base::node_capacity_;
@@ -954,9 +969,6 @@ class ReverseArcListGraph
954969 void AddNode (NodeIndexType node);
955970 ArcIndexType AddArc (NodeIndexType tail, NodeIndexType head);
956971
957- void Build () { Build (nullptr ); }
958- void Build (std::vector<ArcIndexType>* permutation);
959-
960972 private:
961973 internal::Vector<NodeIndexType, ArcIndexType> start_;
962974 internal::Vector<NodeIndexType, ArcIndexType> reverse_start_;
@@ -975,11 +987,14 @@ class ReverseArcListGraph
975987// time lookup function).
976988template <typename NodeIndexType = int32_t , typename ArcIndexType = int32_t >
977989class ReverseArcStaticGraph
978- : public BaseGraph<NodeIndexType, ArcIndexType, true > {
990+ : public BaseGraph<ReverseArcStaticGraph<NodeIndexType, ArcIndexType>,
991+ NodeIndexType, ArcIndexType, true > {
979992 static_assert (internal::IsSigned<ArcIndexType>(),
980993 " ArcIndexType must be signed" );
981994
982- typedef BaseGraph<NodeIndexType, ArcIndexType, true > Base;
995+ typedef BaseGraph<ReverseArcStaticGraph<NodeIndexType, ArcIndexType>,
996+ NodeIndexType, ArcIndexType, true >
997+ Base;
983998 using Base::arc_capacity_;
984999 using Base::const_capacities_;
9851000 using Base::node_capacity_;
@@ -1069,8 +1084,9 @@ class ReverseArcStaticGraph
10691084 void AddNode (NodeIndexType node);
10701085 ArcIndexType AddArc (NodeIndexType tail, NodeIndexType head);
10711086
1087+ void Build (std::vector<ArcIndexType>* permutation) final ;
10721088 void Build () { Build (nullptr ); }
1073- void Build (std::vector<ArcIndexType>* permutation);
1089+ bool IsBuilt () const final { return is_built_; }
10741090
10751091 private:
10761092 ArcIndexType DirectArcLimit (NodeIndexType node) const {
@@ -1124,41 +1140,42 @@ void Permute(const IntVector& permutation, Array* array_to_permute) {
11241140
11251141// BaseGraph implementation ----------------------------------------------------
11261142
1127- template <typename NodeIndexType, typename ArcIndexType,
1143+ template <typename Impl, typename NodeIndexType, typename ArcIndexType,
11281144 bool HasNegativeReverseArcs>
1129- IntegerRange<NodeIndexType> BaseGraph<
1130- NodeIndexType, ArcIndexType, HasNegativeReverseArcs>::AllNodes() const {
1145+ IntegerRange<NodeIndexType>
1146+ BaseGraph<Impl, NodeIndexType, ArcIndexType, HasNegativeReverseArcs>::AllNodes()
1147+ const {
11311148 return IntegerRange<NodeIndexType>(NodeIndexType (0 ), num_nodes_);
11321149}
11331150
1134- template <typename NodeIndexType, typename ArcIndexType,
1151+ template <typename Impl, typename NodeIndexType, typename ArcIndexType,
11351152 bool HasNegativeReverseArcs>
1136- IntegerRange<ArcIndexType>
1137- BaseGraph<NodeIndexType, ArcIndexType, HasNegativeReverseArcs>::AllForwardArcs()
1153+ IntegerRange<ArcIndexType> BaseGraph<Impl, NodeIndexType, ArcIndexType,
1154+ HasNegativeReverseArcs>::AllForwardArcs()
11381155 const {
11391156 return IntegerRange<ArcIndexType>(ArcIndexType (0 ), num_arcs_);
11401157}
11411158
1142- template <typename NodeIndexType, typename ArcIndexType,
1159+ template <typename Impl, typename NodeIndexType, typename ArcIndexType,
11431160 bool HasNegativeReverseArcs>
1144- NodeIndexType BaseGraph<NodeIndexType, ArcIndexType,
1161+ NodeIndexType BaseGraph<Impl, NodeIndexType, ArcIndexType,
11451162 HasNegativeReverseArcs>::node_capacity() const {
11461163 // TODO(user): Is it needed? remove completely? return the real capacities
11471164 // at the cost of having a different implementation for each graphs?
11481165 return node_capacity_ > num_nodes_ ? node_capacity_ : num_nodes_;
11491166}
11501167
1151- template <typename NodeIndexType, typename ArcIndexType,
1168+ template <typename Impl, typename NodeIndexType, typename ArcIndexType,
11521169 bool HasNegativeReverseArcs>
1153- ArcIndexType BaseGraph<NodeIndexType, ArcIndexType,
1170+ ArcIndexType BaseGraph<Impl, NodeIndexType, ArcIndexType,
11541171 HasNegativeReverseArcs>::arc_capacity() const {
11551172 // TODO(user): Same questions as the ones in node_capacity().
11561173 return arc_capacity_ > num_arcs_ ? arc_capacity_ : num_arcs_;
11571174}
11581175
1159- template <typename NodeIndexType, typename ArcIndexType,
1176+ template <typename Impl, typename NodeIndexType, typename ArcIndexType,
11601177 bool HasNegativeReverseArcs>
1161- void BaseGraph<NodeIndexType, ArcIndexType,
1178+ void BaseGraph<Impl, NodeIndexType, ArcIndexType,
11621179 HasNegativeReverseArcs>::FreezeCapacities() {
11631180 // TODO(user): Only define this in debug mode at the cost of having a lot
11641181 // of ifndef NDEBUG all over the place? remove the function completely ?
@@ -1169,9 +1186,9 @@ void BaseGraph<NodeIndexType, ArcIndexType,
11691186
11701187// Computes the cumulative sum of the entry in v. We only use it with
11711188// in/out degree distribution, hence the Check() at the end.
1172- template <typename NodeIndexType, typename ArcIndexType,
1189+ template <typename Impl, typename NodeIndexType, typename ArcIndexType,
11731190 bool HasNegativeReverseArcs>
1174- void BaseGraph<NodeIndexType, ArcIndexType, HasNegativeReverseArcs>::
1191+ void BaseGraph<Impl, NodeIndexType, ArcIndexType, HasNegativeReverseArcs>::
11751192 ComputeCumulativeSum (internal::Vector<NodeIndexType, ArcIndexType>* v) {
11761193 DCHECK_EQ (v->size (), num_nodes_ + NodeIndexType (1 ));
11771194 ArcIndexType sum (0 );
@@ -1189,9 +1206,9 @@ void BaseGraph<NodeIndexType, ArcIndexType, HasNegativeReverseArcs>::
11891206// - Put the head of the new arc #i in (*head)[i].
11901207// - Put in start[i] the index of the first arc with tail >= i.
11911208// - Update "permutation" to reflect the change, unless it is NULL.
1192- template <typename NodeIndexType, typename ArcIndexType,
1209+ template <typename Impl, typename NodeIndexType, typename ArcIndexType,
11931210 bool HasNegativeReverseArcs>
1194- void BaseGraph<NodeIndexType, ArcIndexType, HasNegativeReverseArcs>::
1211+ void BaseGraph<Impl, NodeIndexType, ArcIndexType, HasNegativeReverseArcs>::
11951212 BuildStartAndForwardHead (
11961213 internal::SVector<ArcIndexType, NodeIndexType>* head,
11971214 internal::Vector<NodeIndexType, ArcIndexType>* start,
@@ -1362,14 +1379,6 @@ void ListGraph<NodeIndexType, ArcIndexType>::ReserveArcs(ArcIndexType bound) {
13621379 next_.reserve (bound);
13631380}
13641381
1365- template <typename NodeIndexType, typename ArcIndexType>
1366- void ListGraph<NodeIndexType, ArcIndexType>::Build(
1367- std::vector<ArcIndexType>* permutation) {
1368- if (permutation != nullptr ) {
1369- permutation->clear ();
1370- }
1371- }
1372-
13731382// StaticGraph implementation --------------------------------------------------
13741383
13751384template <typename NodeIndexType, typename ArcIndexType>
@@ -1627,14 +1636,6 @@ ArcIndexType ReverseArcListGraph<NodeIndexType, ArcIndexType>::AddArc(
16271636 return num_arcs_++;
16281637}
16291638
1630- template <typename NodeIndexType, typename ArcIndexType>
1631- void ReverseArcListGraph<NodeIndexType, ArcIndexType>::Build(
1632- std::vector<ArcIndexType>* permutation) {
1633- if (permutation != nullptr ) {
1634- permutation->clear ();
1635- }
1636- }
1637-
16381639template <typename NodeIndexType, typename ArcIndexType>
16391640class ReverseArcListGraph <NodeIndexType,
16401641 ArcIndexType>::OutgoingOrOppositeIncomingArcIterator {
@@ -1852,8 +1853,12 @@ class ReverseArcStaticGraph<
18521853// Nodes and arcs are implicit and not stored.
18531854
18541855template <typename NodeIndexType = int32_t , typename ArcIndexType = int32_t >
1855- class CompleteGraph : public BaseGraph <NodeIndexType, ArcIndexType, false > {
1856- typedef BaseGraph<NodeIndexType, ArcIndexType, false > Base;
1856+ class CompleteGraph
1857+ : public BaseGraph<CompleteGraph<NodeIndexType, ArcIndexType>,
1858+ NodeIndexType, ArcIndexType, false > {
1859+ typedef BaseGraph<CompleteGraph<NodeIndexType, ArcIndexType>, NodeIndexType,
1860+ ArcIndexType, false >
1861+ Base;
18571862 using Base::arc_capacity_;
18581863 using Base::const_capacities_;
18591864 using Base::node_capacity_;
@@ -1936,8 +1941,11 @@ CompleteGraph<NodeIndexType, ArcIndexType>::operator[](
19361941
19371942template <typename NodeIndexType = int32_t , typename ArcIndexType = int32_t >
19381943class CompleteBipartiteGraph
1939- : public BaseGraph<NodeIndexType, ArcIndexType, false > {
1940- typedef BaseGraph<NodeIndexType, ArcIndexType, false > Base;
1944+ : public BaseGraph<CompleteBipartiteGraph<NodeIndexType, ArcIndexType>,
1945+ NodeIndexType, ArcIndexType, false > {
1946+ typedef BaseGraph<CompleteBipartiteGraph<NodeIndexType, ArcIndexType>,
1947+ NodeIndexType, ArcIndexType, false >
1948+ Base;
19411949 using Base::arc_capacity_;
19421950 using Base::const_capacities_;
19431951 using Base::node_capacity_;
0 commit comments