IMP  2.2.1
The Integrative Modeling Platform
base/graph_macros.h
Go to the documentation of this file.
1 /**
2  * \file IMP/base/graph_macros.h
3  * \brief Various general useful macros for IMP.
4  *
5  * Copyright 2007-2014 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPBASE_GRAPH_MACROS_H
10 #define IMPBASE_GRAPH_MACROS_H
11 #include <IMP/base/base_config.h>
12 #include <boost/graph/adjacency_list.hpp>
13 #include "file.h"
14 #include "internal/graph_utility.h"
15 #include <boost/unordered_map.hpp>
16 #include <boost/version.hpp>
17 
18 #if defined(IMP_DOXYGEN)
19 //! Define a graph object in \imp
20 /** The docs for the graph should appear before the macro
21  invocation. Directionality should be one of
22  - \c bidirectional
23  - \c directed
24  - \c undirected
25 
26  ShowVertex should take the VertexData as a variable named `vertex` and write
27  to a stream `out`.
28  */
29 #define IMP_GRAPH(Name, directionality, VertexData, EdgeData, ShowVertex) \
30  /** See \ref graphs "Graphs in IMP" for more information.*/ \
31  typedef boost::graph Name; \
32  typedef Name::VertexNameMap Name##ConstVertexName; \
33  typedef Name::EdgeNameMap Name##ConstEdgeName; \
34  typedef boost::graph_traits<Name> Name##Traits; \
35  typedef Name::vertex_descriptor Name##Vertex; \
36  typedef Name::edge_descriptor Name##Edge; \
37  class Name##VertexIndex {}; \
38  inline void show_as_graphviz(const Name& name, base::TextOutput out); \
39  Name##VertexIndex get_vertex_index(const Name& g)
40 
41 #elif defined(SWIG)
42 #if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && \
43  BOOST_VERSION <= 104800
44 #define IMP_GRAPH(Name, directionality, VertexData, EdgeData, ShowVertex) \
45  class Name; \
46  inline void show_as_graphviz(const Name& name, base::TextOutput out); \
47  class Name##VertexIndex {}
48 
49 #else // GCC VERSION
50 #define IMP_GRAPH(Name, directionality, VertexData, EdgeData, ShowVertex) \
51  class Name; \
52  class Name##VertexIndex {}; \
53  inline void show_as_graphviz(const Name& name, base::TextOutput out); \
54  inline Name##VertexIndex get_vertex_index(const Name& g)
55 #endif // GCC VERSION
56 
57 #else // swig and doxygen
58 
59 // Some combinations of gcc/boost fail to compile Python wrappers for
60 // get_vertex_index ("no match for 'operator=' error); fall back to
61 // std::map in this case
62 #if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 7 && \
63  BOOST_VERSION == 104800
64 #define IMP_GRAPH_MAP_TYPE std::map
65 #else
66 #define IMP_GRAPH_MAP_TYPE boost::unordered_map
67 #endif
68 
69 #define IMP_GRAPH(Name, directionality, VertexData, EdgeData, ShowVertex) \
70  typedef boost::adjacency_list< \
71  boost::vecS, boost::vecS, boost::directionality##S, \
72  boost::property<boost::vertex_name_t, VertexData>, \
73  boost::property<boost::edge_name_t, EdgeData> > Name; \
74  typedef boost::property_map<Name, boost::vertex_name_t>::const_type \
75  Name##ConstVertexName; \
76  typedef boost::property_map<Name, boost::edge_name_t>::const_type \
77  Name##ConstEdgeName; \
78  typedef boost::graph_traits<Name> Name##Traits; \
79  typedef Name##Traits::vertex_descriptor Name##Vertex; \
80  typedef Name##Traits::edge_descriptor Name##Edge; \
81  typedef IMP_GRAPH_MAP_TYPE<VertexData, Name##Vertex> Name##VertexIndex; \
82  inline Name##VertexIndex get_vertex_index(const Name& g) { \
83  return IMP::base::internal::get_graph_vertex_index< \
84  Name, VertexData, Name##Vertex, Name##Traits>(g); \
85  } \
86  struct Show##Name##Vertex { \
87  void operator()(VertexData vertex, base::TextOutput out) const { \
88  ShowVertex; \
89  } \
90  }; \
91  inline void show_as_graphviz(const Name& graph, base::TextOutput out) { \
92  IMP::base::internal::show_as_graphviz(graph, Show##Name##Vertex(), out); \
93  } \
94  typedef boost::property_map<Name, boost::edge_name_t>::type Name##EdgeName; \
95  typedef boost::property_map<Name, boost::vertex_name_t>::type Name##VertexName
96 #endif // swig and doxygen
97 
98 #if defined(IMP_DOXYGEN) || defined(SWIG)
99 //! Define a graph object in \imp
100 /** See IMP_GRAPH() for more info. Edges have a floating point weight.
101  */
102 #define IMP_WEIGHTED_GRAPH(Name, directionality, VertexData, ShowVertex) \
103  /** See \ref graphs "Graphs" for more information.*/ \
104  IMP_GRAPH(Name, directionality, VertexData, double, ShowVertex)
105 
106 #elif defined(SWIG)
107 #define IMP_WEIGHTED_GRAPH(Name, directionality, VertexData, ShowVertex) \
108  class Name
109 #else
110 #define IMP_WEIGHTED_GRAPH(Name, directionality, VertexData, ShowVertex) \
111  typedef boost::adjacency_list< \
112  boost::vecS, boost::vecS, boost::directionality##S, \
113  boost::property<boost::vertex_name_t, VertexData>, \
114  boost::property<boost::edge_weight_t, double> > Name; \
115  typedef boost::property_map<Name, boost::vertex_name_t>::const_type \
116  Name##ConstVertexName; \
117  typedef boost::property_map<Name, boost::edge_weight_t>::const_type \
118  Name##ConstEdgeWeight; \
119  typedef boost::graph_traits<Name> Name##Traits; \
120  typedef Name##Traits::vertex_descriptor Name##Vertex; \
121  typedef Name##Traits::edge_descriptor Name##Edge; \
122  typedef boost::unordered_map<VertexData, Name##Vertex> Name##VertexIndex; \
123  inline Name##VertexIndex get_vertex_index(const Name& g) { \
124  return IMP::base::internal::get_graph_vertex_index< \
125  Name, VertexData, Name##Vertex, Name##Traits>(g); \
126  } \
127  struct Show##Name##Vertex { \
128  void operator()(VertexData vertex, base::TextOutput out) const { \
129  ShowVertex; \
130  } \
131  }; \
132  inline void show_as_graphviz(const Name& graph, base::TextOutput out) { \
133  IMP::base::internal::show_as_graphviz(graph, Show##Name##Vertex(), out); \
134  } \
135  typedef boost::property_map<Name, boost::edge_weight_t>::type \
136  Name##EdgeWeight; \
137  typedef boost::property_map<Name, boost::vertex_name_t>::type Name##VertexName
138 #endif
139 
140 #endif /* IMPBASE_GRAPH_MACROS_H */
Handling of file input/output.