// (C) Copyright 2007-2009 Andrew Sutton
//
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0 (See accompanying file
// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_GRAPH_UNDIRECTED_GRAPH_HPP
#define BOOST_GRAPH_UNDIRECTED_GRAPH_HPP

#include <boost/utility.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/properties.hpp>

// NOTE: The retag_property_list is used to "normalize" a proeprty such that
// any non-property conforming parameter is wrapped in a vertex_bundle
// property. For example (with bad syntax) retag<property<X>> -> property<X>,
// but retag<foo> -> property<vertex_bundle_t, foo>.

namespace boost
{
struct undirected_graph_tag { };

/**
 * The undirected_graph class template is a simplified version of the BGL
 * adjacency list. This class is provided for ease of use, but may not
 * perform as well as custom-defined adjacency list classes. Instances of
 * this template model the VertexIndexGraph, and EdgeIndexGraph concepts. The
 * graph is also fully mutable, supporting both insertions and removals of
 * vertices and edges.
 *
 * @note Special care must be taken when removing vertices or edges since
 * those operations can invalidate the numbering of vertices.
 */
template <
    typename VertexProp = no_property,
    typename EdgeProp = no_property,
    typename GraphProp = no_property>
class undirected_graph
{
public:
    typedef typename graph_detail::graph_prop<GraphProp>::property graph_property_type;
    typedef typename graph_detail::graph_prop<GraphProp>::bundle graph_bundled;

    typedef typename graph_detail::vertex_prop<VertexProp>::property vertex_property_type;
    typedef typename graph_detail::vertex_prop<VertexProp>::bundle vertex_bundled;

    typedef typename graph_detail::edge_prop<EdgeProp>::property edge_property_type;
    typedef typename graph_detail::edge_prop<EdgeProp>::bundle edge_bundled;

private:
    // Embed indices into the vertex type.
    typedef property<vertex_index_t, unsigned, vertex_property_type> vertex_property;
    typedef property<edge_index_t, unsigned, edge_property_type> edge_property;
public:
    typedef adjacency_list<listS,
                listS,
                undirectedS,
                vertex_property,
                edge_property,
                GraphProp,
                listS> graph_type;
private:
    // storage selectors
    typedef typename graph_type::vertex_list_selector vertex_list_selector;
    typedef typename graph_type::edge_list_selector edge_list_selector;
    typedef typename graph_type::out_edge_list_selector out_edge_list_selector;
    typedef typename graph_type::directed_selector directed_selector;

public:
    // more commonly used graph types
    typedef typename graph_type::stored_vertex stored_vertex;
    typedef typename graph_type::vertices_size_type vertices_size_type;
    typedef typename graph_type::edges_size_type edges_size_type;
    typedef typename graph_type::degree_size_type degree_size_type;
    typedef typename graph_type::vertex_descriptor vertex_descriptor;
    typedef typename graph_type::edge_descriptor edge_descriptor;

    // iterator types
    typedef typename graph_type::vertex_iterator vertex_iterator;
    typedef typename graph_type::edge_iterator edge_iterator;
    typedef typename graph_type::out_edge_iterator out_edge_iterator;
    typedef typename graph_type::in_edge_iterator in_edge_iterator;
    typedef typename graph_type::adjacency_iterator adjacency_iterator;

    // miscellaneous types
    typedef undirected_graph_tag graph_tag;
    typedef typename graph_type::directed_category directed_category;
    typedef typename graph_type::edge_parallel_category edge_parallel_category;
    typedef typename graph_type::traversal_category traversal_category;

    typedef std::size_t vertex_index_type;
    typedef std::size_t edge_index_type;

    inline undirected_graph(GraphProp const& p = GraphProp())
        : m_graph(p), m_num_vertices(0), m_num_edges(0), m_max_vertex_index(0)
        , m_max_edge_index(0)
    { }

    inline undirected_graph(undirected_graph const& x)
        : m_graph(x.m_graph), m_num_vertices(x.m_num_vertices), m_num_edges(x.m_num_edges)
        , m_max_vertex_index(x.m_max_vertex_index), m_max_edge_index(x.m_max_edge_index)
    { }

    inline undirected_graph(vertices_size_type n,
                            GraphProp const& p = GraphProp())
        : m_graph(n, p), m_num_vertices(n), m_num_edges(0), m_max_vertex_index(n)
        , m_max_edge_index(0)
    { renumber_vertex_indices(); }

    template <typename EdgeIterator>
    inline undirected_graph(EdgeIterator f,
                            EdgeIterator l,
                            vertices_size_type n,
                            edges_size_type m = 0,
                            GraphProp const& p = GraphProp())
        : m_graph(f, l, n, m, p), m_num_vertices(n), m_num_edges(0)
        , m_max_vertex_index(n), m_max_edge_index(0)
    {
        // Unfortunately, we have to renumber to ensure correct indexing.
        renumber_indices();

        // Can't always guarantee that the number of edges is actually
        // m if distance(f, l) != m (or is undefined).
        m_num_edges = m_max_edge_index = boost::num_edges(m_graph);
    }

    undirected_graph& operator =(undirected_graph const& g) {
        if(&g != this) {
            m_graph = g.m_graph;
            m_num_vertices = g.m_num_vertices;
            m_num_edges = g.m_num_edges;
            m_max_vertex_index = g.m_max_vertex_index;
        }
        return *this;
    }

    // The impl_() methods are not part of the public interface.
    graph_type& impl()
    { return m_graph; }

    graph_type const& impl() const
    { return m_graph; }

    // The following methods are not part of the public interface
    vertices_size_type num_vertices() const
    { return m_num_vertices; }


private:
    // This helper function manages the attribution of vertex indices.
    vertex_descriptor make_index(vertex_descriptor v) {
        boost::put(vertex_index, m_graph, v, m_max_vertex_index);
        m_num_vertices++;
        m_max_vertex_index++;
        return v;
    }
public:
    vertex_descriptor add_vertex()
    { return make_index(boost::add_vertex(m_graph)); }

    vertex_descriptor add_vertex(vertex_property_type const& p)
    { return make_index(boost::add_vertex(vertex_property(0u, p), m_graph)); }

    void clear_vertex(vertex_descriptor v) {
        std::pair<out_edge_iterator, out_edge_iterator>
        p = boost::out_edges(v, m_graph);
        m_num_edges -= std::distance(p.first, p.second);
        boost::clear_vertex(v, m_graph);
    }

    void remove_vertex(vertex_descriptor v) {
        boost::remove_vertex(v, m_graph);
        --m_num_vertices;
    }

    edges_size_type num_edges() const
    { return m_num_edges; }

private:
    // A helper fucntion for managing edge index attributes.
    std::pair<edge_descriptor, bool> const&
    make_index(std::pair<edge_descriptor, bool> const& x)
    {
        if(x.second) {
            boost::put(edge_index, m_graph, x.first, m_max_edge_index);
            ++m_num_edges;
            ++m_max_edge_index;
        }
        return x;
    }
public:
    std::pair<edge_descriptor, bool>
    add_edge(vertex_descriptor u, vertex_descriptor v)
    { return make_index(boost::add_edge(u, v, m_graph)); }

    std::pair<edge_descriptor, bool>
    add_edge(vertex_descriptor u, vertex_descriptor v,
             edge_property_type const& p)
    { return make_index(boost::add_edge(u, v, edge_property(0u, p), m_graph)); }

    void remove_edge(vertex_descriptor u, vertex_descriptor v) {
        // find all edges, (u, v)
        std::vector<edge_descriptor> edges;
        out_edge_iterator i, i_end;
        for(boost::tie(i, i_end) = boost::out_edges(u, m_graph); i != i_end; ++i) {
            if(boost::target(*i, m_graph) == v) {
                edges.push_back(*i);
            }
        }
        // remove all edges, (u, v)
        typename std::vector<edge_descriptor>::iterator
        j = edges.begin(), j_end = edges.end();
        for( ; j != j_end; ++j) {
            remove_edge(*j);
        }
    }

    void remove_edge(edge_iterator i) {
        remove_edge(*i);
    }

    void remove_edge(edge_descriptor e) {
        boost::remove_edge(e, m_graph);
        --m_num_edges;
    }

    vertex_index_type max_vertex_index() const
    { return m_max_vertex_index; }

    void renumber_vertex_indices() {
        vertex_iterator i, i_end;
        boost::tie(i, i_end) = vertices(m_graph);
        m_max_vertex_index = renumber_vertex_indices(i, i_end, 0);
    }

    void remove_vertex_and_renumber_indices(vertex_iterator i) {
        vertex_iterator j = next(i), end = vertices(m_graph).second;
        vertex_index_type n = get(vertex_index, m_graph, *i);

        // remove the offending vertex and renumber everything after
        remove_vertex(*i);
        m_max_vertex_index = renumber_vertex_indices(j, end, n);
    }


    edge_index_type max_edge_index() const
    { return m_max_edge_index; }

    void renumber_edge_indices() {
        edge_iterator i, end;
        boost::tie(i, end) = edges(m_graph);
        m_max_edge_index = renumber_edge_indices(i, end, 0);
    }

    void remove_edge_and_renumber_indices(edge_iterator i) {
        edge_iterator j = next(i), end = edges(m_graph.second);
        edge_index_type n = get(edge_index, m_graph, *i);

        // remove the edge and renumber everything after it
        remove_edge(*i);
        m_max_edge_index = renumber_edge_indices(j, end, n);
    }

    void renumber_indices() {
        renumber_vertex_indices();
        renumber_edge_indices();
    }

    // bundled property support
#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
    vertex_bundled& operator[](vertex_descriptor v)
    { return m_graph[v]; }

    vertex_bundled const& operator[](vertex_descriptor v) const
    { return m_graph[v]; }

    edge_bundled& operator[](edge_descriptor e)
    { return m_graph[e]; }

    edge_bundled const& operator[](edge_descriptor e) const
    { return m_graph[e]; }

    graph_bundled& operator[](graph_bundle_t)
    { return get_property(*this); }

    graph_bundled const& operator[](graph_bundle_t) const
    { return get_property(*this); }
#endif

    // Graph concepts
    static vertex_descriptor null_vertex()
    { return graph_type::null_vertex(); }

    void clear() {
        m_graph.clear();
        m_num_vertices = m_max_vertex_index = 0;
        m_num_edges = m_max_edge_index = 0;
    }

    void swap(undirected_graph& g) {
        m_graph.swap(g);
        std::swap(m_num_vertices, g.m_num_vertices);
        std::swap(m_max_vertex_index, g.m_max_vertex_index);
        std::swap(m_num_edges, g.m_num_edges);
        std::swap(m_max_edge_index, g.m_max_edge_index);
    }

private:
    vertices_size_type renumber_vertex_indices(vertex_iterator i,
                                               vertex_iterator end,
                                               vertices_size_type n)
    {
        typedef typename property_map<graph_type, vertex_index_t>::type IndexMap;
        IndexMap indices = get(vertex_index, m_graph);
        for( ; i != end; ++i) {
            indices[*i] = n++;
        }
        return n;
    }

    edges_size_type renumber_edge_indices(edge_iterator i,
                                          edge_iterator end,
                                          edges_size_type n)
    {
        typedef typename property_map<graph_type, edge_index_t>::type IndexMap;
        IndexMap indices = get(edge_index, m_graph);
        for( ; i != end; ++i) {
            indices[*i] = n++;
        }
        return n;
    }

    graph_type m_graph;
    vertices_size_type m_num_vertices;
    edges_size_type m_num_edges;
    vertex_index_type m_max_vertex_index;
    edge_index_type m_max_edge_index;
};

#define UNDIRECTED_GRAPH_PARAMS typename VP, typename EP, typename GP
#define UNDIRECTED_GRAPH undirected_graph<VP,EP,GP>

// IncidenceGraph concepts
template <UNDIRECTED_GRAPH_PARAMS>
inline typename UNDIRECTED_GRAPH::vertex_descriptor
source(typename UNDIRECTED_GRAPH::edge_descriptor e,
       UNDIRECTED_GRAPH const& g)
{ return source(e, g.impl()); }

template <UNDIRECTED_GRAPH_PARAMS>
inline typename UNDIRECTED_GRAPH::vertex_descriptor
target(typename UNDIRECTED_GRAPH::edge_descriptor e,
       UNDIRECTED_GRAPH const& g)
{ return target(e, g.impl()); }

template <UNDIRECTED_GRAPH_PARAMS>
inline typename UNDIRECTED_GRAPH::degree_size_type
out_degree(typename UNDIRECTED_GRAPH::vertex_descriptor v,
           UNDIRECTED_GRAPH const& g)
{ return out_degree(v, g.impl()); }

template <UNDIRECTED_GRAPH_PARAMS>
inline std::pair<
    typename UNDIRECTED_GRAPH::out_edge_iterator,
    typename UNDIRECTED_GRAPH::out_edge_iterator
>
out_edges(typename UNDIRECTED_GRAPH::vertex_descriptor v,
          UNDIRECTED_GRAPH const& g)
{ return out_edges(v, g.impl()); }

// BidirectionalGraph concepts
template <UNDIRECTED_GRAPH_PARAMS>
inline typename UNDIRECTED_GRAPH::degree_size_type
in_degree(typename UNDIRECTED_GRAPH::vertex_descriptor v,
          UNDIRECTED_GRAPH const& g)
{ return in_degree(v, g.impl()); }

template <UNDIRECTED_GRAPH_PARAMS>
inline std::pair<
    typename UNDIRECTED_GRAPH::in_edge_iterator,
    typename UNDIRECTED_GRAPH::in_edge_iterator
>
in_edges(typename UNDIRECTED_GRAPH::vertex_descriptor v,
         UNDIRECTED_GRAPH const& g)
{ return in_edges(v, g.impl()); }

template <UNDIRECTED_GRAPH_PARAMS>
inline std::pair<
    typename UNDIRECTED_GRAPH::out_edge_iterator,
    typename UNDIRECTED_GRAPH::out_edge_iterator
>
incident_edges(typename UNDIRECTED_GRAPH::vertex_descriptor v,
               UNDIRECTED_GRAPH const& g)
{ return out_edges(v, g.impl()); }

template <UNDIRECTED_GRAPH_PARAMS>
inline typename UNDIRECTED_GRAPH::degree_size_type
degree(typename UNDIRECTED_GRAPH::vertex_descriptor v,
       UNDIRECTED_GRAPH const& g)
{ return degree(v, g.impl()); }

// AdjacencyGraph concepts
template <UNDIRECTED_GRAPH_PARAMS>
inline std::pair<
    typename UNDIRECTED_GRAPH::adjacency_iterator,
    typename UNDIRECTED_GRAPH::adjacency_iterator
    >
adjacent_vertices(typename UNDIRECTED_GRAPH::vertex_descriptor v,
                  UNDIRECTED_GRAPH const& g)
{ return adjacent_vertices(v, g.impl()); }

template <UNDIRECTED_GRAPH_PARAMS>
typename UNDIRECTED_GRAPH::vertex_descriptor
vertex(typename UNDIRECTED_GRAPH::vertices_size_type n,
       UNDIRECTED_GRAPH const& g)
{ return vertex(g.impl()); }

template <UNDIRECTED_GRAPH_PARAMS>
std::pair<typename UNDIRECTED_GRAPH::edge_descriptor, bool>
edge(typename UNDIRECTED_GRAPH::vertex_descriptor u,
    typename UNDIRECTED_GRAPH::vertex_descriptor v,
    UNDIRECTED_GRAPH const& g)
{ return edge(u, v, g.impl()); }

// VertexListGraph concepts
template <UNDIRECTED_GRAPH_PARAMS>
inline typename UNDIRECTED_GRAPH::vertices_size_type
num_vertices(UNDIRECTED_GRAPH const& g)
{ return g.num_vertices(); }

template <UNDIRECTED_GRAPH_PARAMS>
inline std::pair<
    typename UNDIRECTED_GRAPH::vertex_iterator,
    typename UNDIRECTED_GRAPH::vertex_iterator
>
vertices(UNDIRECTED_GRAPH const& g)
{ return vertices(g.impl()); }

// EdgeListGraph concepts
template <UNDIRECTED_GRAPH_PARAMS>
inline typename UNDIRECTED_GRAPH::edges_size_type
num_edges(UNDIRECTED_GRAPH const& g)
{ return g.num_edges(); }

template <UNDIRECTED_GRAPH_PARAMS>
inline std::pair<
    typename UNDIRECTED_GRAPH::edge_iterator,
    typename UNDIRECTED_GRAPH::edge_iterator
>
edges(UNDIRECTED_GRAPH const& g)
{ return edges(g.impl()); }

// MutableGraph concepts
template <UNDIRECTED_GRAPH_PARAMS>
inline typename UNDIRECTED_GRAPH::vertex_descriptor
add_vertex(UNDIRECTED_GRAPH& g)
{ return g.add_vertex(); }

template <UNDIRECTED_GRAPH_PARAMS>
inline typename UNDIRECTED_GRAPH::vertex_descriptor
add_vertex(typename UNDIRECTED_GRAPH::vertex_property_type const& p,
           UNDIRECTED_GRAPH& g)
{ return g.add_vertex(p); }

template <UNDIRECTED_GRAPH_PARAMS>
inline void
clear_vertex(typename UNDIRECTED_GRAPH::vertex_descriptor v,
             UNDIRECTED_GRAPH& g)
{ return g.clear_vertex(v); }

template <UNDIRECTED_GRAPH_PARAMS>
inline void
remove_vertex(typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g)
{ return g.remove_vertex(v); }

template <UNDIRECTED_GRAPH_PARAMS>
inline std::pair<typename UNDIRECTED_GRAPH::edge_descriptor, bool>
add_edge(typename UNDIRECTED_GRAPH::vertex_descriptor u,
         typename UNDIRECTED_GRAPH::vertex_descriptor v,
         UNDIRECTED_GRAPH& g)
{ return g.add_edge(u, v); }

template <UNDIRECTED_GRAPH_PARAMS>
inline std::pair<typename UNDIRECTED_GRAPH::edge_descriptor, bool>
add_edge(typename UNDIRECTED_GRAPH::vertex_descriptor u,
         typename UNDIRECTED_GRAPH::vertex_descriptor v,
         typename UNDIRECTED_GRAPH::edge_property_type const& p,
         UNDIRECTED_GRAPH& g)
{ return g.add_edge(u, v, p); }

template <UNDIRECTED_GRAPH_PARAMS>
inline void
remove_edge(typename UNDIRECTED_GRAPH::vertex_descriptor u,
            typename UNDIRECTED_GRAPH::vertex_descriptor v,
            UNDIRECTED_GRAPH& g)
{ return g.remove_edge(u, v); }

template <UNDIRECTED_GRAPH_PARAMS>
inline void
remove_edge(typename UNDIRECTED_GRAPH::edge_descriptor e, UNDIRECTED_GRAPH& g)
{ return g.remove_edge(e); }

template <UNDIRECTED_GRAPH_PARAMS>
inline void
remove_edge(typename UNDIRECTED_GRAPH::edge_iterator i, UNDIRECTED_GRAPH& g)
{ return g.remove_edge(i); }

template <UNDIRECTED_GRAPH_PARAMS, class Predicate>
inline void remove_edge_if(Predicate pred, UNDIRECTED_GRAPH& g)
{ return remove_edge_if(pred, g.impl()); }

template <UNDIRECTED_GRAPH_PARAMS, class Predicate>
inline void
remove_incident_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v,
                        Predicate pred,
                        UNDIRECTED_GRAPH& g)
{ return remove_out_edge_if(v, pred, g.impl()); }

template <UNDIRECTED_GRAPH_PARAMS, class Predicate>
inline void
remove_out_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v,
                   Predicate pred,
                   UNDIRECTED_GRAPH& g)
{ return remove_out_edge_if(v, pred, g.impl()); }

template <UNDIRECTED_GRAPH_PARAMS, class Predicate>
inline void
remove_in_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v,
                  Predicate pred,
                  UNDIRECTED_GRAPH& g)
{ return remove_in_edge_if(v, pred, g.impl()); }

// Helper code for working with property maps
namespace detail {
    struct undirected_graph_vertex_property_selector {
        template <class UndirectedGraph, class Property, class Tag>
        struct bind_ {
            typedef typename UndirectedGraph::graph_type Graph;
            typedef property_map<Graph, Tag> PropertyMap;
            typedef typename PropertyMap::type type;
            typedef typename PropertyMap::const_type const_type;
        };
    };

    struct undirected_graph_edge_property_selector {
        template <class UndirectedGraph, class Property, class Tag>
        struct bind_ {
            typedef typename UndirectedGraph::graph_type Graph;
            typedef property_map<Graph, Tag> PropertyMap;
            typedef typename PropertyMap::type type;
            typedef typename PropertyMap::const_type const_type;
        };
    };
} // namespace detail

template <>
struct vertex_property_selector<undirected_graph_tag>
{ typedef detail::undirected_graph_vertex_property_selector type; };

template <>
struct edge_property_selector<undirected_graph_tag>
{ typedef detail::undirected_graph_edge_property_selector type; };

// PropertyGraph concepts
template <UNDIRECTED_GRAPH_PARAMS, typename Property>
inline typename property_map<UNDIRECTED_GRAPH, Property>::type
get(Property p, UNDIRECTED_GRAPH& g)
{ return get(p, g.impl()); }

template <UNDIRECTED_GRAPH_PARAMS, typename Property>
inline typename property_map<UNDIRECTED_GRAPH, Property>::const_type
get(Property p, UNDIRECTED_GRAPH const& g)
{ return get(p, g.impl()); }

template <UNDIRECTED_GRAPH_PARAMS, typename Property, typename Key>
inline typename property_traits<
    typename property_map<
        typename UNDIRECTED_GRAPH::graph_type, Property
    >::const_type
>::value_type
get(Property p, UNDIRECTED_GRAPH const& g, Key const& k)
{ return get(p, g.impl(), k); }

template <UNDIRECTED_GRAPH_PARAMS, typename Property, typename Key, typename Value>
inline void put(Property p, UNDIRECTED_GRAPH& g, Key const& k, Value const& v)
{ put(p, g.impl(), k, v); }

template <UNDIRECTED_GRAPH_PARAMS, class Property>
inline typename graph_property<UNDIRECTED_GRAPH, Property>::type&
get_property(UNDIRECTED_GRAPH& g, Property p)
{ return get_property(g.impl(), p); }

template <UNDIRECTED_GRAPH_PARAMS, class Property>
inline typename graph_property<UNDIRECTED_GRAPH, Property>::type const&
get_property(UNDIRECTED_GRAPH const& g, Property p)
{ return get_property(g.impl(), p); }

template <UNDIRECTED_GRAPH_PARAMS, class Property, class Value>
inline void set_property(UNDIRECTED_GRAPH& g, Property p, Value v)
{ return set_property(g.impl(), p, v); }

#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
template <UNDIRECTED_GRAPH_PARAMS, typename Type, typename Bundle>
inline typename property_map<UNDIRECTED_GRAPH, Type Bundle::*>::type
get(Type Bundle::* p, UNDIRECTED_GRAPH& g) {
    typedef typename property_map<
        UNDIRECTED_GRAPH, Type Bundle::*
    >::type return_type;
    return return_type(&g, p);
}

template <UNDIRECTED_GRAPH_PARAMS, typename Type, typename Bundle>
inline typename property_map<UNDIRECTED_GRAPH, Type Bundle::*>::const_type
get(Type Bundle::* p, UNDIRECTED_GRAPH const& g) {
    typedef typename property_map<
        UNDIRECTED_GRAPH, Type Bundle::*
    >::const_type return_type;
    return return_type(&g, p);
}

template <UNDIRECTED_GRAPH_PARAMS, typename Type, typename Bundle, typename Key>
inline Type
get(Type Bundle::* p, UNDIRECTED_GRAPH const& g, Key const& k)
{ return get(p, g.impl(), k); }

template <UNDIRECTED_GRAPH_PARAMS, typename Type, typename Bundle, typename Key, typename Value>
inline void
put(Type Bundle::* p, UNDIRECTED_GRAPH& g, Key const& k, Value const& v)
{ put(p, g.impl(), k, v); }
#endif

// Indexed Vertex graph

template <UNDIRECTED_GRAPH_PARAMS>
inline typename UNDIRECTED_GRAPH::vertex_index_type
get_vertex_index(typename UNDIRECTED_GRAPH::vertex_descriptor v,
                 UNDIRECTED_GRAPH const& g)
{ return get(vertex_index, g, v); }

template <UNDIRECTED_GRAPH_PARAMS>
typename UNDIRECTED_GRAPH::vertex_index_type
max_vertex_index(UNDIRECTED_GRAPH const& g)
{ return g.max_vertex_index(); }

template <UNDIRECTED_GRAPH_PARAMS>
inline void
renumber_vertex_indices(UNDIRECTED_GRAPH& g)
{ g.renumber_vertex_indices(); }

template <UNDIRECTED_GRAPH_PARAMS>
inline void
remove_vertex_and_renumber_indices(typename UNDIRECTED_GRAPH::vertex_iterator i,
                                   UNDIRECTED_GRAPH& g)
{ g.remove_vertex_and_renumber_indices(i); }


// Edge index management

template <UNDIRECTED_GRAPH_PARAMS>
inline typename UNDIRECTED_GRAPH::edge_index_type
get_edge_index(typename UNDIRECTED_GRAPH::edge_descriptor v,
               UNDIRECTED_GRAPH const& g)
{ return get(edge_index, g, v); }

template <UNDIRECTED_GRAPH_PARAMS>
typename UNDIRECTED_GRAPH::edge_index_type
max_edge_index(UNDIRECTED_GRAPH const& g)
{ return g.max_edge_index(); }

template <UNDIRECTED_GRAPH_PARAMS>
inline void
renumber_edge_indices(UNDIRECTED_GRAPH& g)
{ g.renumber_edge_indices(); }

template <UNDIRECTED_GRAPH_PARAMS>
inline void
remove_edge_and_renumber_indices(typename UNDIRECTED_GRAPH::edge_iterator i,
                                 UNDIRECTED_GRAPH& g)
{ g.remove_edge_and_renumber_indices(i); }

// Index management
template <UNDIRECTED_GRAPH_PARAMS>
inline void
renumber_indices(UNDIRECTED_GRAPH& g)
{ g.renumber_indices(); }

// Mutability Traits
template <UNDIRECTED_GRAPH_PARAMS>
struct graph_mutability_traits<UNDIRECTED_GRAPH> {
    typedef mutable_property_graph_tag category;
};

#undef UNDIRECTED_GRAPH_PARAMS
#undef UNDIRECTED_GRAPH

} /* namespace boost */

#endif
