deba@2335: /* -*- C++ -*- deba@2335: * deba@2335: * This file is a part of LEMON, a generic C++ optimization library deba@2335: * alpar@2391: * Copyright (C) 2003-2007 deba@2335: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport deba@2335: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@2335: * deba@2335: * Permission to use, modify and distribute this software is granted deba@2335: * provided that this copyright notice appears in all copies. For deba@2335: * precise terms see the accompanying LICENSE file. deba@2335: * deba@2335: * This software is provided "AS IS" with no warranty of any kind, deba@2335: * express or implied, and with no claim as to its suitability for any deba@2335: * purpose. deba@2335: * deba@2335: */ deba@2335: deba@2335: ///\ingroup paths deba@2335: ///\file deba@2335: ///\brief Classes for representing paths in graphs. deba@2335: /// deba@2335: deba@2335: #ifndef LEMON_PATH_UTILS_H deba@2335: #define LEMON_PATH_UTILS_H deba@2335: deba@2335: #include deba@2335: deba@2335: namespace lemon { deba@2335: deba@2335: namespace _path_bits { deba@2335: deba@2335: template deba@2335: struct RevTagIndicator { deba@2335: static const bool value = false; deba@2335: }; deba@2335: deba@2335: template deba@2335: struct RevTagIndicator< deba@2335: Graph, deba@2335: typename enable_if::type deba@2335: > { deba@2335: static const bool value = true; deba@2335: }; deba@2335: deba@2335: template deba@2335: struct PathCopySelector { deba@2335: static void copy(Target& target, const Source& source) { deba@2357: target.clear(); deba@2335: for (typename Source::EdgeIt it(source); it != INVALID; ++it) { deba@2335: target.addBack(it); deba@2335: } deba@2335: } deba@2335: }; deba@2335: deba@2335: template deba@2335: struct PathCopySelector< deba@2335: Target, Source, BuildEnable, deba@2335: typename enable_if::type> { deba@2335: static void copy(Target& target, const Source& source) { deba@2357: target.clear(); deba@2357: for (typename Source::RevEdgeIt it(source); it != INVALID; ++it) { deba@2335: target.addFront(it); deba@2335: } deba@2335: } deba@2335: }; deba@2335: deba@2335: template deba@2335: struct PathCopySelector< deba@2335: Target, Source, deba@2335: typename enable_if::type, RevEnable> { deba@2335: static void copy(Target& target, const Source& source) { deba@2335: target.clear(); deba@2335: target.build(source); deba@2335: } deba@2335: }; deba@2335: deba@2335: template deba@2335: struct PathCopySelector< deba@2335: Target, Source, deba@2335: typename enable_if::type, deba@2335: typename enable_if::type> { deba@2335: static void copy(Target& target, const Source& source) { deba@2335: target.clear(); deba@2335: target.buildRev(source); deba@2335: } deba@2335: }; deba@2335: deba@2335: } deba@2335: deba@2335: deba@2335: /// \brief Make of copy of a path. deba@2335: /// deba@2335: /// Make of copy of a path. deba@2335: template deba@2335: void copyPath(Target& target, const Source& source) { deba@2335: checkConcept, Source>(); deba@2335: _path_bits::PathCopySelector::copy(target, source); deba@2335: } deba@2335: deba@2335: /// \brief Checks the path's consistency. deba@2335: /// deba@2335: /// Checks that each edge's target is the next's source. alpar@2350: /// deba@2335: template deba@2335: bool checkPath(const Graph& graph, const Path& path) { deba@2335: typename Path::EdgeIt it(path); deba@2335: if (it == INVALID) return true; deba@2335: typename Graph::Node node = graph.target(it); deba@2335: ++it; deba@2335: while (it != INVALID) { deba@2335: if (graph.source(it) != node) return false; deba@2335: node = graph.target(it); deba@2335: ++it; deba@2335: } deba@2335: return true; deba@2335: } deba@2335: deba@2335: /// \brief Gives back the source of the path deba@2335: /// deba@2335: /// Gives back the source of the path. deba@2335: template deba@2335: typename Graph::Node pathSource(const Graph& graph, const Path& path) { deba@2335: return graph.source(path.front()); deba@2335: } deba@2335: deba@2335: /// \brief Gives back the target of the path deba@2335: /// deba@2335: /// Gives back the target of the path. deba@2335: template deba@2335: typename Graph::Node pathTarget(const Graph& graph, const Path& path) { deba@2335: return graph.target(path.back()); deba@2335: } deba@2335: } deba@2335: deba@2335: #endif