
On Nov 23, 2004, at 2:26 PM, David Abrahams wrote:
1) We need a params.has(k) member, that returns mpl::true_ when the parameter is there and mpl::false_ when the parameter is not there. That lets us dispatch either statically or dynamically based on the existence of an argument for keyword k.
Seems like that interface makes static dispatch unneccessarily hard. How about a metafunction:
has_param<Params, k>
such that
has_param<Params, k>
is derived from either mpl::true_ or mpl::false_ and
has_param<Params, k>::type
is one of mpl::true_ or mpl::false_.
Yes, that's better.
2) The macro BOOST_NAMED_PARAMS_FUN is okay when all parameters may be named parameters. In my use cases, there are always several positional-only parameters for which I do *not* want the option to rename them, and may want to be more picky about how they are passed to the function. For instance, I want to be able to take a "Graph& g" as the first parameter. One way to address this would be another variant of this macro, which I'll lamely call BOOST_NAMED_PARAMS_FUN_EXT, that might work like this:
BOOST_NAMED_PARAMS_FUN_EXT(void, page_rank, 0, 3, detail::page_rank_keywords, (2, (typename Graph, typename RankMap)), (2, ((Graph&, g), (RankMap rank))))
The first new argument is a preprocessor array giving the extra template parameters that should be introduced into the function. The second new argument is also a preprocessor array, this one containing the parameter types and names (each as tuples). I believe there is enough information here to generate, e.g.,
template<typename Graph, typename RankMap> void page_rank(Graph& g, RankMap rank) { return page_rank_with_named_params(g, rank, detail::page_rank_keywords()()); }
template<typename Graph, typename RankMap, typename T0> void page_rank(Graph& g, RankMap rank, const T0& a0) { return page_rank_with_named_params(g, rank, detail::page_rank_keywords()(a0)); }
etc...
Probably something like that could work. But my intuition tells me this is a good candidate for vertical repetition:
#ifndef BOOST_PP_IS_ITERATING
...
# define BOOST_NAMED_PARAMS_SETUP(whatever.hpp, 2, 5) # include BOOST_NAMED_PARAMS_GENERATE #else
template <class Graph, class RankMap BOOST_NAMED_PARAMS_TYPES> void page_rank(Graph& g, RankMap rank BOOST_NAMED_PARAMS_ARGS) { return page_rank_with_named_params( g, rank, BOOST_NAMED_PARAMS_KEYWORDS); }
#endif
Otherwise it's just too ugly and unreadable, not to mention what happens when types contain commas.
I'm thinking both are a bit too ugly... the Graph library might just be weird in this regard (having a single non-named parameter at the beginning of every function). Maybe I'll think of something else.
3) Partly due to the missing "params.has(p)", we're lacking the ability to determine the type of an expression like "params[index_map | get(vertex_index, g)]" without passing it to another function. I'd gladly give up some clarity in the handling of default parameters if I could get at this information. I'd even go for an auto-like macro:
BOOST_NAMED_PARAMS_AUTO(index, index_map, get(vertex_index, g));
Yikes; that one is hard without some kind of typeof support.
How about:
BOOST_NAMED_PARAMS_AUTO(index, index_map, some-type-expression);
??
Well, we'd need to have that get(vertex_index, g) in there somewhere for the auto to expand properly. Just having something like typename param_type<Params, index_map_t, default-type>::type would suffice for most uses.
You already have some way to look up the type of
get(vertex_index, g)
right?
Yes.
2) Keywords are stated to be of type "boost::keyword<keyword type>". Can we derive from the appropriate boost::keyword<...> instead? This is important to the BGL for backward compatibility reasons.
I honestly don't know. If we can, we should enable it.
Well, it seems to work on Apple GCC 3.3 :) Doug