Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:37:29

0001 // Copyright (C) 2006  Tiago de Paula Peixoto <tiago@forked.de>
0002 // Copyright (C) 2004  The Trustees of Indiana University.
0003 //
0004 // Use, modification and distribution is subject to the Boost Software
0005 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 //  Authors: Douglas Gregor
0009 //           Andrew Lumsdaine
0010 //           Tiago de Paula Peixoto
0011 
0012 #ifndef BOOST_GRAPH_GRAPHML_HPP
0013 #define BOOST_GRAPH_GRAPHML_HPP
0014 
0015 #include <boost/config.hpp>
0016 #include <boost/lexical_cast.hpp>
0017 #include <boost/any.hpp>
0018 #include <boost/type_traits/is_convertible.hpp>
0019 #include <boost/graph/dll_import_export.hpp>
0020 #include <boost/graph/graphviz.hpp> // for exceptions
0021 #include <boost/mpl/bool.hpp>
0022 #include <boost/mpl/vector.hpp>
0023 #include <boost/mpl/find.hpp>
0024 #include <boost/mpl/for_each.hpp>
0025 #include <boost/property_tree/detail/xml_parser_utils.hpp>
0026 #include <boost/throw_exception.hpp>
0027 #include <exception>
0028 #include <sstream>
0029 #include <typeinfo>
0030 
0031 namespace boost
0032 {
0033 
0034 /////////////////////////////////////////////////////////////////////////////
0035 // Graph reader exceptions
0036 /////////////////////////////////////////////////////////////////////////////
0037 struct BOOST_SYMBOL_VISIBLE parse_error : public graph_exception
0038 {
0039     parse_error(const std::string& err)
0040     {
0041         error = err;
0042         statement = "parse error: " + error;
0043     }
0044     ~parse_error() throw() BOOST_OVERRIDE {}
0045     const char* what() const throw() BOOST_OVERRIDE { return statement.c_str(); }
0046     std::string statement;
0047     std::string error;
0048 };
0049 
0050 class mutate_graph
0051 {
0052 public:
0053     virtual ~mutate_graph() {}
0054     virtual bool is_directed() const = 0;
0055 
0056     virtual boost::any do_add_vertex() = 0;
0057     virtual std::pair< boost::any, bool > do_add_edge(
0058         boost::any source, boost::any target)
0059         = 0;
0060 
0061     virtual void set_graph_property(const std::string& name,
0062         const std::string& value, const std::string& value_type)
0063         = 0;
0064 
0065     virtual void set_vertex_property(const std::string& name, boost::any vertex,
0066         const std::string& value, const std::string& value_type)
0067         = 0;
0068 
0069     virtual void set_edge_property(const std::string& name, boost::any edge,
0070         const std::string& value, const std::string& value_type)
0071         = 0;
0072 };
0073 
0074 template < typename MutableGraph > class mutate_graph_impl : public mutate_graph
0075 {
0076     typedef typename graph_traits< MutableGraph >::vertex_descriptor
0077         vertex_descriptor;
0078     typedef
0079         typename graph_traits< MutableGraph >::edge_descriptor edge_descriptor;
0080 
0081 public:
0082     mutate_graph_impl(MutableGraph& g, dynamic_properties& dp)
0083     : m_g(g), m_dp(dp)
0084     {
0085     }
0086 
0087     bool is_directed() const BOOST_OVERRIDE
0088     {
0089         return is_convertible<
0090             typename graph_traits< MutableGraph >::directed_category,
0091             directed_tag >::value;
0092     }
0093 
0094     any do_add_vertex() BOOST_OVERRIDE { return any(add_vertex(m_g)); }
0095 
0096     std::pair< any, bool > do_add_edge(any source, any target) BOOST_OVERRIDE
0097     {
0098         std::pair< edge_descriptor, bool > retval
0099             = add_edge(any_cast< vertex_descriptor >(source),
0100                 any_cast< vertex_descriptor >(target), m_g);
0101         return std::make_pair(any(retval.first), retval.second);
0102     }
0103 
0104     void set_graph_property(const std::string& name,
0105         const std::string& value, const std::string& value_type) BOOST_OVERRIDE
0106     {
0107         bool type_found = false;
0108         try
0109         {
0110             mpl::for_each< value_types >(
0111                 put_property< MutableGraph*, value_types >(name, m_dp, &m_g,
0112                     value, value_type, m_type_names, type_found));
0113         }
0114         catch (const bad_lexical_cast&)
0115         {
0116             BOOST_THROW_EXCEPTION(parse_error("invalid value \"" + value
0117                 + "\" for key " + name + " of type " + value_type));
0118         }
0119         if (!type_found)
0120         {
0121             BOOST_THROW_EXCEPTION(parse_error(
0122                 "unrecognized type \"" + value_type + "\" for key " + name));
0123         }
0124     }
0125 
0126     void set_vertex_property(const std::string& name, any vertex,
0127         const std::string& value, const std::string& value_type) BOOST_OVERRIDE
0128     {
0129         bool type_found = false;
0130         try
0131         {
0132             mpl::for_each< value_types >(
0133                 put_property< vertex_descriptor, value_types >(name, m_dp,
0134                     any_cast< vertex_descriptor >(vertex), value, value_type,
0135                     m_type_names, type_found));
0136         }
0137         catch (const bad_lexical_cast&)
0138         {
0139             BOOST_THROW_EXCEPTION(parse_error("invalid value \"" + value
0140                 + "\" for key " + name + " of type " + value_type));
0141         }
0142         if (!type_found)
0143         {
0144             BOOST_THROW_EXCEPTION(parse_error(
0145                 "unrecognized type \"" + value_type + "\" for key " + name));
0146         }
0147     }
0148 
0149     void set_edge_property(const std::string& name, any edge,
0150         const std::string& value, const std::string& value_type) BOOST_OVERRIDE
0151     {
0152         bool type_found = false;
0153         try
0154         {
0155             mpl::for_each< value_types >(
0156                 put_property< edge_descriptor, value_types >(name, m_dp,
0157                     any_cast< edge_descriptor >(edge), value, value_type,
0158                     m_type_names, type_found));
0159         }
0160         catch (const bad_lexical_cast&)
0161         {
0162             BOOST_THROW_EXCEPTION(parse_error("invalid value \"" + value
0163                 + "\" for key " + name + " of type " + value_type));
0164         }
0165         if (!type_found)
0166         {
0167             BOOST_THROW_EXCEPTION(parse_error(
0168                 "unrecognized type \"" + value_type + "\" for key " + name));
0169         }
0170     }
0171 
0172     template < typename Key, typename ValueVector > class put_property
0173     {
0174     public:
0175         put_property(const std::string& name, dynamic_properties& dp,
0176             const Key& key, const std::string& value,
0177             const std::string& value_type, const char** type_names,
0178             bool& type_found)
0179         : m_name(name)
0180         , m_dp(dp)
0181         , m_key(key)
0182         , m_value(value)
0183         , m_value_type(value_type)
0184         , m_type_names(type_names)
0185         , m_type_found(type_found)
0186         {
0187         }
0188         template < class Value > void operator()(Value)
0189         {
0190             if (m_value_type
0191                 == m_type_names[mpl::find< ValueVector,
0192                     Value >::type::pos::value])
0193             {
0194                 put(m_name, m_dp, m_key, lexical_cast< Value >(m_value));
0195                 m_type_found = true;
0196             }
0197         }
0198 
0199     private:
0200         const std::string& m_name;
0201         dynamic_properties& m_dp;
0202         const Key& m_key;
0203         const std::string& m_value;
0204         const std::string& m_value_type;
0205         const char** m_type_names;
0206         bool& m_type_found;
0207     };
0208 
0209 protected:
0210     MutableGraph& m_g;
0211     dynamic_properties& m_dp;
0212     typedef mpl::vector< bool, int, long, float, double, std::string >
0213         value_types;
0214     static const char* m_type_names[];
0215 };
0216 
0217 template < typename MutableGraph >
0218 const char* mutate_graph_impl< MutableGraph >::m_type_names[]
0219     = { "boolean", "int", "long", "float", "double", "string" };
0220 
0221 void BOOST_GRAPH_DECL read_graphml(
0222     std::istream& in, mutate_graph& g, size_t desired_idx);
0223 
0224 template < typename MutableGraph >
0225 void read_graphml(std::istream& in, MutableGraph& g, dynamic_properties& dp,
0226     size_t desired_idx = 0)
0227 {
0228     mutate_graph_impl< MutableGraph > mg(g, dp);
0229     read_graphml(in, mg, desired_idx);
0230 }
0231 
0232 template < typename Types > class get_type_name
0233 {
0234 public:
0235     get_type_name(const std::type_info& type, const char** type_names,
0236         std::string& type_name)
0237     : m_type(type), m_type_names(type_names), m_type_name(type_name)
0238     {
0239     }
0240     template < typename Type > void operator()(Type)
0241     {
0242         if (typeid(Type) == m_type)
0243             m_type_name
0244                 = m_type_names[mpl::find< Types, Type >::type::pos::value];
0245     }
0246 
0247 private:
0248     const std::type_info& m_type;
0249     const char** m_type_names;
0250     std::string& m_type_name;
0251 };
0252 
0253 template < typename Graph, typename VertexIndexMap >
0254 void write_graphml(std::ostream& out, const Graph& g,
0255     VertexIndexMap vertex_index, const dynamic_properties& dp,
0256     bool ordered_vertices = false)
0257 {
0258     typedef typename graph_traits< Graph >::directed_category directed_category;
0259     typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor;
0260     typedef typename graph_traits< Graph >::vertex_descriptor vertex_descriptor;
0261 
0262     using boost::property_tree::xml_parser::encode_char_entities;
0263 
0264     BOOST_STATIC_CONSTANT(bool,
0265         graph_is_directed
0266         = (is_convertible< directed_category*, directed_tag* >::value));
0267 
0268     out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
0269         << "<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" "
0270            "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
0271            "xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns "
0272            "http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">\n";
0273 
0274     typedef mpl::vector< bool, short, unsigned short, int, unsigned int, long,
0275         unsigned long, long long, unsigned long long, float, double,
0276         long double, std::string >
0277         value_types;
0278     const char* type_names[] = { "boolean", "int", "int", "int", "int", "long",
0279         "long", "long", "long", "float", "double", "double", "string" };
0280     std::map< std::string, std::string > graph_key_ids;
0281     std::map< std::string, std::string > vertex_key_ids;
0282     std::map< std::string, std::string > edge_key_ids;
0283     int key_count = 0;
0284 
0285     // Output keys
0286     for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
0287     {
0288         std::string key_id = "key" + lexical_cast< std::string >(key_count++);
0289         if (i->second->key() == typeid(Graph*))
0290             graph_key_ids[i->first] = key_id;
0291         else if (i->second->key() == typeid(vertex_descriptor))
0292             vertex_key_ids[i->first] = key_id;
0293         else if (i->second->key() == typeid(edge_descriptor))
0294             edge_key_ids[i->first] = key_id;
0295         else
0296             continue;
0297         std::string type_name = "string";
0298         mpl::for_each< value_types >(get_type_name< value_types >(
0299             i->second->value(), type_names, type_name));
0300         out << "  <key id=\"" << encode_char_entities(key_id) << "\" for=\""
0301             << (i->second->key() == typeid(Graph*)
0302                        ? "graph"
0303                        : (i->second->key() == typeid(vertex_descriptor)
0304                                ? "node"
0305                                : "edge"))
0306             << "\""
0307             << " attr.name=\"" << i->first << "\""
0308             << " attr.type=\"" << type_name << "\""
0309             << " />\n";
0310     }
0311 
0312     out << "  <graph id=\"G\" edgedefault=\""
0313         << (graph_is_directed ? "directed" : "undirected") << "\""
0314         << " parse.nodeids=\"" << (ordered_vertices ? "canonical" : "free")
0315         << "\""
0316         << " parse.edgeids=\"canonical\" parse.order=\"nodesfirst\">\n";
0317 
0318     // Output graph data
0319     for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
0320     {
0321         if (i->second->key() == typeid(Graph*))
0322         {
0323             // The const_cast here is just to get typeid correct for property
0324             // map key; the graph should not be mutated using it.
0325             out << "   <data key=\"" << graph_key_ids[i->first] << "\">"
0326                 << encode_char_entities(
0327                        i->second->get_string(const_cast< Graph* >(&g)))
0328                 << "</data>\n";
0329         }
0330     }
0331 
0332     typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator;
0333     vertex_iterator v, v_end;
0334     for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v)
0335     {
0336         out << "    <node id=\"n" << get(vertex_index, *v) << "\">\n";
0337         // Output data
0338         for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end();
0339              ++i)
0340         {
0341             if (i->second->key() == typeid(vertex_descriptor))
0342             {
0343                 out << "      <data key=\"" << vertex_key_ids[i->first] << "\">"
0344                     << encode_char_entities(i->second->get_string(*v))
0345                     << "</data>\n";
0346             }
0347         }
0348         out << "    </node>\n";
0349     }
0350 
0351     typedef typename graph_traits< Graph >::edge_iterator edge_iterator;
0352     edge_iterator e, e_end;
0353     typename graph_traits< Graph >::edges_size_type edge_count = 0;
0354     for (boost::tie(e, e_end) = edges(g); e != e_end; ++e)
0355     {
0356         out << "    <edge id=\"e" << edge_count++ << "\" source=\"n"
0357             << get(vertex_index, source(*e, g)) << "\" target=\"n"
0358             << get(vertex_index, target(*e, g)) << "\">\n";
0359 
0360         // Output data
0361         for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end();
0362              ++i)
0363         {
0364             if (i->second->key() == typeid(edge_descriptor))
0365             {
0366                 out << "      <data key=\"" << edge_key_ids[i->first] << "\">"
0367                     << encode_char_entities(i->second->get_string(*e))
0368                     << "</data>\n";
0369             }
0370         }
0371         out << "    </edge>\n";
0372     }
0373 
0374     out << "  </graph>\n"
0375         << "</graphml>\n";
0376 }
0377 
0378 template < typename Graph >
0379 void write_graphml(std::ostream& out, const Graph& g,
0380     const dynamic_properties& dp, bool ordered_vertices = false)
0381 {
0382     write_graphml(out, g, get(vertex_index, g), dp, ordered_vertices);
0383 }
0384 
0385 } // boost namespace
0386 
0387 #endif // BOOST_GRAPH_GRAPHML_HPP