gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Doc improvement for visitor classes (ticket #134)
0 2 0
default
2 files changed with 10 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 384 line context
... ...
@@ -1073,384 +1073,389 @@
1073 1073
    ///\brief \ref named-templ-param "Named parameter"
1074 1074
    ///for setting \ref PredMap object.
1075 1075
    ///
1076 1076
    /// \ref named-templ-param "Named parameter"
1077 1077
    ///for setting \ref PredMap object.
1078 1078
    template<class T>
1079 1079
    BfsWizard<DefPredMapBase<T> > predMap(const T &t)
1080 1080
    {
1081 1081
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
1082 1082
      return BfsWizard<DefPredMapBase<T> >(*this);
1083 1083
    }
1084 1084

	
1085 1085
    template<class T>
1086 1086
    struct DefReachedMapBase : public Base {
1087 1087
      typedef T ReachedMap;
1088 1088
      static ReachedMap *createReachedMap(const Digraph &) { return 0; };
1089 1089
      DefReachedMapBase(const TR &b) : TR(b) {}
1090 1090
    };
1091 1091
    ///\brief \ref named-templ-param "Named parameter"
1092 1092
    ///for setting \ref ReachedMap object.
1093 1093
    ///
1094 1094
    /// \ref named-templ-param "Named parameter"
1095 1095
    ///for setting \ref ReachedMap object.
1096 1096
    template<class T>
1097 1097
    BfsWizard<DefReachedMapBase<T> > reachedMap(const T &t)
1098 1098
    {
1099 1099
      Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
1100 1100
      return BfsWizard<DefReachedMapBase<T> >(*this);
1101 1101
    }
1102 1102

	
1103 1103
    template<class T>
1104 1104
    struct DefProcessedMapBase : public Base {
1105 1105
      typedef T ProcessedMap;
1106 1106
      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
1107 1107
      DefProcessedMapBase(const TR &b) : TR(b) {}
1108 1108
    };
1109 1109
    ///\brief \ref named-templ-param "Named parameter"
1110 1110
    ///for setting \ref ProcessedMap object.
1111 1111
    ///
1112 1112
    /// \ref named-templ-param "Named parameter"
1113 1113
    ///for setting \ref ProcessedMap object.
1114 1114
    template<class T>
1115 1115
    BfsWizard<DefProcessedMapBase<T> > processedMap(const T &t)
1116 1116
    {
1117 1117
      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
1118 1118
      return BfsWizard<DefProcessedMapBase<T> >(*this);
1119 1119
    }
1120 1120

	
1121 1121
    template<class T>
1122 1122
    struct DefDistMapBase : public Base {
1123 1123
      typedef T DistMap;
1124 1124
      static DistMap *createDistMap(const Digraph &) { return 0; };
1125 1125
      DefDistMapBase(const TR &b) : TR(b) {}
1126 1126
    };
1127 1127
    ///\brief \ref named-templ-param "Named parameter"
1128 1128
    ///for setting \ref DistMap object.
1129 1129
    ///
1130 1130
    /// \ref named-templ-param "Named parameter"
1131 1131
    ///for setting \ref DistMap object.
1132 1132
    template<class T>
1133 1133
    BfsWizard<DefDistMapBase<T> > distMap(const T &t)
1134 1134
    {
1135 1135
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1136 1136
      return BfsWizard<DefDistMapBase<T> >(*this);
1137 1137
    }
1138 1138

	
1139 1139
  };
1140 1140

	
1141 1141
  ///Function type interface for Bfs algorithm.
1142 1142

	
1143 1143
  /// \ingroup search
1144 1144
  ///Function type interface for Bfs algorithm.
1145 1145
  ///
1146 1146
  ///This function also has several
1147 1147
  ///\ref named-templ-func-param "named parameters",
1148 1148
  ///they are declared as the members of class \ref BfsWizard.
1149 1149
  ///The following
1150 1150
  ///example shows how to use these parameters.
1151 1151
  ///\code
1152 1152
  ///  bfs(g,source).predMap(preds).run();
1153 1153
  ///\endcode
1154 1154
  ///\warning Don't forget to put the \ref BfsWizard::run() "run()"
1155 1155
  ///to the end of the parameter list.
1156 1156
  ///\sa BfsWizard
1157 1157
  ///\sa Bfs
1158 1158
  template<class GR>
1159 1159
  BfsWizard<BfsWizardBase<GR> >
1160 1160
  bfs(const GR &g,typename GR::Node s=INVALID)
1161 1161
  {
1162 1162
    return BfsWizard<BfsWizardBase<GR> >(g,s);
1163 1163
  }
1164 1164

	
1165 1165
#ifdef DOXYGEN
1166 1166
  /// \brief Visitor class for BFS.
1167 1167
  ///
1168 1168
  /// This class defines the interface of the BfsVisit events, and
1169 1169
  /// it could be the base of a real visitor class.
1170 1170
  template <typename _Digraph>
1171 1171
  struct BfsVisitor {
1172 1172
    typedef _Digraph Digraph;
1173 1173
    typedef typename Digraph::Arc Arc;
1174 1174
    typedef typename Digraph::Node Node;
1175 1175
    /// \brief Called for the source node(s) of the BFS.
1176 1176
    ///
1177 1177
    /// This function is called for the source node(s) of the BFS.
1178 1178
    void start(const Node& node) {}
1179 1179
    /// \brief Called when a node is reached first time.
1180 1180
    ///
1181 1181
    /// This function is called when a node is reached first time.
1182 1182
    void reach(const Node& node) {}
1183 1183
    /// \brief Called when a node is processed.
1184 1184
    ///
1185 1185
    /// This function is called when a node is processed.
1186 1186
    void process(const Node& node) {}
1187 1187
    /// \brief Called when an arc reaches a new node.
1188 1188
    ///
1189 1189
    /// This function is called when the BFS finds an arc whose target node
1190 1190
    /// is not reached yet.
1191 1191
    void discover(const Arc& arc) {}
1192 1192
    /// \brief Called when an arc is examined but its target node is
1193 1193
    /// already discovered.
1194 1194
    ///
1195 1195
    /// This function is called when an arc is examined but its target node is
1196 1196
    /// already discovered.
1197 1197
    void examine(const Arc& arc) {}
1198 1198
  };
1199 1199
#else
1200 1200
  template <typename _Digraph>
1201 1201
  struct BfsVisitor {
1202 1202
    typedef _Digraph Digraph;
1203 1203
    typedef typename Digraph::Arc Arc;
1204 1204
    typedef typename Digraph::Node Node;
1205 1205
    void start(const Node&) {}
1206 1206
    void reach(const Node&) {}
1207 1207
    void process(const Node&) {}
1208 1208
    void discover(const Arc&) {}
1209 1209
    void examine(const Arc&) {}
1210 1210

	
1211 1211
    template <typename _Visitor>
1212 1212
    struct Constraints {
1213 1213
      void constraints() {
1214 1214
        Arc arc;
1215 1215
        Node node;
1216 1216
        visitor.start(node);
1217 1217
        visitor.reach(node);
1218 1218
        visitor.process(node);
1219 1219
        visitor.discover(arc);
1220 1220
        visitor.examine(arc);
1221 1221
      }
1222 1222
      _Visitor& visitor;
1223 1223
    };
1224 1224
  };
1225 1225
#endif
1226 1226

	
1227 1227
  /// \brief Default traits class of BfsVisit class.
1228 1228
  ///
1229 1229
  /// Default traits class of BfsVisit class.
1230 1230
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
1231 1231
  template<class _Digraph>
1232 1232
  struct BfsVisitDefaultTraits {
1233 1233

	
1234 1234
    /// \brief The type of the digraph the algorithm runs on.
1235 1235
    typedef _Digraph Digraph;
1236 1236

	
1237 1237
    /// \brief The type of the map that indicates which nodes are reached.
1238 1238
    ///
1239 1239
    /// The type of the map that indicates which nodes are reached.
1240 1240
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
1241 1241
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
1242 1242

	
1243 1243
    /// \brief Instantiates a \ref ReachedMap.
1244 1244
    ///
1245 1245
    /// This function instantiates a \ref ReachedMap.
1246 1246
    /// \param digraph is the digraph, to which
1247 1247
    /// we would like to define the \ref ReachedMap.
1248 1248
    static ReachedMap *createReachedMap(const Digraph &digraph) {
1249 1249
      return new ReachedMap(digraph);
1250 1250
    }
1251 1251

	
1252 1252
  };
1253 1253

	
1254 1254
  /// \ingroup search
1255 1255
  ///
1256 1256
  /// \brief %BFS algorithm class with visitor interface.
1257 1257
  ///
1258 1258
  /// This class provides an efficient implementation of the %BFS algorithm
1259 1259
  /// with visitor interface.
1260 1260
  ///
1261 1261
  /// The %BfsVisit class provides an alternative interface to the Bfs
1262 1262
  /// class. It works with callback mechanism, the BfsVisit object calls
1263 1263
  /// the member functions of the \c Visitor class on every BFS event.
1264 1264
  ///
1265
  /// This interface of the BFS algorithm should be used in special cases
1266
  /// when extra actions have to be performed in connection with certain
1267
  /// events of the BFS algorithm. Otherwise consider to use Bfs or bfs()
1268
  /// instead.
1269
  ///
1265 1270
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
1266 1271
  /// The default value is
1267 1272
  /// \ref ListDigraph. The value of _Digraph is not used directly by
1268 1273
  /// \ref BfsVisit, it is only passed to \ref BfsVisitDefaultTraits.
1269 1274
  /// \tparam _Visitor The Visitor type that is used by the algorithm.
1270 1275
  /// \ref BfsVisitor "BfsVisitor<_Digraph>" is an empty visitor, which
1271 1276
  /// does not observe the BFS events. If you want to observe the BFS
1272 1277
  /// events, you should implement your own visitor class.
1273 1278
  /// \tparam _Traits Traits class to set various data types used by the
1274 1279
  /// algorithm. The default traits class is
1275 1280
  /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<_Digraph>".
1276 1281
  /// See \ref BfsVisitDefaultTraits for the documentation of
1277 1282
  /// a BFS visit traits class.
1278 1283
#ifdef DOXYGEN
1279 1284
  template <typename _Digraph, typename _Visitor, typename _Traits>
1280 1285
#else
1281 1286
  template <typename _Digraph = ListDigraph,
1282 1287
            typename _Visitor = BfsVisitor<_Digraph>,
1283 1288
            typename _Traits = BfsDefaultTraits<_Digraph> >
1284 1289
#endif
1285 1290
  class BfsVisit {
1286 1291
  public:
1287 1292

	
1288 1293
    /// \brief \ref Exception for uninitialized parameters.
1289 1294
    ///
1290 1295
    /// This error represents problems in the initialization
1291 1296
    /// of the parameters of the algorithm.
1292 1297
    class UninitializedParameter : public lemon::UninitializedParameter {
1293 1298
    public:
1294 1299
      virtual const char* what() const throw()
1295 1300
      {
1296 1301
        return "lemon::BfsVisit::UninitializedParameter";
1297 1302
      }
1298 1303
    };
1299 1304

	
1300 1305
    ///The traits class.
1301 1306
    typedef _Traits Traits;
1302 1307

	
1303 1308
    ///The type of the digraph the algorithm runs on.
1304 1309
    typedef typename Traits::Digraph Digraph;
1305 1310

	
1306 1311
    ///The visitor type used by the algorithm.
1307 1312
    typedef _Visitor Visitor;
1308 1313

	
1309 1314
    ///The type of the map that indicates which nodes are reached.
1310 1315
    typedef typename Traits::ReachedMap ReachedMap;
1311 1316

	
1312 1317
  private:
1313 1318

	
1314 1319
    typedef typename Digraph::Node Node;
1315 1320
    typedef typename Digraph::NodeIt NodeIt;
1316 1321
    typedef typename Digraph::Arc Arc;
1317 1322
    typedef typename Digraph::OutArcIt OutArcIt;
1318 1323

	
1319 1324
    //Pointer to the underlying digraph.
1320 1325
    const Digraph *_digraph;
1321 1326
    //Pointer to the visitor object.
1322 1327
    Visitor *_visitor;
1323 1328
    //Pointer to the map of reached status of the nodes.
1324 1329
    ReachedMap *_reached;
1325 1330
    //Indicates if _reached is locally allocated (true) or not.
1326 1331
    bool local_reached;
1327 1332

	
1328 1333
    std::vector<typename Digraph::Node> _list;
1329 1334
    int _list_front, _list_back;
1330 1335

	
1331 1336
    ///Creates the maps if necessary.
1332 1337
    ///\todo Better memory allocation (instead of new).
1333 1338
    void create_maps() {
1334 1339
      if(!_reached) {
1335 1340
        local_reached = true;
1336 1341
        _reached = Traits::createReachedMap(*_digraph);
1337 1342
      }
1338 1343
    }
1339 1344

	
1340 1345
  protected:
1341 1346

	
1342 1347
    BfsVisit() {}
1343 1348

	
1344 1349
  public:
1345 1350

	
1346 1351
    typedef BfsVisit Create;
1347 1352

	
1348 1353
    /// \name Named template parameters
1349 1354

	
1350 1355
    ///@{
1351 1356
    template <class T>
1352 1357
    struct DefReachedMapTraits : public Traits {
1353 1358
      typedef T ReachedMap;
1354 1359
      static ReachedMap *createReachedMap(const Digraph &digraph) {
1355 1360
        throw UninitializedParameter();
1356 1361
      }
1357 1362
    };
1358 1363
    /// \brief \ref named-templ-param "Named parameter" for setting
1359 1364
    /// ReachedMap type.
1360 1365
    ///
1361 1366
    /// \ref named-templ-param "Named parameter" for setting ReachedMap type.
1362 1367
    template <class T>
1363 1368
    struct DefReachedMap : public BfsVisit< Digraph, Visitor,
1364 1369
                                            DefReachedMapTraits<T> > {
1365 1370
      typedef BfsVisit< Digraph, Visitor, DefReachedMapTraits<T> > Create;
1366 1371
    };
1367 1372
    ///@}
1368 1373

	
1369 1374
  public:
1370 1375

	
1371 1376
    /// \brief Constructor.
1372 1377
    ///
1373 1378
    /// Constructor.
1374 1379
    ///
1375 1380
    /// \param digraph The digraph the algorithm runs on.
1376 1381
    /// \param visitor The visitor object of the algorithm.
1377 1382
    BfsVisit(const Digraph& digraph, Visitor& visitor)
1378 1383
      : _digraph(&digraph), _visitor(&visitor),
1379 1384
        _reached(0), local_reached(false) {}
1380 1385

	
1381 1386
    /// \brief Destructor.
1382 1387
    ~BfsVisit() {
1383 1388
      if(local_reached) delete _reached;
1384 1389
    }
1385 1390

	
1386 1391
    /// \brief Sets the map that indicates which nodes are reached.
1387 1392
    ///
1388 1393
    /// Sets the map that indicates which nodes are reached.
1389 1394
    /// If you don't use this function before calling \ref run(),
1390 1395
    /// it will allocate one. The destructor deallocates this
1391 1396
    /// automatically allocated map, of course.
1392 1397
    /// \return <tt> (*this) </tt>
1393 1398
    BfsVisit &reachedMap(ReachedMap &m) {
1394 1399
      if(local_reached) {
1395 1400
        delete _reached;
1396 1401
        local_reached = false;
1397 1402
      }
1398 1403
      _reached = &m;
1399 1404
      return *this;
1400 1405
    }
1401 1406

	
1402 1407
  public:
1403 1408

	
1404 1409
    /// \name Execution control
1405 1410
    /// The simplest way to execute the algorithm is to use
1406 1411
    /// one of the member functions called \ref lemon::BfsVisit::run()
1407 1412
    /// "run()".
1408 1413
    /// \n
1409 1414
    /// If you need more control on the execution, first you must call
1410 1415
    /// \ref lemon::BfsVisit::init() "init()", then you can add several
1411 1416
    /// source nodes with \ref lemon::BfsVisit::addSource() "addSource()".
1412 1417
    /// Finally \ref lemon::BfsVisit::start() "start()" will perform the
1413 1418
    /// actual path computation.
1414 1419

	
1415 1420
    /// @{
1416 1421

	
1417 1422
    /// \brief Initializes the internal data structures.
1418 1423
    ///
1419 1424
    /// Initializes the internal data structures.
1420 1425
    void init() {
1421 1426
      create_maps();
1422 1427
      _list.resize(countNodes(*_digraph));
1423 1428
      _list_front = _list_back = -1;
1424 1429
      for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
1425 1430
        _reached->set(u, false);
1426 1431
      }
1427 1432
    }
1428 1433

	
1429 1434
    /// \brief Adds a new source node.
1430 1435
    ///
1431 1436
    /// Adds a new source node to the set of nodes to be processed.
1432 1437
    void addSource(Node s) {
1433 1438
      if(!(*_reached)[s]) {
1434 1439
          _reached->set(s,true);
1435 1440
          _visitor->start(s);
1436 1441
          _visitor->reach(s);
1437 1442
          _list[++_list_back] = s;
1438 1443
        }
1439 1444
    }
1440 1445

	
1441 1446
    /// \brief Processes the next node.
1442 1447
    ///
1443 1448
    /// Processes the next node.
1444 1449
    ///
1445 1450
    /// \return The processed node.
1446 1451
    ///
1447 1452
    /// \pre The queue must not be empty.
1448 1453
    Node processNextNode() {
1449 1454
      Node n = _list[++_list_front];
1450 1455
      _visitor->process(n);
1451 1456
      Arc e;
1452 1457
      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
1453 1458
        Node m = _digraph->target(e);
1454 1459
        if (!(*_reached)[m]) {
1455 1460
          _visitor->discover(e);
1456 1461
          _visitor->reach(m);
Ignore white space 6 line context
... ...
@@ -1020,384 +1020,389 @@
1020 1020
    template<class T>
1021 1021
    struct DefReachedMapBase : public Base {
1022 1022
      typedef T ReachedMap;
1023 1023
      static ReachedMap *createReachedMap(const Digraph &) { return 0; };
1024 1024
      DefReachedMapBase(const TR &b) : TR(b) {}
1025 1025
    };
1026 1026
    ///\brief \ref named-templ-param "Named parameter"
1027 1027
    ///for setting \ref ReachedMap object.
1028 1028
    ///
1029 1029
    /// \ref named-templ-param "Named parameter"
1030 1030
    ///for setting \ref ReachedMap object.
1031 1031
    template<class T>
1032 1032
    DfsWizard<DefReachedMapBase<T> > reachedMap(const T &t)
1033 1033
    {
1034 1034
      Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
1035 1035
      return DfsWizard<DefReachedMapBase<T> >(*this);
1036 1036
    }
1037 1037

	
1038 1038
    template<class T>
1039 1039
    struct DefProcessedMapBase : public Base {
1040 1040
      typedef T ProcessedMap;
1041 1041
      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
1042 1042
      DefProcessedMapBase(const TR &b) : TR(b) {}
1043 1043
    };
1044 1044
    ///\brief \ref named-templ-param "Named parameter"
1045 1045
    ///for setting \ref ProcessedMap object.
1046 1046
    ///
1047 1047
    /// \ref named-templ-param "Named parameter"
1048 1048
    ///for setting \ref ProcessedMap object.
1049 1049
    template<class T>
1050 1050
    DfsWizard<DefProcessedMapBase<T> > processedMap(const T &t)
1051 1051
    {
1052 1052
      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
1053 1053
      return DfsWizard<DefProcessedMapBase<T> >(*this);
1054 1054
    }
1055 1055

	
1056 1056
    template<class T>
1057 1057
    struct DefDistMapBase : public Base {
1058 1058
      typedef T DistMap;
1059 1059
      static DistMap *createDistMap(const Digraph &) { return 0; };
1060 1060
      DefDistMapBase(const TR &b) : TR(b) {}
1061 1061
    };
1062 1062
    ///\brief \ref named-templ-param "Named parameter"
1063 1063
    ///for setting \ref DistMap object.
1064 1064
    ///
1065 1065
    ///\ref named-templ-param "Named parameter"
1066 1066
    ///for setting \ref DistMap object.
1067 1067
    template<class T>
1068 1068
    DfsWizard<DefDistMapBase<T> > distMap(const T &t)
1069 1069
    {
1070 1070
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1071 1071
      return DfsWizard<DefDistMapBase<T> >(*this);
1072 1072
    }
1073 1073

	
1074 1074
  };
1075 1075

	
1076 1076
  ///Function type interface for Dfs algorithm.
1077 1077

	
1078 1078
  ///\ingroup search
1079 1079
  ///Function type interface for Dfs algorithm.
1080 1080
  ///
1081 1081
  ///This function also has several
1082 1082
  ///\ref named-templ-func-param "named parameters",
1083 1083
  ///they are declared as the members of class \ref DfsWizard.
1084 1084
  ///The following
1085 1085
  ///example shows how to use these parameters.
1086 1086
  ///\code
1087 1087
  ///  dfs(g,source).predMap(preds).run();
1088 1088
  ///\endcode
1089 1089
  ///\warning Don't forget to put the \ref DfsWizard::run() "run()"
1090 1090
  ///to the end of the parameter list.
1091 1091
  ///\sa DfsWizard
1092 1092
  ///\sa Dfs
1093 1093
  template<class GR>
1094 1094
  DfsWizard<DfsWizardBase<GR> >
1095 1095
  dfs(const GR &g,typename GR::Node s=INVALID)
1096 1096
  {
1097 1097
    return DfsWizard<DfsWizardBase<GR> >(g,s);
1098 1098
  }
1099 1099

	
1100 1100
#ifdef DOXYGEN
1101 1101
  /// \brief Visitor class for DFS.
1102 1102
  ///
1103 1103
  /// This class defines the interface of the DfsVisit events, and
1104 1104
  /// it could be the base of a real visitor class.
1105 1105
  template <typename _Digraph>
1106 1106
  struct DfsVisitor {
1107 1107
    typedef _Digraph Digraph;
1108 1108
    typedef typename Digraph::Arc Arc;
1109 1109
    typedef typename Digraph::Node Node;
1110 1110
    /// \brief Called for the source node of the DFS.
1111 1111
    ///
1112 1112
    /// This function is called for the source node of the DFS.
1113 1113
    void start(const Node& node) {}
1114 1114
    /// \brief Called when the source node is leaved.
1115 1115
    ///
1116 1116
    /// This function is called when the source node is leaved.
1117 1117
    void stop(const Node& node) {}
1118 1118
    /// \brief Called when a node is reached first time.
1119 1119
    ///
1120 1120
    /// This function is called when a node is reached first time.
1121 1121
    void reach(const Node& node) {}
1122 1122
    /// \brief Called when an arc reaches a new node.
1123 1123
    ///
1124 1124
    /// This function is called when the DFS finds an arc whose target node
1125 1125
    /// is not reached yet.
1126 1126
    void discover(const Arc& arc) {}
1127 1127
    /// \brief Called when an arc is examined but its target node is
1128 1128
    /// already discovered.
1129 1129
    ///
1130 1130
    /// This function is called when an arc is examined but its target node is
1131 1131
    /// already discovered.
1132 1132
    void examine(const Arc& arc) {}
1133 1133
    /// \brief Called when the DFS steps back from a node.
1134 1134
    ///
1135 1135
    /// This function is called when the DFS steps back from a node.
1136 1136
    void leave(const Node& node) {}
1137 1137
    /// \brief Called when the DFS steps back on an arc.
1138 1138
    ///
1139 1139
    /// This function is called when the DFS steps back on an arc.
1140 1140
    void backtrack(const Arc& arc) {}
1141 1141
  };
1142 1142
#else
1143 1143
  template <typename _Digraph>
1144 1144
  struct DfsVisitor {
1145 1145
    typedef _Digraph Digraph;
1146 1146
    typedef typename Digraph::Arc Arc;
1147 1147
    typedef typename Digraph::Node Node;
1148 1148
    void start(const Node&) {}
1149 1149
    void stop(const Node&) {}
1150 1150
    void reach(const Node&) {}
1151 1151
    void discover(const Arc&) {}
1152 1152
    void examine(const Arc&) {}
1153 1153
    void leave(const Node&) {}
1154 1154
    void backtrack(const Arc&) {}
1155 1155

	
1156 1156
    template <typename _Visitor>
1157 1157
    struct Constraints {
1158 1158
      void constraints() {
1159 1159
        Arc arc;
1160 1160
        Node node;
1161 1161
        visitor.start(node);
1162 1162
        visitor.stop(arc);
1163 1163
        visitor.reach(node);
1164 1164
        visitor.discover(arc);
1165 1165
        visitor.examine(arc);
1166 1166
        visitor.leave(node);
1167 1167
        visitor.backtrack(arc);
1168 1168
      }
1169 1169
      _Visitor& visitor;
1170 1170
    };
1171 1171
  };
1172 1172
#endif
1173 1173

	
1174 1174
  /// \brief Default traits class of DfsVisit class.
1175 1175
  ///
1176 1176
  /// Default traits class of DfsVisit class.
1177 1177
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
1178 1178
  template<class _Digraph>
1179 1179
  struct DfsVisitDefaultTraits {
1180 1180

	
1181 1181
    /// \brief The type of the digraph the algorithm runs on.
1182 1182
    typedef _Digraph Digraph;
1183 1183

	
1184 1184
    /// \brief The type of the map that indicates which nodes are reached.
1185 1185
    ///
1186 1186
    /// The type of the map that indicates which nodes are reached.
1187 1187
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
1188 1188
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
1189 1189

	
1190 1190
    /// \brief Instantiates a \ref ReachedMap.
1191 1191
    ///
1192 1192
    /// This function instantiates a \ref ReachedMap.
1193 1193
    /// \param digraph is the digraph, to which
1194 1194
    /// we would like to define the \ref ReachedMap.
1195 1195
    static ReachedMap *createReachedMap(const Digraph &digraph) {
1196 1196
      return new ReachedMap(digraph);
1197 1197
    }
1198 1198

	
1199 1199
  };
1200 1200

	
1201 1201
  /// \ingroup search
1202 1202
  ///
1203 1203
  /// \brief %DFS algorithm class with visitor interface.
1204 1204
  ///
1205 1205
  /// This class provides an efficient implementation of the %DFS algorithm
1206 1206
  /// with visitor interface.
1207 1207
  ///
1208 1208
  /// The %DfsVisit class provides an alternative interface to the Dfs
1209 1209
  /// class. It works with callback mechanism, the DfsVisit object calls
1210 1210
  /// the member functions of the \c Visitor class on every DFS event.
1211 1211
  ///
1212
  /// This interface of the DFS algorithm should be used in special cases
1213
  /// when extra actions have to be performed in connection with certain
1214
  /// events of the DFS algorithm. Otherwise consider to use Dfs or dfs()
1215
  /// instead.
1216
  ///
1212 1217
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
1213 1218
  /// The default value is
1214 1219
  /// \ref ListDigraph. The value of _Digraph is not used directly by
1215 1220
  /// \ref DfsVisit, it is only passed to \ref DfsVisitDefaultTraits.
1216 1221
  /// \tparam _Visitor The Visitor type that is used by the algorithm.
1217 1222
  /// \ref DfsVisitor "DfsVisitor<_Digraph>" is an empty visitor, which
1218 1223
  /// does not observe the DFS events. If you want to observe the DFS
1219 1224
  /// events, you should implement your own visitor class.
1220 1225
  /// \tparam _Traits Traits class to set various data types used by the
1221 1226
  /// algorithm. The default traits class is
1222 1227
  /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<_Digraph>".
1223 1228
  /// See \ref DfsVisitDefaultTraits for the documentation of
1224 1229
  /// a DFS visit traits class.
1225 1230
#ifdef DOXYGEN
1226 1231
  template <typename _Digraph, typename _Visitor, typename _Traits>
1227 1232
#else
1228 1233
  template <typename _Digraph = ListDigraph,
1229 1234
            typename _Visitor = DfsVisitor<_Digraph>,
1230 1235
            typename _Traits = DfsDefaultTraits<_Digraph> >
1231 1236
#endif
1232 1237
  class DfsVisit {
1233 1238
  public:
1234 1239

	
1235 1240
    /// \brief \ref Exception for uninitialized parameters.
1236 1241
    ///
1237 1242
    /// This error represents problems in the initialization
1238 1243
    /// of the parameters of the algorithm.
1239 1244
    class UninitializedParameter : public lemon::UninitializedParameter {
1240 1245
    public:
1241 1246
      virtual const char* what() const throw()
1242 1247
      {
1243 1248
        return "lemon::DfsVisit::UninitializedParameter";
1244 1249
      }
1245 1250
    };
1246 1251

	
1247 1252
    ///The traits class.
1248 1253
    typedef _Traits Traits;
1249 1254

	
1250 1255
    ///The type of the digraph the algorithm runs on.
1251 1256
    typedef typename Traits::Digraph Digraph;
1252 1257

	
1253 1258
    ///The visitor type used by the algorithm.
1254 1259
    typedef _Visitor Visitor;
1255 1260

	
1256 1261
    ///The type of the map that indicates which nodes are reached.
1257 1262
    typedef typename Traits::ReachedMap ReachedMap;
1258 1263

	
1259 1264
  private:
1260 1265

	
1261 1266
    typedef typename Digraph::Node Node;
1262 1267
    typedef typename Digraph::NodeIt NodeIt;
1263 1268
    typedef typename Digraph::Arc Arc;
1264 1269
    typedef typename Digraph::OutArcIt OutArcIt;
1265 1270

	
1266 1271
    //Pointer to the underlying digraph.
1267 1272
    const Digraph *_digraph;
1268 1273
    //Pointer to the visitor object.
1269 1274
    Visitor *_visitor;
1270 1275
    //Pointer to the map of reached status of the nodes.
1271 1276
    ReachedMap *_reached;
1272 1277
    //Indicates if _reached is locally allocated (true) or not.
1273 1278
    bool local_reached;
1274 1279

	
1275 1280
    std::vector<typename Digraph::Arc> _stack;
1276 1281
    int _stack_head;
1277 1282

	
1278 1283
    ///Creates the maps if necessary.
1279 1284
    ///\todo Better memory allocation (instead of new).
1280 1285
    void create_maps() {
1281 1286
      if(!_reached) {
1282 1287
        local_reached = true;
1283 1288
        _reached = Traits::createReachedMap(*_digraph);
1284 1289
      }
1285 1290
    }
1286 1291

	
1287 1292
  protected:
1288 1293

	
1289 1294
    DfsVisit() {}
1290 1295

	
1291 1296
  public:
1292 1297

	
1293 1298
    typedef DfsVisit Create;
1294 1299

	
1295 1300
    /// \name Named template parameters
1296 1301

	
1297 1302
    ///@{
1298 1303
    template <class T>
1299 1304
    struct DefReachedMapTraits : public Traits {
1300 1305
      typedef T ReachedMap;
1301 1306
      static ReachedMap *createReachedMap(const Digraph &digraph) {
1302 1307
        throw UninitializedParameter();
1303 1308
      }
1304 1309
    };
1305 1310
    /// \brief \ref named-templ-param "Named parameter" for setting
1306 1311
    /// ReachedMap type.
1307 1312
    ///
1308 1313
    /// \ref named-templ-param "Named parameter" for setting ReachedMap type.
1309 1314
    template <class T>
1310 1315
    struct DefReachedMap : public DfsVisit< Digraph, Visitor,
1311 1316
                                            DefReachedMapTraits<T> > {
1312 1317
      typedef DfsVisit< Digraph, Visitor, DefReachedMapTraits<T> > Create;
1313 1318
    };
1314 1319
    ///@}
1315 1320

	
1316 1321
  public:
1317 1322

	
1318 1323
    /// \brief Constructor.
1319 1324
    ///
1320 1325
    /// Constructor.
1321 1326
    ///
1322 1327
    /// \param digraph The digraph the algorithm runs on.
1323 1328
    /// \param visitor The visitor object of the algorithm.
1324 1329
    DfsVisit(const Digraph& digraph, Visitor& visitor)
1325 1330
      : _digraph(&digraph), _visitor(&visitor),
1326 1331
        _reached(0), local_reached(false) {}
1327 1332

	
1328 1333
    /// \brief Destructor.
1329 1334
    ~DfsVisit() {
1330 1335
      if(local_reached) delete _reached;
1331 1336
    }
1332 1337

	
1333 1338
    /// \brief Sets the map that indicates which nodes are reached.
1334 1339
    ///
1335 1340
    /// Sets the map that indicates which nodes are reached.
1336 1341
    /// If you don't use this function before calling \ref run(),
1337 1342
    /// it will allocate one. The destructor deallocates this
1338 1343
    /// automatically allocated map, of course.
1339 1344
    /// \return <tt> (*this) </tt>
1340 1345
    DfsVisit &reachedMap(ReachedMap &m) {
1341 1346
      if(local_reached) {
1342 1347
        delete _reached;
1343 1348
        local_reached=false;
1344 1349
      }
1345 1350
      _reached = &m;
1346 1351
      return *this;
1347 1352
    }
1348 1353

	
1349 1354
  public:
1350 1355

	
1351 1356
    /// \name Execution control
1352 1357
    /// The simplest way to execute the algorithm is to use
1353 1358
    /// one of the member functions called \ref lemon::DfsVisit::run()
1354 1359
    /// "run()".
1355 1360
    /// \n
1356 1361
    /// If you need more control on the execution, first you must call
1357 1362
    /// \ref lemon::DfsVisit::init() "init()", then you can add several
1358 1363
    /// source nodes with \ref lemon::DfsVisit::addSource() "addSource()".
1359 1364
    /// Finally \ref lemon::DfsVisit::start() "start()" will perform the
1360 1365
    /// actual path computation.
1361 1366

	
1362 1367
    /// @{
1363 1368

	
1364 1369
    /// \brief Initializes the internal data structures.
1365 1370
    ///
1366 1371
    /// Initializes the internal data structures.
1367 1372
    void init() {
1368 1373
      create_maps();
1369 1374
      _stack.resize(countNodes(*_digraph));
1370 1375
      _stack_head = -1;
1371 1376
      for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
1372 1377
        _reached->set(u, false);
1373 1378
      }
1374 1379
    }
1375 1380

	
1376 1381
    ///Adds a new source node.
1377 1382

	
1378 1383
    ///Adds a new source node to the set of nodes to be processed.
1379 1384
    ///
1380 1385
    ///\pre The stack must be empty. (Otherwise the algorithm gives
1381 1386
    ///false results.)
1382 1387
    ///
1383 1388
    ///\warning Distances will be wrong (or at least strange) in case of
1384 1389
    ///multiple sources.
1385 1390
    void addSource(Node s)
1386 1391
    {
1387 1392
      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
1388 1393
      if(!(*_reached)[s]) {
1389 1394
          _reached->set(s,true);
1390 1395
          _visitor->start(s);
1391 1396
          _visitor->reach(s);
1392 1397
          Arc e;
1393 1398
          _digraph->firstOut(e, s);
1394 1399
          if (e != INVALID) {
1395 1400
            _stack[++_stack_head] = e;
1396 1401
          } else {
1397 1402
            _visitor->leave(s);
1398 1403
          }
1399 1404
        }
1400 1405
    }
1401 1406

	
1402 1407
    /// \brief Processes the next arc.
1403 1408
    ///
0 comments (0 inline)