text: //=======================================================================
  // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
  //
  // Distributed under the Boost Software License, Version 1.0. (See
  // accompanying file LICENSE_1_0.txt or copy at
  // http://www.boost.org/LICENSE_1_0.txt)
  //=======================================================================
  
  #include <boost/config.hpp>
  #include <iostream>
  #include <string>
  #include <boost/graph/adjacency_list.hpp>
  #include <boost/graph/graph_utility.hpp>
  
  using namespace boost;
  
  // Predicate Function for use in remove if
  template <class NamePropertyMap>
  struct name_equals_predicate
  {
    name_equals_predicate(const std::string& x, NamePropertyMap name)
      : m_str(x), m_name(name) { }
  
    template <class Edge>
    bool operator()(const Edge& e) const {
      return m_str == m_name[e];
    }
    std::string m_str;
    NamePropertyMap m_name;
  };
  // helper creation function
  template <class NamePropertyMap>
  inline name_equals_predicate<NamePropertyMap>
  name_equals(const std::string& str, NamePropertyMap name) {
    return name_equals_predicate<NamePropertyMap>(str, name);
  }
  
  template <class MutableGraph>
  void modify_demo(MutableGraph& g)
  {
    typedef graph_traits<MutableGraph> GraphTraits;
    typedef typename GraphTraits::vertices_size_type size_type;
    typedef typename GraphTraits::edge_descriptor edge_descriptor;
    size_type n = 0;
    typename GraphTraits::edges_size_type m = 0;
    typename GraphTraits::vertex_descriptor u, v, w;
    edge_descriptor e, e1, e2;
    typename property_map<MutableGraph, edge_name_t>::type
      name_map = get(edge_name, g);
    bool added;
    typename GraphTraits::vertex_iterator vi, vi_end;
  
    {
      v = add_vertex(g);
  
      assert(num_vertices(g) == n + 1);
      assert(size_type(vertices(g).second - vertices(g).first) == n + 1);
      assert(v == *std::find(vertices(g).first, vertices(g).second, v));
    }
    {
      remove_vertex(v, g);
  
      assert(num_vertices(g) == n);
      assert(size_type(vertices(g).second - vertices(g).first) == n);
      // v is no longer a valid vertex descriptor
    }
    {
      u = add_vertex(g);
      v = add_vertex(g);
  
      std::pair<edge_descriptor, bool> p = add_edge(u, v, g);
  
      assert(num_edges(g) == m + 1);
      assert(p.second == true); // edge should have been added
      assert(source(p.first, g) == u);
      assert(target(p.first, g) == v);
      assert(p.first == *std::find(out_edges(u, g).first,
                                   out_edges(u, g).second, p.first));
      assert(p.first == *std::find(in_edges(v, g).first,
                                   in_edges(v, g).second, p.first));
    }
    {
      // use tie() for convenience, avoid using the std::pair
  
      u = add_vertex(g);
      v = add_vertex(g);
  
      boost::tie(e, added) = add_edge(u, v, g);
  
      assert(num_edges(g) == m + 2);
      assert(added == true); // edge should have been added
      assert(source(e, g) == u);
      assert(target(e, g) == v);
      assert(e == *std::find(out_edges(u, g).first, out_edges(u, g).second, e));
      assert(e == *std::find(in_edges(v, g).first, in_edges(v, g).second, e));
    }
    {
      add_edge(u, v, g); // add a parallel edge
  
      remove_edge(u, v, g);
  
      assert(num_edges(g) == m + 1);
      bool exists;
      boost::tie(e, exists) = edge(u, v, g);
      assert(exists == false);
      assert(out_degree(u, g) == 0);
      assert(in_degree(v, g) == 0);
    }
    {
      e = *edges(g).first;
      boost::tie(u, v) = incident(e, g);
  
      remove_edge(e, g);
  
      assert(num_edges(g) == m);
      assert(out_degree(u, g) == 0);
      assert(in_degree(v, g) == 0);
    }
    {
      add_edge(u, v, g);
  
      typename GraphTraits::out_edge_iterator iter, iter_end;
      boost::tie(iter, iter_end) = out_edges(u, g);
  
      remove_edge(iter, g);
  
      assert(num_edges(g) == m);
      assert(out_degree(u, g) == 0);
      assert(in_degree(v, g) == 0);
    }
    {
      w = add_vertex(g);
      boost::tie(e1, added) = add_edge(u, v, g);
      boost::tie(e2, added) = add_edge(v, w, g);
      name_map[e1] = "I-5";
      name_map[e2] = "Route 66";
  
      typename GraphTraits::out_edge_iterator iter, iter_end;
      boost::tie(iter, iter_end) = out_edges(u, g);
  
      remove_edge_if(name_equals("Route 66", name_map), g);
  
      assert(num_edges(g) == m + 1);
  
      remove_edge_if(name_equals("I-5", name_map), g);
  
      assert(num_edges(g) == m);
      assert(out_degree(u, g) == 0);
      assert(out_degree(v, g) == 0);
      assert(in_degree(v, g) == 0);
      assert(in_degree(w, g) == 0);
    }
    {
      boost::tie(e1, added) = add_edge(u, v, g);
      boost::tie(e2, added) = add_edge(u, w, g);
      name_map[e1] = "foo";
      name_map[e2] = "foo";
  
      remove_out_edge_if(u, name_equals("foo", name_map), g);
  
      assert(num_edges(g) == m);
      assert(out_degree(u, g) == 0);
    }
    {
      boost::tie(e1, added) = add_edge(u, v, g);
      boost::tie(e2, added) = add_edge(w, v, g);
      name_map[e1] = "bar";
      name_map[e2] = "bar";
  
      remove_in_edge_if(v, name_equals("bar", name_map), g);
  
      assert(num_edges(g) == m);
      assert(in_degree(v, g) == 0);
    }
    {
      add_edge(u, v, g);
      add_edge(u, w, g);
      add_edge(u, v, g);
      add_edge(v, u, g);
  
      clear_vertex(u, g);
  
      assert(out_degree(u, g) == 0);
  
      for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
        typename GraphTraits::adjacency_iterator ai, ai_end;
        for (boost::tie(ai, ai_end) = adjacent_vertices(*vi, g);
             ai != ai_end; ++ai)
          assert(*ai != u);
      }
    }
  }
  
  int
  main()
  {
    adjacency_list<listS, vecS, bidirectionalS,
      no_property, property<edge_name_t, std::string> > g;
  
    modify_demo(g);
    return 0;
  }
  