Program Listing for File nx2bgl.hpp

Return to documentation for file (py2cpp/nx2bgl.hpp)

#pragma once

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/graph_utility.hpp>
#include <type_traits>

namespace xn {

template <typename Graph> class VertexView : public Graph {
  public:
    explicit VertexView(Graph &&G) noexcept : Graph{std::forward<Graph>(G)} {}

    [[nodiscard]] auto begin() const {
        // auto [v_iter, v_end] = boost::vertices(*this);
        // return v_iter;
        return boost::vertices(*this).first;
    }

    [[nodiscard]] auto end() const {
        // auto [v_iter, v_end] = boost::vertices(*this);
        // return v_end;
        return boost::vertices(*this).second;
    }

    [[nodiscard]] auto cbegin() const {
        // auto [v_iter, v_end] = boost::vertices(*this);
        // return v_iter;
        return boost::vertices(*this).first;
    }

    [[nodiscard]] auto cend() const {
        // auto [v_iter, v_end] = boost::vertices(*this);
        // return v_end;
        return boost::vertices(*this).second;
    }
};

template <typename Graph> class EdgeView {
  private:
    const Graph &G;

  public:
    explicit EdgeView(const Graph &G) : G{G} {}

    [[nodiscard]] auto begin() const {
        // auto [e_iter, e_end] = boost::edges(_G);
        // return e_iter;
        return boost::edges(this->G).first;
    }

    [[nodiscard]] auto end() const {
        // auto [e_iter, e_end] = boost::edges(_G);
        // return e_end;
        return boost::edges(this->G).second;
    }

    [[nodiscard]] auto cbegin() const {
        // auto [e_iter, e_end] = boost::edges(_G);
        // return e_iter;
        return boost::edges(this->G).first;
    }

    [[nodiscard]] auto cend() const {
        // auto [e_iter, e_end] = boost::edges(_G);
        // return e_end;
        return boost::edges(this->G).second;
    }
};

template <typename Vertex, typename Graph> class AtlasView {
  private:
    Vertex _v;
    const Graph &G;

  public:
    AtlasView(Vertex v, const Graph &G) : _v{v}, G{G} {}

    auto begin() const {
        // auto [e_iter, e_end] = boost::out_edges(_v, _G);
        // return e_iter;
        return boost::out_edges(this->_v, this->G).first;
    }

    auto end() const {
        // auto [e_iter, e_end] = boost::out_edges(_v, _G);
        // return e_end;
        return boost::out_edges(this->_v, this->G).second;
    }

    auto cbegin() const {
        // auto [e_iter, e_end] = boost::out_edges(_v, _G);
        // return e_iter;
        return boost::out_edges(this->_v, this->G).first;
    }

    auto cend() const {
        // auto [e_iter, e_end] = boost::out_edges(_v, _G);
        // return e_end;
        return boost::out_edges(this->_v, this->G).second;
    }
};

template <typename Graph> class grAdaptor : public VertexView<Graph> {
  public:
    using Vertex = typename boost::graph_traits<Graph>::vertex_descriptor;
    using node_t = Vertex;
    using edge_t = typename boost::graph_traits<Graph>::edge_descriptor;

    // using edge_wt_t = decltype( boost::get(boost::edge_weight,
    // std::declval<Graph>()) );

    grAdaptor() = delete;

    explicit grAdaptor(Graph &&G) noexcept
        : VertexView<Graph>{std::forward<Graph>(G)} {}

    // grAdaptor(const grAdaptor&) = delete;            // don't copy
    // grAdaptor& operator=(const grAdaptor&) = delete; // don't assign
    // grAdaptor(grAdaptor&&) noexcept = default;                // don't copy

    [[nodiscard]] auto number_of_nodes() const {
        return boost::num_vertices(*this);
    }

    [[nodiscard]] auto number_of_edges() const {
        return boost::num_edges(*this);
    }

    [[nodiscard]] auto edges() const -> EdgeView<Graph> {
        return EdgeView<Graph>(*this);
    }

    [[nodiscard]] auto neighbors(Vertex v) const -> AtlasView<Vertex, Graph> {
        return AtlasView<Vertex, Graph>(v, *this);
    }

    auto add_edge(int u, int v) { return boost::add_edge(u, v, *this); }

    static auto null_vertex() -> Vertex {
        return boost::graph_traits<Graph>::null_vertex();
    }

    template <typename Edge> auto source(const Edge &e) const -> Vertex {
        return boost::source(e, *this);
    }

    template <typename Edge> auto target(const Edge &e) const -> Vertex {
        return boost::target(e, *this);
    }

    template <typename Edge>
    [[nodiscard]] auto end_points(const Edge &e) const {
        auto s = boost::source(e, *this);
        auto t = boost::target(e, *this);
        return std::make_pair(s, t);
    }
};

} // namespace xn