incidence_graph_fwd.h

Back to Incidence graph

pastel/sys/incidence_graph/

// Description: Types for the incidence graph

#ifndef PASTELSYS_INCIDENCE_GRAPH_FWD_H
#define PASTELSYS_INCIDENCE_GRAPH_FWD_H

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

#include <boost/iterator/iterator_adaptor.hpp>

#include <type_traits>
#include <list>

namespace Pastel
{

    enum class GraphType : integer
    {
        Undirected,
        Directed,
        Mixed,
    };

    namespace IncidenceGraph_
    {

        template <typename Type>
        class Incidence_Iterator
            : public boost::iterator_adaptor<
            Incidence_Iterator<Type>, Type>
        {
        public:
            Incidence_Iterator()
                : Incidence_Iterator::iterator_adaptor_(0) 
            {
            }

            Incidence_Iterator(Type that)
                : Incidence_Iterator::iterator_adaptor_(that) 
            {
            }

            template <
                typename That, 
                Requires<std::is_convertible<That, Type>> = 0>
            Incidence_Iterator(const Incidence_Iterator<That>& that)
                : Incidence_Iterator::iterator_adaptor_(that.base()) 
            {
            }

        private:
            friend class boost::iterator_core_access;

            void increment() 
            { 
                this->base_reference() = this->base()->next_;
            }
        };

    }

    template <typename Settings_>
    class IncidenceGraph_Fwd
    {
    public:
        using Settings = Settings_;
        using Fwd = Settings;

        static constexpr GraphType Type = Settings::Type;
        PASTEL_FWD(VertexData);
        PASTEL_FWD(EdgeData);

        using VertexData_Class = Class<VertexData>;
        using EdgeData_Class = Class<EdgeData>;

        PASTEL_STATIC_ASSERT(
            Type == GraphType::Undirected ||
            Type == GraphType::Directed ||
            Type == GraphType::Mixed);

        // Vertices

        class Vertex;
        using VertexSet = std::list<Vertex>;
        using Vertex_Iterator =    typename VertexSet::iterator;
        using Vertex_ConstIterator = 
#ifndef __GNUC__
            typename VertexSet::const_iterator;
#else
            Vertex_Iterator;
#endif

        // Edges

        class Edge;
        using EdgeSet = std::list<Edge>;
        using Edge_Iterator = typename EdgeSet::iterator;
        using Edge_ConstIterator = 
#ifndef __GNUC__
            typename EdgeSet::const_iterator;
#else
            Edge_Iterator;
#endif

        // Incidences

        class Incidence_Link;
        class Incidence;
        using Incidence_Iterator = 
            IncidenceGraph_::Incidence_Iterator<Incidence*>;
        using Incidence_ConstIterator = 
            IncidenceGraph_::Incidence_Iterator<const Incidence*>;

        enum : int
        {
            IncidenceTypes = 
                (Type == GraphType::Undirected) ? 
                1 : ((Type == GraphType::Directed) ? 2 : 3),

            Undirected = 
                (Type == GraphType::Directed) ? 
                IncidenceTypes : 0,

            Incoming = 
                (Type == GraphType::Directed) ? 
                0 : ((Type == GraphType::Mixed) ? 1 : IncidenceTypes),

            Outgoing = 
                (Type == GraphType::Directed) ? 
                1 : ((Type == GraphType::Mixed) ? 2 : IncidenceTypes)
        };
    };

}

namespace Pastel
{

    template <typename Settings>
    class No_Incidence_Graph_Customization
    {
    protected:
        using Fwd = IncidenceGraph_Fwd<Settings>;

        PASTEL_FWD(Vertex_Iterator);
        PASTEL_FWD(Vertex_ConstIterator);
        PASTEL_FWD(Edge_Iterator);
        PASTEL_FWD(Edge_ConstIterator);

        No_Incidence_Graph_Customization() {}
        void swap(No_Incidence_Graph_Customization& that) {}

        void onClear() {}
        void onAddVertex(const Vertex_Iterator& vertex) {}
        void onRemoveVertex(const Vertex_Iterator& that) {}
        void onAddEdge(const Edge_Iterator& that) {}
        void onRemoveEdge(const Edge_Iterator& that) {}

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

    template <
        typename Settings, 
        template <typename> class = No_Incidence_Graph_Customization>
    class IncidenceGraph;

}

namespace Pastel
{

    template <
        GraphType Type_, 
        typename VertexData_ = void, 
        typename EdgeData_ = void>
    class IncidenceGraph_Settings
    {
    public:
        static constexpr GraphType Type = Type_;
        using VertexData = VertexData_;
        using EdgeData = EdgeData_;
    };

}

#endif