1 //=======================================================================
2 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
3 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See
6 // accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //=======================================================================
9 
10 /*
11   Sample data (edge_iterator_constructor.dat):
12   5
13   10
14   0 1
15   1 2
16   1 3
17   2 4
18   3 4
19   1 0
20   2 1
21   3 1
22   4 2
23   4 3
24 
25   Sample output:
26 
27   0 --> 1
28   1 --> 2 3 0
29   2 --> 4 1
30   3 --> 4 1
31   4 --> 2 3
32 
33  */
34 
35 #include <boost/config.hpp>
36 #include <utility>
37 #include <iostream>
38 #include <fstream>
39 
40 #include <iterator>
41 #include <boost/graph/graph_utility.hpp>
42 #include <boost/graph/adjacency_list.hpp>
43 
44 class edge_stream_iterator {
45 public:
46   typedef std::input_iterator_tag  iterator_category;
47   typedef std::pair<int,int>  value_type;
48   typedef std::ptrdiff_t      difference_type;
49   typedef const value_type*   pointer;
50   typedef const value_type&   reference;
51 
edge_stream_iterator()52   edge_stream_iterator() : m_stream(0), m_end_marker(false) {}
edge_stream_iterator(std::istream & s)53   edge_stream_iterator(std::istream& s) : m_stream(&s) { m_read(); }
operator *() const54   reference operator*() const { return m_edge; }
operator ++()55   edge_stream_iterator& operator++() {
56     m_read();
57     return *this;
58   }
operator ++(int)59   edge_stream_iterator operator++(int)  {
60     edge_stream_iterator tmp = *this;
61     m_read();
62     return tmp;
63   }
64 protected:
65   std::istream* m_stream;
66   value_type m_edge;
67   bool m_end_marker;
m_read()68   void m_read() {
69     m_end_marker = (*m_stream) ? true : false;
70     if (m_end_marker) {
71       *m_stream >> m_edge.first >> m_edge.second;
72     }
73     m_end_marker = (*m_stream) ? true : false;
74   }
75   friend bool operator==(const edge_stream_iterator& x,
76                          const edge_stream_iterator& y);
77 
78 };
operator ==(const edge_stream_iterator & x,const edge_stream_iterator & y)79 bool operator==(const edge_stream_iterator& x,
80                 const edge_stream_iterator& y)
81 {
82   return (x.m_stream == y.m_stream && x.m_end_marker == y.m_end_marker)
83     || (x.m_end_marker == false && y.m_end_marker == false);
84 }
operator !=(const edge_stream_iterator & x,const edge_stream_iterator & y)85 bool operator!=(const edge_stream_iterator& x,
86                 const edge_stream_iterator& y)
87 {
88   return !(x == y);
89 }
90 
91 
92 
93 int
main(int argc,const char ** argv)94 main(int argc, const char** argv)
95 {
96   typedef boost::adjacency_list<> IteratorConstructibleGraph;
97   typedef boost::graph_traits<IteratorConstructibleGraph> Traits;
98   Traits::vertices_size_type size_V;
99   Traits::edges_size_type size_E;
100 
101   std::ifstream f(argc >= 2 ? argv[1] : "edge_iterator_constructor.dat");
102   f >> size_V >> size_E;
103 
104   edge_stream_iterator edge_iter(f), end;
105 #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
106   // VC++ can't handle the iterator constructor
107   IteratorConstructibleGraph G(size_V);
108   while (edge_iter != end) {
109     int i, j;
110     boost::tie(i, j) = *edge_iter++;
111     boost::add_edge(i, j, G);
112   }
113 #else
114   IteratorConstructibleGraph G(edge_iter, end, size_V);
115 #endif
116   boost::print_graph(G);
117 
118   return 0;
119 }
120