Consider:
typedef adjacency_list<
listS, //out edges stored as std::list
listS, //verteices stored as std::list
directedS,
property<vertex_name_t, std::string>,
property<edge_weight_t, double>
> user_graph;
Storage of edges and vertices as std::list
precludes random access via [index]
.
Consider further that property maps are defined so.
typedef property_map<user_graph, vertex_name_t>::type name_map_t;
typedef property_map<user_graph, edge_weight_t>::type weight_map_t;
user_graph g;
name_map_t name_map = get(vertex_name, g);
weight_map_t weight_map = get(edge_weight, g);
Even though random access of actual edges/vertices is not possible via [index]
, is it guaranteed that access to the name of a vertex and weight of an edge are efficient and fast under random access like so:
graph_traits<user_graph>::vertex_iterator vi, vi_end;
for(tie(vi, vi_end)=vertices(g); vi != vi_end; ++vi)
cout<<"Name of vertex is "<<name_map[*vi];//Question is, is this efficient given storage of vertices as std::list
Part of my confusion comes from general std::map
characteristic that it too does not support random access (See here)
Is it the case that whether vertices are stored as std::vector
or std::list
or std::set
, regardless, access to its property maps via vertex descriptors using some_map[vertex_descriptor]
or some_map[*vertex_iterator]
is always guaranteed to be efficient (constant time)?
Yes. The properties are actually stored inline with the vertex/edge node. A descriptor is effectively a type erased pointer to that node.
name_map[*vi]
ends up inlining to something likeget<N>(*static_cast<storage_node*>(vi))
if you imagine the property storage as a kind of tuple with aget<>
accessor¹.Property maps are not like std::map; They may be consecutive, they may be node-based, ordered, unordered, or even calculated. In fact Boost Property Map maybe closer to the concept of a Lense in some functional programming languages. It is a set of functions that can be used to model (mutable) projections for a given key type.
See also:
Curiosity Wins... Code Gen
Let's see what code gets generated:
Live On Compiler Explorer
Prints
But more interestingly, the codegen:
You see, no algorithmic overhead, just dereferences.
¹ In reality, the properties are stored in a kind of Lisp-like list type that end up behaving similarly to a tuple. Boost Graph predates tuples by considerable time margin. I suppose if you want one can compare it closely to Boost Fusion's
map
type (which also has a type key).