incidence_graph_edge.h

Back to Incidence graph

pastel/sys/incidence_graph/

#ifndef PASTELSYS_INCIDENCE_GRAPH_EDGE_H
#define PASTELSYS_INCIDENCE_GRAPH_EDGE_H

#include "pastel/sys/incidence_graph.h"
#include "pastel/sys/generic/class.h"

namespace Pastel
{

    namespace IncidenceGraph_
    {

        template <GraphType Type, typename Data>
        class Directed_EdgeData;

        template <typename Data>
        class Directed_EdgeData<GraphType::Directed, Data>
            : public Class<Data>
        {
        public:
            typedef Class<Data> 
                Base;

            template <typename Data_>
            Directed_EdgeData(
                bool directed,
                Data_&& data)
                : Base(std::forward<Data_>(data))
            {
            }

            bool directed() const
            {
                return true;
            }

        protected:
            void setDirected(bool directed)
            {
            }

        private:
            Directed_EdgeData() = delete;
            Directed_EdgeData(Directed_EdgeData&& that) = delete;
            Directed_EdgeData(const Directed_EdgeData& that) = delete;
            Directed_EdgeData& operator=(Directed_EdgeData that) = delete;
        };

        template <typename Data>
        class Directed_EdgeData<GraphType::Undirected, Data>
            : public Class<Data>
        {
        public:
            typedef Class<Data> 
                Base;

            template <typename Data_>
            Directed_EdgeData(
                bool directed,
                Data_&& data)
                : Base(std::forward<Data_>(data))
            {
            }

            bool directed() const
            {
                return false;
            }

        protected:
            void setDirected(bool directed)
            {
            }

        private:
            Directed_EdgeData() = delete;
            Directed_EdgeData(Directed_EdgeData&& that) = delete;
            Directed_EdgeData(const Directed_EdgeData& that) = delete;
            Directed_EdgeData& operator=(Directed_EdgeData that) = delete;
        };

        template <typename Data>
        class Directed_EdgeData<GraphType::Mixed, Data>
            : public Class<Data>
        {
        public:
            typedef Class<Data> 
                Base;

            template <typename Data_>
            Directed_EdgeData(
                bool directed,
                Data_&& data)
                : Base(std::forward<Data_>(data))
                , directed_(directed)
            {
            }

            bool directed() const
            {
                return directed_;
            }

        protected:
            void setDirected(bool directed)
            {
                directed_ = directed;
            }

        private:
            Directed_EdgeData() = delete;
            Directed_EdgeData(Directed_EdgeData&& that) = delete;
            Directed_EdgeData(const Directed_EdgeData& that) = delete;
            Directed_EdgeData& operator=(Directed_EdgeData that) = delete;

        private:
            bool directed_;
        };

    }

    template <typename Settings>
    class IncidenceGraph_Fwd<Settings>::Edge
        : public IncidenceGraph_::Directed_EdgeData<Type, EdgeData>
    {
    public:
        template <typename, template <typename> class>
        friend class Pastel::IncidenceGraph;

        typedef IncidenceGraph_::Directed_EdgeData<Type, EdgeData>
            Base;

        // FIX: Delete after emplace becomes available in Visual Studio.
        Edge(Edge&& that)
            : Base(that.directed(), std::move((EdgeData_Class&&)that))
            , from_(std::move(that.from_))
            , to_(std::move(that.to_))
        {
        }

        //! Assigns to the contained data.
        template <typename Type>
        Edge& operator=(Type&& that)
        {
            ((EdgeData_Class&)*this) = std::forward<Type>(that);
            return *this;
        }

        Vertex_Iterator from()
        {
            // Note that the to-incidence, which is stored
            // in the to-vertex, stores a reference
            // to the from-vertex of the edge. And vice versa.
            // This is because when examining a vertex, it
            // would not give you any extra-information if
            // the vertex reference of its incidence were 
            // to the vertex itself.
            return to_->vertex();
        }

        Vertex_ConstIterator from() const
        {
            return to_->vertex();
        }

        Vertex_Iterator to()
        {
            return from_->vertex();
        }

        Vertex_ConstIterator to() const
        {
            return from_->vertex();
        }

        bool directed() const
        {
            return Base::directed();
        }

    private:
        Edge() = delete;
        Edge(const Edge& that) = delete;
        Edge& operator=(const Edge& that) = delete;

    private:
        explicit Edge(EdgeData_Class data, bool directed)
            : Base(directed, std::move(data))
            , from_(0)
            , to_(0)
        {
        }

        Incidence* from_;
        Incidence* to_;
    };

}

#endif