[parameters] Runtime enumeration of parameter list
From a post about using strings as an indexing mechanism:
"David Abrahams"
Since all are known at compile time I'm sure it must be easy to do this. I'm pretty sure when someone shows me the obvious solution I will be very embarrassed, but until then I can do this with a std::map at runtime, but not at compile time. I'm pretty sure the parameter library is a good -- if not perfect -- match for your problem. Since I've pointed at it twice now, if you're not embarrassed yet, I'll stop pushing ;-)
I too am quite interested in this process of compile time indexing. Let me think out loud (visibly?). Question at the bottom. I have often used this pattern of access for a vector of a known size (contrived example): enum TabIndices { PERSON_TAB, ADDRESS_TAB, EMPLOYER_TAB, TAB_COUNT }; Window windows[TAB_COUNT]; ... display_window( TabIndices tab_index ) { windows[tab_index].display(); for( int i = 0; i < (int)TAB_COUNT; ++i ) { if( i != (int)tab_index ) windows[i].hide(); } } ... display_window( PERSON_TAB ); Let me have go at converting this to use the parameter keyword system for indexing by using an ArgumentPack. BOOST_PARAMETER_KEYWORD(tag, PERSON_WINDOW) BOOST_PARAMETER_KEYWORD(tag, ADDRESS_WINDOW) BOOST_PARAMETER_KEYWORD(tag, EMPLOYER_WINDOW)XXXX windows( ( PERSON_WINDOW = Window(), ADDRESS_WINDOW = Window(), EMPLOYER_WINDOW = Window() ) ); ... template<class keyword> display_window( keyword tab_index) { windows[tab_index].display(); for( YYYY ) { if( *iterator != tab_index ) windows[iterator].hide(); } } ... display_window( PERSON_TAB ); My two immediate problems are how to declare the type of the ArgumentPack that would actually hold the window objects. (XXXX) And secondly, how to iterate over the windows at runtime. (YYYY). I guess the main thrust of the question is "Does the parameters library support runtime enumeration?" or should I be looking at MPL? Neil
"Neil Hunt"
I guess the main thrust of the question is "Does the parameters library support runtime enumeration?"
Not directly, but it seems like something we (sh/c)ould support, probably by making ArgumentPacks conforming Fusion sequences so you could use boost/spirit/fusion/algorithm/for_each.hpp to enumerate them. The problem is that I don't have expertise with Fusion-1 and AFAIK it's not fully documented. Specifically, I don't know how to make a conforming Fusion sequence. Maybe Joel can help. Joel?
or should I be looking at MPL?
Wouldn't help you, at least not directly. Well, here's one thing you could do (ALL_CAPS should be reserved for macros, so I'm going with lower_case): // untested BOOST_PARAMETER_KEYWORD(tag, person_window) BOOST_PARAMETER_KEYWORD(tag, address_window) BOOST_PARAMETER_KEYWORD(tag, employer_window) typedef mpl::vector< tag::person_window, tag::address_window, tag::employer_window
all_windows;
template
David Abrahams wrote:
"Neil Hunt"
writes: I guess the main thrust of the question is "Does the parameters library support runtime enumeration?"
Not directly, but it seems like something we (sh/c)ould support, probably by making ArgumentPacks conforming Fusion sequences so you could use boost/spirit/fusion/algorithm/for_each.hpp to enumerate them. The problem is that I don't have expertise with Fusion-1 and AFAIK it's not fully documented. Specifically, I don't know how to make a conforming Fusion sequence. Maybe Joel can help. Joel?
Sure. I'll look into it. Should be a good example for the docs in the making. I'm a bit hesitant to write this for Fusion-1, however, as it will be replaced by Fusion-2 --which, BTW, has a "map" that might be a good replacement for boost parameter's internals. If boost.parameter uses fusion::map, then you automatically have iteration support plus all the algorithms etc. I bet fusion::map will simplify boost.parameter significantly too. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
Joel de Guzman
David Abrahams wrote:
"Neil Hunt"
writes: I guess the main thrust of the question is "Does the parameters library support runtime enumeration?"
Not directly, but it seems like something we (sh/c)ould support, probably by making ArgumentPacks conforming Fusion sequences so you could use boost/spirit/fusion/algorithm/for_each.hpp to enumerate them. The problem is that I don't have expertise with Fusion-1 and AFAIK it's not fully documented. Specifically, I don't know how to make a conforming Fusion sequence. Maybe Joel can help. Joel?
Sure. I'll look into it. Should be a good example for the docs in the making. I'm a bit hesitant to write this for Fusion-1, however, as it will be replaced by Fusion-2
I know; I was just thinking that Neil is probably not going to want to check out a branch.
--which, BTW, has a "map" that might be a good replacement for boost parameter's internals.
Might be. Boost.Parameter's internals have a bunch of stuff in them that isn't simply a map. And furthermore, that library works on broken compilers :(
If boost.parameter uses fusion::map, then you automatically have iteration support plus all the algorithms etc. I bet fusion::map will simplify boost.parameter significantly too.
Unless you make it "portable." The main motivation for making Boost.Parameter "portable" was that I wanted to use it in Boost.Python. But then again, maybe it will be possible to drop vc6/7 support from Boost.Python soon enough. -- Dave Abrahams Boost Consulting www.boost-consulting.com
Thanks David (and Joel),
Appreciate the time. That's helped me along the path.
As an aside, I think the docs in
http://www.boost.org/libs/parameter/doc/html/#applying-sfinae-to-the-overloa...
reference a superceded example.
I think "when the name argument is not convertible to const char*." should
be "when the root_vertex argument is not convertible to int." as per the
section above it.
Thanks again,
Neil
"David Abrahams"
"Neil Hunt"
writes: I guess the main thrust of the question is "Does the parameters library support runtime enumeration?"
Not directly, but it seems like something we (sh/c)ould support, probably by making ArgumentPacks conforming Fusion sequences so you could use boost/spirit/fusion/algorithm/for_each.hpp to enumerate them. The problem is that I don't have expertise with Fusion-1 and AFAIK it's not fully documented. Specifically, I don't know how to make a conforming Fusion sequence. Maybe Joel can help. Joel?
or should I be looking at MPL?
Wouldn't help you, at least not directly. Well, here's one thing you could do (ALL_CAPS should be reserved for macros, so I'm going with lower_case):
// untested BOOST_PARAMETER_KEYWORD(tag, person_window) BOOST_PARAMETER_KEYWORD(tag, address_window) BOOST_PARAMETER_KEYWORD(tag, employer_window)
typedef mpl::vector< tag::person_window, tag::address_window, tag::employer_window
all_windows;
template
struct process_arg { process_arg(ArgumentPack args, F f) : args(args), f(f) {} template <class Keyword> void operator()(Keyword k) const { f(k, args[k]); }
private: ArgumentPack const& args; F const& f; };
template
for_each_arg(ArgumentPack const& args, F const& f) { mpl::for_each<Keywords>( process_arg (args,f) ); } Now you can for_each_arg(args, f) where f is some binary function you'd like to be applied to each argument. The first parameter is the keyword (just in case you need it) and the second one is the original argument passed.
This won't cope well with missing default arguments, so it seems to me making our ArgumentPacks conforming fusion sequences is really the way to go.
-- Dave Abrahams Boost Consulting www.boost-consulting.com
"Neil Hunt"
Thanks David (and Joel),
Appreciate the time. That's helped me along the path.
As an aside, I think the docs in http://www.boost.org/libs/parameter/doc/html/#applying-sfinae-to-the-overloa... reference a superceded example.
I think "when the name argument is not convertible to const char*." should be "when the root_vertex argument is not convertible to int." as per the section above it.
Good catch. Could you put a bug in the SourceForge bug tracker, please? Thanks, -- Dave Abrahams Boost Consulting www.boost-consulting.com
Hi, I'd like to ask how to create device and stream class using stream class from iostreams library so that read function in my device class can accept n bytes argument properly? I know that from my last discussion with Jonathan Turkanish i have to set stream's buffer first using stream constructor or open method say, in x bytes. Each times i call read function in my stream class to read n bytes, read function in my device class always accept argument in x bytes. I'd like to have flexible read method so that my device class can figure out how many bytes that my stream want read. Can anybody help me? Regards Hendra Hidayat __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
"Neil Hunt"
Thanks David (and Joel),
Appreciate the time. That's helped me along the path.
As an aside, I think the docs in http://www.boost.org/libs/parameter/doc/html/#applying-sfinae-to-the-overloa... reference a superceded example.
I think "when the name argument is not convertible to const char*." should be "when the root_vertex argument is not convertible to int." as per the section above it.
Thanks, fixing now. -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (4)
-
David Abrahams
-
Hendra Hidayat
-
Joel de Guzman
-
Neil Hunt