[program_options] Configuration file syntax (or how to fill a vector from the configuration file)
Hi, is there a general description of the config file syntax that program_options uses available? Like if it's case-sensitive, if you can quote arguments, etc ... currently i'm wondering if I can fill a vector from one line, like val = foo bar baz with foo, bar, and baz as the values ... is this possible with some separator? Regards, Stefan
Stefan, it depends on how far you are ready to go ;) What you request is possible, but that will not work (AFAIK) from the scratch. What you need is custom handling of the options parsed. namespace po = boost::program_options; template<class CharT> void handle_parsed_option(po::basic_option<CharT> const& parsed_option) { //parse it } //program options are used to properly parse values // so all options parsed are valid po::options_description options("Option Parser"); options.add_options() ("*", po::value<int>(), "dummy placeholder") ; po::parsed_options const& opts = po::parse_config_file(input, options); ::std::for_each(opts.options.begin(), opts.options.end(), &handle_parsed_option<char>); Hope that helps. Best Regards, Ovanes On Fri, Apr 18, 2008 at 10:53 AM, Stefan Walk <walk@mis.tu-darmstadt.de> wrote:
Hi,
is there a general description of the config file syntax that program_options uses available? Like if it's case-sensitive, if you can quote arguments, etc ... currently i'm wondering if I can fill a vector from one line, like val = foo bar baz with foo, bar, and baz as the values ... is this possible with some separator?
Regards, Stefan
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hi all I'm wondering if there is such stuff in boost, or anything similar: double d0, d1, d2, d3; boost::array<double &, 4> array = {{d0, d1, d2, d3}}; for(int i=0; i<4; i++) array[i] = i; assert(d2 == 2); or double d0, d1, d2, d3; boost::array<double, 4> array; boost::bind(array[0], d0); boost::bind(array[1], d1); boost::bind(array[2], d2); boost::bind(array[3], d3); for(int i=0; i<4; i++) array[i] = i; assert(d2 == 2); Thanks Max
Max wrote:
Hi all
I'm wondering if there is such stuff in boost, or anything similar:
double d0, d1, d2, d3; boost::array<double &, 4> array = {{d0, d1, d2, d3}}; for(int i=0; i<4; i++) array[i] = i; assert(d2 == 2);
or
double d0, d1, d2, d3; boost::array<double, 4> array; boost::bind(array[0], d0); boost::bind(array[1], d1); boost::bind(array[2], d2); boost::bind(array[3], d3); for(int i=0; i<4; i++) array[i] = i; assert(d2 == 2);
Sounds like you need the reference wrappers http://www.boost.org/doc/libs/1_35_0/doc/html/ref.html which are designed for passing references to function objects where passing a value would be inappropriate or inefficient, as they are CopyConstructible and Assignable they are also suitable for storage in containers where simple pointers are inappropriate.
Thanks Max
------------------------------------------------------------------------
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Bill Somerville Class Design Limited
Max wrote:
Hi all
I'm wondering if there is such stuff in boost, or anything similar:
double d0, d1, d2, d3; boost::array<double &, 4> array = {{d0, d1, d2, d3}}; for(int i=0; i<4; i++) array[i] = i; assert(d2 == 2);
or
double d0, d1, d2, d3; boost::array<double, 4> array; boost::bind(array[0], d0); boost::bind(array[1], d1); boost::bind(array[2], d2); boost::bind(array[3], d3); for(int i=0; i<4; i++) array[i] = i; assert(d2 == 2);
Sounds like you need the reference wrappers http://www.boost.org/doc/libs/1_35_0/doc/html/ref.html which are designed for passing references to function objects where passing a value would be inappropriate or inefficient, as they are CopyConstructible and Assignable they are also suitable for storage in containers where simple pointers are inappropriate.
Thanks Max
Thank you Somerville for your direction. I never used Ref before, and I'll have a look into its documentation. If it won't take a long time, is it possible to rewrite the above code snnipet making use of boost.Ref? Thanks again. Max
On Saturday 03 May 2008 09:12:01 pm Max wrote:
double d0, d1, d2, d3; boost::array<double &, 4> array = {{d0, d1, d2, d3}}; for(int i=0; i<4; i++) array[i] = i; assert(d2 == 2);
[snip]
If it won't take a long time, is it possible to rewrite the above code snnipet making use of boost.Ref?
#include <boost/array.hpp> #include <boost/ref.hpp> #include <cassert> int main() { typedef boost::reference_wrapper<double> double_ref_t; boost::array<double, 2> array; double_ref_t d0( array[0] ); double_ref_t d1( array[1] ); array[0] = 1.0; array[1] = 2.0; assert( d1 == 2.0 ); d0 += d1; assert( d0 == 3.0 ); }
Hi Max & Ravi Ravi wrote:
On Saturday 03 May 2008 09:12:01 pm Max wrote:
double d0, d1, d2, d3; boost::array<double &, 4> array = {{d0, d1, d2, d3}}; for(int i=0; i<4; i++) array[i] = i; assert(d2 == 2);
[snip]
If it won't take a long time, is it possible to rewrite the above code snnipet making use of boost.Ref?
#include <boost/array.hpp> #include <boost/ref.hpp>
#include <cassert>
int main() { typedef boost::reference_wrapper<double> double_ref_t; boost::array<double, 2> array;
double_ref_t d0( array[0] ); double_ref_t d1( array[1] );
array[0] = 1.0; array[1] = 2.0; assert( d1 == 2.0 );
d0 += d1; assert( d0 == 3.0 ); }
or even: #include <cassert> #include <boost/array.hpp> #include <boost/ref.hpp> int main() { double d0, d1, d2, d3; boost::array<boost::reference_wrapper<double>, 4> array = {boost::ref(d0), boost::ref(d1), boost::ref(d2), boost::ref(d3)}; for(int i=0; i<4; i++) { array[i].get() = i; } assert(d2 == 2); return 0; } although this is a slightly unusual construct which might suffer nasty aliasing issues, perhaps a few more details of your requirement might clarify a better approach. -- Bill Somerville Class Design Limited
Hi Max & Ravi
Ravi wrote:
On Saturday 03 May 2008 09:12:01 pm Max wrote:
double d0, d1, d2, d3; boost::array<double &, 4> array = {{d0, d1, d2, d3}}; for(int i=0; i<4; i++) array[i] = i; assert(d2 == 2);
[snip]
If it won't take a long time, is it possible to rewrite the above code snnipet making use of boost.Ref?
#include <boost/array.hpp> #include <boost/ref.hpp>
#include <cassert>
int main() { typedef boost::reference_wrapper<double> double_ref_t; boost::array<double, 2> array;
double_ref_t d0( array[0] ); double_ref_t d1( array[1] );
array[0] = 1.0; array[1] = 2.0; assert( d1 == 2.0 );
d0 += d1; assert( d0 == 3.0 ); }
or even:
#include <cassert> #include <boost/array.hpp> #include <boost/ref.hpp>
int main() { double d0, d1, d2, d3; boost::array<boost::reference_wrapper<double>, 4> array = {boost::ref(d0), boost::ref(d1), boost::ref(d2), boost::ref(d3)}; for(int i=0; i<4; i++) { array[i].get() = i; } assert(d2 == 2);
return 0; }
Thank you Somerville for your solution. This is exactly what I need!
although this is a slightly unusual construct which might suffer nasty aliasing issues, perhaps a few more details of your requirement might clarify a better approach.
Please decorate on the 'nasty aliasing issues'. For more details of my intention, please refer to my previous mail I just posted. I hope ther's a even more elgent way to get rid of the issues you mentioned. B/Rgds Max
-- Bill Somerville Class Design Limited
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Max wrote:
#include <cassert> #include <boost/array.hpp> #include <boost/ref.hpp>
int main() { double d0, d1, d2, d3; boost::array<boost::reference_wrapper<double>, 4> array = {boost::ref(d0), boost::ref(d1), boost::ref(d2), boost::ref(d3)}; for(int i=0; i<4; i++) { array[i].get() = i; } assert(d2 == 2);
return 0; }
Thank you Somerville for your solution. This is exactly what I need!
although this is a slightly unusual construct which might suffer nasty aliasing issues, perhaps a few more details of your requirement might clarify a better approach.
Please decorate on the 'nasty aliasing issues'. For more details of my intention, please refer to my previous mail I just posted. I hope ther's a even more elgent way to get rid of the issues you mentioned.
Given your requirement then this does seem a fairly good solution. I was just pointing out that you will have to ensure that the lifetime of the objects being bound to the reference wrappers are at least as long as the reference wrappers themselves. This is no different than references or pointers.
B/Rgds Max
-- Bill Somerville Class Design Limited
Is it possible to compare tokens in the preprocessors library? What I mean is that I can say #if (abc == abc) foo #else bar #endif and it gives me foo but if I say BOOST_PP_IF(abc == abc, foo, bar) I get an error. Is it possible to do something like this? If so, what am I doing wrong? Thank you, -EdK Ed Keith e_d_k@yahoo.com Blog: edkeith.blogspot.com ____________________________________________________________________________________ Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
Ed Keith wrote:
Is it possible to compare tokens in the preprocessors library?
What I mean is that I can say
#if (abc == abc) foo #else bar #endif
and it gives me foo
but if I say
BOOST_PP_IF(abc == abc, foo, bar)
I get an error.
I don't know the implementation of BOOST_PP_IF, but would this work any better? BOOST_PP_IF((abc == abc), foo, bar)
--- Nat Goodspeed <nat@lindenlab.com> wrote:
Ed Keith wrote:
Is it possible to compare tokens in the preprocessors library?
What I mean is that I can say
#if (abc == abc) foo #else bar #endif
and it gives me foo
but if I say
BOOST_PP_IF(abc == abc, foo, bar)
I get an error.
I don't know the implementation of BOOST_PP_IF, but would this work any better?
BOOST_PP_IF((abc == abc), foo, bar)
No, I tried that too. Thanks anyway, -EdK Ed Keith e_d_k@yahoo.com Blog: edkeith.blogspot.com ____________________________________________________________________________________ Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
Quoting Ed Keith <e_d_k@yahoo.com>:
[...]
BOOST_PP_IF(abc == abc, foo, bar)
I get an error.
Is it possible to do something like this? If so, what am I doing wrong?
I think you have to use BOOST_PP_IF( BOOST_PP_EQUAL(abc,abc) , foo, bar ) here. Pete
--- Peter Bartlett <pete@pcbartlett.com> wrote:
Quoting Ed Keith <e_d_k@yahoo.com>:
[...]
BOOST_PP_IF(abc == abc, foo, bar)
I get an error.
Is it possible to do something like this? If so, what am I doing wrong?
I think you have to use BOOST_PP_IF( BOOST_PP_EQUAL(abc,abc) , foo, bar ) here.
I tried that, but apparently BOOST_PP_EQUAL only takes int values. Thank for the suggestion though, -EdK Ed Keith e_d_k@yahoo.com Blog: edkeith.blogspot.com ____________________________________________________________________________________ Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
Quoting Ed Keith <e_d_k@yahoo.com>:
--- Peter Bartlett <pete@pcbartlett.com> wrote:
Quoting Ed Keith <e_d_k@yahoo.com>:
[...]
BOOST_PP_IF(abc == abc, foo, bar)
I get an error.
Is it possible to do something like this? If so, what am I doing wrong?
I think you have to use BOOST_PP_IF( BOOST_PP_EQUAL(abc,abc) , foo, bar ) here.
I tried that, but apparently BOOST_PP_EQUAL only takes int values.
Thank for the suggestion though,
-EdK
Ok. BOOST_PP_IF has a similar restriction, so you probably can't do what you want with it. Be sure though that even the '#if' version is doing what you want - for example the following program prints 1 on my compiler (VC9): #if foo == bar int baz() { return 1; } #else int baz() { return 0; } #endif #include <iostream> int main() { std::cout << "\n" << baz() << "\n"; }
--- Peter Bartlett <pete@pcbartlett.com> wrote:
Quoting Ed Keith <e_d_k@yahoo.com>:
--- Peter Bartlett <pete@pcbartlett.com> wrote:
Quoting Ed Keith <e_d_k@yahoo.com>:
[...]
BOOST_PP_IF(abc == abc, foo, bar)
I get an error.
Is it possible to do something like this? If
so,
what
am I doing wrong?
I think you have to use BOOST_PP_IF( BOOST_PP_EQUAL(abc,abc) , foo, bar ) here.
I tried that, but apparently BOOST_PP_EQUAL only takes int values.
Thank for the suggestion though,
-EdK
Ok. BOOST_PP_IF has a similar restriction, so you probably can't do what you want with it. Be sure though that even the '#if' version is doing what you want - for example the following program prints 1 on my compiler (VC9):
#if foo == bar int baz() { return 1; } #else int baz() { return 0; } #endif
#include <iostream> int main() { std::cout << "\n" << baz() << "\n"; }
Your right it's not doing what I want. Let me ask a hight level question. What I am trying to do is the following: I have two sequences. Both represent sets, one is a subset of the other. What I want to do is for each element in the superset, generate one value if it is in the subset, and another value if it is not in the subset. The problem is that the elements are not numeric (they are just tokens), so I can not seem to compare them to determine if they are the same. Any sugestions? Thank you, -EdK Ed Keith e_d_k@yahoo.com Blog: edkeith.blogspot.com ____________________________________________________________________________________ Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
Your right it's not doing what I want. Let me ask a hight level question.
What I am trying to do is the following:
I have two sequences. Both represent sets, one is a subset of the other. What I want to do is for each element in the superset, generate one value if it is in the subset, and another value if it is not in the subset. The problem is that the elements are not numeric (they are just tokens), so I can not seem to compare them to determine if they are the same.
Any sugestions?
What I woukld write is borrowed from the inner mechanics of Boost::PP. let's say you have two token FOO & BAR. #define IS_SAME_TOKEN_FOO_FOO 1 #define IS_SAME_TOKEN_FOO_BAR 0 #define IS_SAME_TOKEN_BAR_FOO 0 #define IS_SAME_TOKEN_BAR_BAR 0 #define IS_SAME_TOKEN(X,Y) BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_CAT(IS_SAME_TOKEN_,X),_),Y) then use IS_SAME_TOKEN in BOOST_PP_IF I knwo it gets cumbersome as the number of tokens increase but I can't see hwo to do it better.
--- Joel Falcou <joel.falcou@u-psud.fr> wrote:
I have two sequences. Both represent sets, one is
subset of the other. What I want to do is for each element in the superset, generate one value if it is in the subset, and another value if it is not in
a the
subset. The problem is that the elements are not numeric (they are just tokens), so I can not seem to compare them to determine if they are the same.
Any sugestions?
What I woukld write is borrowed from the inner mechanics of Boost::PP. let's say you have two token FOO & BAR.
#define IS_SAME_TOKEN_FOO_FOO 1 #define IS_SAME_TOKEN_FOO_BAR 0 #define IS_SAME_TOKEN_BAR_FOO 0 #define IS_SAME_TOKEN_BAR_BAR 0
#define IS_SAME_TOKEN(X,Y)
BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_CAT(IS_SAME_TOKEN_,X),_),Y)
then use IS_SAME_TOKEN in BOOST_PP_IF
I knwo it gets cumbersome as the number of tokens increase but I can't see hwo to do it better.
I have about a dozen tokens. Maybe I can automagicly generate the defines. . . I'll give it a try. Thanks, -EdK Ed Keith e_d_k@yahoo.com Blog: edkeith.blogspot.com ____________________________________________________________________________________ Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
--- Joel Falcou <joel.falcou@u-psud.fr> wrote:
I have two sequences. Both represent sets, one is a subset of the other. What I want to do is for each element in the superset, generate one value if it is in the subset, and another value if it is not in the subset. The problem is that the elements are not numeric (they are just tokens), so I can not seem to compare them to determine if they are the same.
Any sugestions?
What I woukld write is borrowed from the inner mechanics of Boost::PP. let's say you have two token FOO & BAR.
#define IS_SAME_TOKEN_FOO_FOO 1 #define IS_SAME_TOKEN_FOO_BAR 0 #define IS_SAME_TOKEN_BAR_FOO 0 #define IS_SAME_TOKEN_BAR_BAR 0
#define IS_SAME_TOKEN(X,Y)
BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_CAT(IS_SAME_TOKEN_,X),_),Y)
then use IS_SAME_TOKEN in BOOST_PP_IF
I knwo it gets cumbersome as the number of tokens increase but I can't see hwo to do it better.
I have not got it working yet, but I think I can avoid the combinatorial explosion. For each token 'foo', I define 'X_foo' and give it a uneque numeric value. Then I can use the following to compare them : #define MY_COMPARE(x,y) BOOST_PP_EQUAL(BOOST_PP_CAT(X_, x), BOOST_PP_CAT(X_,y)) Still not a elegant as I'd like, but no combinatorial explosion. Thanks a lot for putting me on the right track. -EdK Ed Keith e_d_k@yahoo.com Blog: edkeith.blogspot.com ____________________________________________________________________________________ Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
I have a sequence of numbers, some positive, some negative that I want to sum. And I just learned that BOOST_PP_ADD(x, y) does not work with negative numbers. Does anyone know of a work around? Thanks in advance, -EdK Ed Keith e_d_k@yahoo.com Blog: edkeith.blogspot.com ____________________________________________________________________________________ Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
Please decorate on the 'nasty aliasing issues'. For more details of my intention, please refer to my previous mail I just posted. I hope ther's a even more elgent way to get rid of the issues you mentioned.
Given your requirement then this does seem a fairly good solution. I was just pointing out that you will have to ensure that the lifetime of the objects being bound to the reference wrappers are at least as long as the reference wrappers themselves. This is no different than references or pointers.
Thank you for your furthur clarification. It's quite clear and elegant. The life-time problem should not be an extra burden raised by this solution. Thanks again for your help. And thanks to Ravi, too. B/Rgds Max
Bill Somerville Class Design Limited
#include <boost/array.hpp> #include <boost/ref.hpp>
#include <cassert>
int main() { typedef boost::reference_wrapper<double> double_ref_t; boost::array<double, 2> array;
double_ref_t d0( array[0] ); double_ref_t d1( array[1] );
array[0] = 1.0; array[1] = 2.0; assert( d1 == 2.0 );
d0 += d1; assert( d0 == 3.0 ); }
Thank you for your reply, I've also walked through the brief documentation of Ref (There's even not a simple example showing its usage and power!) The solution you provided is nearly what I need. My main intention is to get the ability to group/organize scattered/individual variables of a same type into a standard container (vector or so) to enable fast/elegant traversal in one run with one or two lines of code (with a call to for_each() or similar), without doing the same operation one by one with these individual variables. With your solution, I should declare my varaibles of type T, on which I will do some operation in the future, as boost::reference_wrapper<T>. Obviously to me for any arbitrary type, class reference_wrapper<T> will not automatically delegate all the functionality of T. That's why I'm not saying this is EXACTLY what I need. And remember to delcare T as reference_wrapper<T> for a variable is an extra burden to me. :-) In the meantile, your code is no different to the following much simpler form: boost::array<double, 2> array; double & d0 = array[0]; double & d1 = array[1]; array[0] = 1.0; array[1] = 2.0; assert( d1 == 2.0 ); I also tried the following code snnippet: typedef boost::reference_wrapper<double> double_ref_t; double d0, d1, d2, d3; boost::array<double_ref_t, 4> array = {{boost::ref(d0), boost::ref(d1), boost::ref(d2), boost::ref(d3)}}; for(int i=0; i<4; i++) array[i] = 2.0; assert(d2 == 2.0); return 0; It seems closer to what I need but, in fact, it has the same restriction. And, even worse, it didn't get compiled. Thank you anyway for your help! Still expecting more exiciting solutions! B/Rgds Max
participants (9)
-
Bill Somerville
-
Ed Keith
-
Joel Falcou
-
Max
-
Nat Goodspeed
-
Ovanes Markarian
-
Peter Bartlett
-
Ravi
-
Stefan Walk