Named params library and BGL

I've just made an attempt to use the named parameters library (currently in review queue, and available at http://groups.yahoo.com/group/boost/files/named_params.zip) to simply properties in BGL. Currently, to initialize all properties one has to do: edge_descriptor e = add_edge(....); put(e, g, vertex_color, 10); put(e, g, vertex_name, "foo"); I hope that with the named parameters library it will be possible to do: add_edge(v1, v2, (vertex_color = 10, vertex_name = "foo"), g); I've tried to implement this idea, but run into the problems. First issue is documentation: it gives foo_impl(foo_keywords(a0)); as example, while the code uses: return f_impl(f_keywords()(t, name_)); Which has extra '()' after f_keywords. The second problem is that I need to create a type for 'keywords' (derived from 'keywords<...>' and use it for passing arguments). The docs suggest to create a number of forwarding functions, but given that a number of vertex properties can be rather large (and is actually unbounded), this does not seem good. So, now can do: vertex_property p = prop_keywords()(color = 10, name = "foo"); but I'd rather like: vertex_property p((color = 10, name = "foo")); So, the operator, will be overloaded to create something I can index with 'tag type' and get a value. In fact, this will allow to avoid declaring 'pop_keywords' -- since again, user can declare it's own keywords so it's not clear how to define that class. The example I've played with is at: http://zigzag.cs.msu.su:7813/p.cpp Comments are appreciated. - Volodya

I've just made an attempt to use the named parameters library (currently in review queue, and available at http://groups.yahoo.com/group/boost/files/named_params.zip) to simply properties in BGL.
Currently, to initialize all properties one has to do:
edge_descriptor e = add_edge(....); put(e, g, vertex_color, 10); put(e, g, vertex_name, "foo");
I hope that with the named parameters library it will be possible to do:
add_edge(v1, v2, (vertex_color = 10, vertex_name = "foo"), g);
FWIW, I could try and see if it will be possible to use the assign lib to write something like assign::add_egde( v1, v2, g )(vertex_color,10)(vertex_name, "foo" ); or maybe assign::inserter<X> edge_adder( g ); edge_adder( v1,v2 )(vertex_color,10)(vertex_name, "foo" ); edge_adder( v1,v3 )(vertex_color,10)(vertex_name, "bar" ); when I add the new functionality. br Thorsten

Thorsten Ottosen wrote:
Currently, to initialize all properties one has to do:
edge_descriptor e = add_edge(....); put(e, g, vertex_color, 10); put(e, g, vertex_name, "foo");
I hope that with the named parameters library it will be possible to do:
add_edge(v1, v2, (vertex_color = 10, vertex_name = "foo"), g);
FWIW, I could try and see if it will be possible to use the assign lib to write something like
assign::add_egde( v1, v2, g )(vertex_color,10)(vertex_name, "foo" );
It could be possible too. Though I have some preference to named params library. The reason is the notion of container which has types as indices but returns real values when subscribed. I've played with this idea in past, and I also see this approach used for filesystem attributes (in the sandbox). I'm pretty sure named params library implements such a container internally, and if it's exposed/documented it probably can even replace boost::property. Consider another thing that was around for a while: associative_list. That's map from type to type. Combined with map from type to value this can be use in BGL like this: template<...., class VertexProperty, ... > class graph { typedef type2value_map<VertexProperty> vertex_property; }; typedef graph<...., make_type_2_type_map(vertex_color_t, unsigned, vertex_name_t, std::string, vertex_weight_t, unsigned) ... > my_graph; I think this might simplify some of the BGL internals. And for another example, if named parameters produce documented class type2value_map, we can do this: depth_first_visit(.., (on_vertex_discover = cout << constant("found vertex") << _1, on_back_edge = ....)); And probably in some other places. If we use the same classes everywhere, the implementation will be simplified. - Volodya

Vladimir Prus <ghost@cs.msu.su> writes:
I've just made an attempt to use the named parameters library (currently in review queue, and available at http://groups.yahoo.com/group/boost/files/named_params.zip) to simply properties in BGL.
Currently, to initialize all properties one has to do:
edge_descriptor e = add_edge(....); put(e, g, vertex_color, 10); put(e, g, vertex_name, "foo");
I hope that with the named parameters library it will be possible to do:
add_edge(v1, v2, (vertex_color = 10, vertex_name = "foo"), g); ^--------------------------------------^
What are these for? That's not part of how the library works, at least today... oh, I see you're trying to deal with the "unbounded number of vertex properties" problem. Probably the library should be modified a bit to help with that sort of situation. We really envisioned that it could help the graph library by just making the interfaces to the algorithms, which have lots of default arguments, much easier.
I've tried to implement this idea, but run into the problems. First issue is documentation: it gives
foo_impl(foo_keywords(a0));
as example, while the code uses:
return f_impl(f_keywords()(t, name_));
Which has extra '()' after f_keywords.
Uh, yeah. I think I need to let Daniel answer for that problem.
The second problem is that I need to create a type for 'keywords' (derived from 'keywords<...>' and use it for passing arguments). The docs suggest to create a number of forwarding functions, but given that a number of vertex properties can be rather large (and is actually unbounded), this does not seem good.
So, now can do:
vertex_property p = prop_keywords()(color = 10, name = "foo");
but I'd rather like:
vertex_property p((color = 10, name = "foo"));
So, the operator, will be overloaded to create something I can index with 'tag type' and get a value. In fact, this will allow to avoid declaring 'pop_keywords' -- since again, user can declare it's own keywords so it's not clear how to define that class.
The example I've played with is at:
http://zigzag.cs.msu.su:7813/p.cpp
Comments are appreciated.
I think we can whip something together for you. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
I hope that with the named parameters library it will be possible to do:
add_edge(v1, v2, (vertex_color = 10, vertex_name = "foo"), g); ^--------------------------------------^
What are these for? That's not part of how the library works, at least today... oh, I see you're trying to deal with the "unbounded number of vertex properties" problem.
Right.
Probably the library should be modified a bit to help with that sort of situation. We really envisioned that it could help the graph library by just making the interfaces to the algorithms, which have lots of default arguments, much easier.
Well, I think BGL already supports default arguments in its named parameters. For me, the biggest advance of using this library for BGL (besides the above use case) would be the fact that the procedure for declaring/using named parameters is *documented*. With current BGL implementation, I'm still at loss.
Comments are appreciated.
I think we can whip something together for you.
That's great. - Volodya

Vladimir Prus <ghost@cs.msu.su> writes:
David Abrahams wrote:
I hope that with the named parameters library it will be possible to do:
add_edge(v1, v2, (vertex_color = 10, vertex_name = "foo"), g); ^--------------------------------------^
What are these for? That's not part of how the library works, at least today... oh, I see you're trying to deal with the "unbounded number of vertex properties" problem.
Right.
Probably the library should be modified a bit to help with that sort of situation. We really envisioned that it could help the graph library by just making the interfaces to the algorithms, which have lots of default arguments, much easier.
Well, I think BGL already supports default arguments in its named parameters.
Yeah but they're ugly to the user, and bad to maintain for the developer. Adding a new parameter name ties it to all the other parameter names because they have to be members of the same class template. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
Vladimir Prus <ghost@cs.msu.su> writes:
I've just made an attempt to use the named parameters library (currently in review queue, and available at http://groups.yahoo.com/group/boost/files/named_params.zip) to simply properties in BGL.
I've tried to implement this idea, but run into the problems. First issue is documentation: it gives
foo_impl(foo_keywords(a0));
as example, while the code uses:
return f_impl(f_keywords()(t, name_));
Which has extra '()' after f_keywords.
Uh, yeah. I think I need to let Daniel answer for that problem.
Yeah I'll take care of it.. Thanks.
The second problem is that I need to create a type for 'keywords' (derived from 'keywords<...>' and use it for passing arguments). The docs suggest to create a number of forwarding functions, but given that a number of vertex properties can be rather large (and is actually unbounded), this does not seem good.
Isn't the number of properties bounded by the graph type? Couldn't you create some metafunction to generate the keywords<> type from the graph and use Boost.PP to generate overloads on this form (please ignore all the BGL related errors here): template<class G, class A0, .., class AN> typename enable_if_graph< G , typename graph_traits<G>::edge_descriptor
::type add_edge( typename graph_traits<G>::vertex_descriptor u , typename graph_traits<G>::vertex_descriptor v , A0 const& a0 , ... , AN const& an , G& g) { typename keywords_for_graph<G>::type kw; return add_edge_impl(u, v, g, kw(a0, ..., an)); }
-- Daniel Wallin

Daniel Wallin wrote:
The second problem is that I need to create a type for 'keywords' (derived from 'keywords<...>' and use it for passing arguments). The docs suggest to create a number of forwarding functions, but given that a number of vertex properties can be rather large (and is actually unbounded), this does not seem good.
Isn't the number of properties bounded by the graph type? Couldn't you create some metafunction to generate the keywords<> type from the graph
Yes, I think it could be possible.
and use Boost.PP to generate overloads on this form (please ignore all the BGL related errors here):
template<class G, class A0, .., class AN> typename enable_if_graph< G , typename graph_traits<G>::edge_descriptor
::type add_edge( typename graph_traits<G>::vertex_descriptor u , typename graph_traits<G>::vertex_descriptor v , A0 const& a0 , ... , AN const& an , G& g) { typename keywords_for_graph<G>::type kw; return add_edge_impl(u, v, g, kw(a0, ..., an));
Should there be kw()(a0...) ? It seems the syntax that works for me.
}
I did not consider overloading 'add_edge'. In fact, it's still not so good idea. You'd also need to provide similiar overloads for at least 'add_vertex' and 'put' and maybe something else, which makes the implementation more complex. I though I can only provide new constructor for boost::proprty and have everything work. I wonder what's the reason to require conversion/construction of keywords<>? Couldn't (color = 10, name = "foo") already create a type with proper operator[])? - Volodya

Vladimir Prus wrote:
Daniel Wallin wrote:
template<class G, class A0, .., class AN> typename enable_if_graph< G , typename graph_traits<G>::edge_descriptor
::type add_edge( typename graph_traits<G>::vertex_descriptor u , typename graph_traits<G>::vertex_descriptor v , A0 const& a0 , ... , AN const& an , G& g) { typename keywords_for_graph<G>::type kw; ^^^^^^^^ ^^ return add_edge_impl(u, v, g, kw(a0, ..., an));
Should there be kw()(a0...) ? It seems the syntax that works for me.
No, kw isn't a type here. [snip]
I wonder what's the reason to require conversion/construction of keywords<>? Couldn't (color = 10, name = "foo") already create a type with proper operator[])?
Yes, it could. The point of keywords<> is to enable positional parameters as well as named (and also the SFINAE stuff). Anyway, I checked in some changes to the sandbox that enables list creation with operator,. Could you try that version out? -- Daniel Wallin

Hi Daniel,
[snip]
I wonder what's the reason to require conversion/construction of keywords<>? Couldn't (color = 10, name = "foo") already create a type with proper operator[])?
Yes, it could. The point of keywords<> is to enable positional parameters as well as named (and also the SFINAE stuff).
I see.
Anyway, I checked in some changes to the sandbox that enables list creation with operator,. Could you try that version out?
I've just tried it. For my tests, it works perfectly. Thanks! I'll try to take a closer look at implementation later -- I really hope some of it can be reusable in a winder context (see my reply to Thorsten). Thanks, Volodya
participants (4)
-
Daniel Wallin
-
David Abrahams
-
Thorsten Ottosen
-
Vladimir Prus