depth_first.hpp

Back to Depth-first traversal

pastel/sys/graph/depth_first/

#ifndef PASTELSYS_DEPTH_FIRST_TRAVERSAL_HPP
#define PASTELSYS_DEPTH_FIRST_TRAVERSAL_HPP

#include "pastel/sys/graph/depth_first/depth_first.h"

#include <boost/bind.hpp>

#include <functional>

namespace Pastel
{

    class DepthFirst_GraphTraversal
    {
    public:
        template <
            typename Vertex,
            typename ForEachSeedVertex,
            typename ForEachAdjacent,
            typename Mark,
            typename Marked>
        void work(
            const ForEachSeedVertex& forEachSeedVertex,
            const ForEachAdjacent& forEachAdjacent,
            const Mark& mark,
            const Marked& marked) const
        {
            Work<Vertex, ForEachSeedVertex, 
                ForEachAdjacent, Mark, Marked> work(
                forEachSeedVertex, forEachAdjacent,
                mark, marked);
        }

    private:
        template <
            typename Vertex,
            typename ForEachSeedVertex,
            typename ForEachAdjacent,
            typename Mark,
            typename Marked>
        class Work
        {
        public:
            Work(
                const ForEachSeedVertex& forEachSeedVertex_,
                const ForEachAdjacent& forEachAdjacent_,
                const Mark& mark_,
                const Marked& marked_)
                : forEachSeedVertex(forEachSeedVertex_)
                , forEachAdjacent(forEachAdjacent_)
                , mark(mark_)
                , marked(marked_)
            {
                // Traverse each seed-vertex depth-first.
                forEachSeedVertex(
                    boost::bind(&Work::visit, 
                    boost::ref(*this), _1));
            }

            void visit(const Vertex& vertex)
            {
                // Avoid visiting the same vertex twice.
                if (!marked(vertex))
                {
                    // Mark as visited.
                    mark(vertex);

                    // Traverse the edges.
                    forEachAdjacent(
                        vertex,
                        boost::bind(&Work::visit, 
                        boost::ref(*this), _1));
                }
            }

        private:
            const ForEachSeedVertex& forEachSeedVertex;
            const ForEachAdjacent& forEachAdjacent;
            const Mark& mark;
            const Marked& marked;
        };
    };

}

#endif