I want to include property maps in a binary tree class, so I can access the graph vertices and write this syntax in the spirit of the BGL:
using vertex_properties = std::string;
using tree_type = binary_tree<vertex_properties, boost::no_property>;
using vertex_descriptor = tree_type::vertex_descriptor;
tree_type tree;
vertex_descriptor a = add_vertex(tree, "a");
vertex_descriptor b = add_vertex(tree, "b");
assert(tree[a] == "a");
tree[a] = tree[b];
assert(tree[a] == "b");
I got the the add_vertex
function working but I struggle enabling the bracket operator syntax.
In the tree_type
class I defined as a member an instance of the VertexManager
class:
template<typename Graph, typename VertexProperty>
struct VertexManager
{
using vertex_descriptor = typename Graph::vertex_descriptor;
using vertex_hashmap_type = std::map<vertex_descriptor, VertexProperty>;
vertex_hashmap_type _vertex_property_hashmap;
boost::associative_property_map< vertex_hashmap_type > _vertex_property_map { _vertex_property_hashmap };
template<typename... Args>
vertex_descriptor add_vertex_to_manager(Graph &g, Args&&... args)
{
vertex_descriptor key = add_vertex(g);
VertexProperty value = { std::forward<Args>(args)...};
put(_vertex_property_map, key, value);
return key;
}
const VertexProperty& operator [](vertex_descriptor v) const
{
return get(_vertex_property_hashmap, v);
}
VertexProperty & operator [](vertex_descriptor v)
{
return get(_vertex_property_hashmap, v);
}
};
But it does not work, as the boost get
function is defined with a const interface as follow:
template <class T>
inline const T& get(const T* pa, std::ptrdiff_t k) { return pa[k]; }
Is there a way to get a reference to an in-place element in the map?
I ended up looking in the implementation of the associative_property_map
: it implements the required value_type& operator[const key_type& k]
. Although it's not very clear why this operator is marked as const
:
template <typename UniquePairAssociativeContainer>
class associative_property_map
: public boost::put_get_helper<
typename UniquePairAssociativeContainer::value_type::second_type&,
associative_property_map<UniquePairAssociativeContainer> >
{
typedef UniquePairAssociativeContainer C;
public:
typedef typename C::key_type key_type;
typedef typename C::value_type::second_type value_type;
typedef value_type& reference;
typedef lvalue_property_map_tag category;
associative_property_map() : m_c(0) { }
associative_property_map(C& c) : m_c(&c) { }
reference operator[](const key_type& k) const {
return (*m_c)[k];
}
private:
C* m_c;
};