[program_options] Recent changes

Hello, just before feature freeze, I've committed some changes to program_options: - the command line parser was refactored. For historic reasons, it has its own data structures for representing options, and now it uses the options_description class. The internals were also cleaned up. - the 'implicit' option flag was removed. I've asked for comments on this some time ago, and no objections was raised. - some methods of 'options_description' and 'option_description' classes were removed - In 1.32, the 'additional_parser' could return only a single option. There's a new method of command line parser -- 'add_style_parser', which can be used to specify a function that can return vector<option>. This might be convenient, for example, for parsing response files Except for 'implicit' removal, those changes should not affect users of the library. However, I'd appreciate if user test the new version and report any problems. - Volodya

Vladimir Prus wrote:
Hello, just before feature freeze, I've committed some changes to program_options:
Seems like this broke program_options on Tru64/cxx. This is what I get when compiling the regression tests: cxx -c -timplicit_local -ptr "/vol2/boost/results/bin/boost/libs/program_options/build/libboost_program_options.a/tru64cxx65-042/debug/threading-mult i/cxx_repository" -noimplicit_include -D__USE_STD_IOSTREAM -nousing_std -msg_display_number -msg_disable 186,450,1115 -g -O0 -pthread -inline none -v ersion V6.5-042 -ieee -model ansi -I"/vol2/boost/results/bin/boost/libs/program_options/build" -I"/vol2/boost/boost" -I"/usr/include" -I"/vol2/boos t/boost" -o "/vol2/boost/results/bin/boost/libs/program_options/build/libboost_program_options.a/tru64cxx65-042/debug/threading-multi/cmdline.o" "/vol 2/boost/boost/libs/program_options/build/../src/cmdline.cpp" cxx: Warning: /vol2/boost/boost/libs/program_options/build/../src/cmdline.cpp, line 191: #767-D conversion from pointer to smaller integer assert(m_desc); --------^ cxx: Error: /vol2/boost/boost/boost/bind.hpp, line 978: #266 "value" is ambiguous detected during: instantiation of class "boost::_bi::add_value<T> [with T=boost::program_options::detail::cmdline *]" at line 1055 instantiation of class "boost::_bi::list_av_2<A1, A2> [with A1=boost::program_options::detail::cmdline *, A2=boost::arg<1>]" at line 200 of "/vol2/boost/boost/libs/program_options/build/../src/cmdl ine.cpp" typedef value<T> type; ------------^ cxx: Error: /vol2/boost/boost/boost/bind.hpp, line 264: #266 "value" is ambiguous detected during: instantiation of class "boost::_bi::list2<A1, A2> [with A1=boost::_bi::list_av_2<boost::program_options::detail:: cmdline *, boost::arg<1>>::B1, A2=boost::_bi::list_av_2<boost::program_options::detail:: cmdline *, boost::arg<1>>::B2]" at line 161 of "/vol2/boost/boost/boost/bind/bind_template.hpp" instantiation of class "boost::_bi::bind_t<R, F, L> [with R=std::vector<boost::program_options::option, std::allocator<boost::program_options::option>>, F=boost::_mfi::mf1<std::vector<boost::program_options::op tion, std::allocator<boost::program_options::option>>, boost::program_options::detail::cmdline, std::vector<std::string, std::allocator<std::string>> &>, L=boost::_bi::list2<boost::_bi::list_av_2<boost::program_ options::detail::cmdline *, boost::arg<1>>::B1, boost::_bi::list_av_2<boost::program_options::detail::cmd line *, boost::arg<1>>::B2>]" at line 200 of "/vol2/boost/boost/libs/program_options/build/../src/cmdl ine.cpp" template<class T> T & operator[] (value<T> & v) const { return v.get(); } --------------------------------------^ cxx: Error: /vol2/boost/boost/boost/bind.hpp, line 266: #266 "value" is ambiguous detected during: instantiation of class "boost::_bi::list2<A1, A2> [with A1=boost::_bi::list_av_2<boost::program_options::detail:: cmdline *, boost::arg<1>>::B1, A2=boost::_bi::list_av_2<boost::program_options::detail:: cmdline *, boost::arg<1>>::B2]" at line 161 of "/vol2/boost/boost/boost/bind/bind_template.hpp" instantiation of class "boost::_bi::bind_t<R, F, L> [with R=std::vector<boost::program_options::option, std::allocator<boost::program_options::option>>, F=boost::_mfi::mf1<std::vector<boost::program_options::op tion, std::allocator<boost::program_options::option>>, boost::program_options::detail::cmdline, std::vector<std::string, std::allocator<std::string>> &>, L=boost::_bi::list2<boost::_bi::list_av_2<boost::program_ options::detail::cmdline *, boost::arg<1>>::B1, boost::_bi::list_av_2<boost::program_options::detail::cmd line *, boost::arg<1>>::B2>]" at line 200 of "/vol2/boost/boost/libs/program_options/build/../src/cmdl ine.cpp" template<class T> T const & operator[] (value<T> const & v) const { return v.get(); } --------------------------------------------^ cxx: Info: 3 errors detected in the compilation of "/vol2/boost/boost/libs/program_options/build/../src/cmdline.cpp".

Markus Sch?pflin wrote:
Vladimir Prus wrote:
Hello, just before feature freeze, I've committed some changes to program_options:
Seems like this broke program_options on Tru64/cxx.
Did it work before? I recall some bind-releated problems on this platform were present previously.
cxx: Error: /vol2/boost/boost/boost/bind.hpp, line 978: #266 "value" is ambiguous detected during: instantiation of class "boost::_bi::add_value<T> [with T=boost::program_options::detail::cmdline *]" at line 1055 instantiation of class "boost::_bi::list_av_2<A1, A2> [with A1=boost::program_options::detail::cmdline *, A2=boost::arg<1>]" at line 200 of
Can you modify that line, replacing: template<class T> struct add_value { typedef value<T> type; }; template<class T> struct add_value< value<T> > { typedef value<T> type; }; with template<class T> struct add_value { typedef boost::_bi::value<T> type; }; template<class T> struct add_value< value<T> > { typedef boost::_bi::value<T> type; }; ? Looks like the compiler is incorrectly considering both boost::_bi::value (bind internal) and boost::program_options::value. Thanks, Volodya

Vladimir Prus wrote:
Markus Sch?pflin wrote:
Vladimir Prus wrote:
Hello, just before feature freeze, I've committed some changes to program_options:
Seems like this broke program_options on Tru64/cxx.
Did it work before? I recall some bind-releated problems on this platform were present previously.
cxx: Error: /vol2/boost/boost/boost/bind.hpp, line 978: #266 "value" is ambiguous detected during: instantiation of class "boost::_bi::add_value<T> [with T=boost::program_options::detail::cmdline *]" at line 1055 instantiation of class "boost::_bi::list_av_2<A1, A2> [with A1=boost::program_options::detail::cmdline *, A2=boost::arg<1>]" at line 200 of
Can you modify that line, replacing:
To clarify, /vol2/boost/boost/boost/bind.hpp, line 978 - Volodya

Vladimir Prus wrote:
Markus Sch?pflin wrote:
Seems like this broke program_options on Tru64/cxx.
Did it work before? I recall some bind-releated problems on this platform were present previously.
Yes, see http://tinyurl.com/aawmm for reference.
cxx: Error: /vol2/boost/boost/boost/bind.hpp, line 978: #266 "value" is ambiguous detected during: instantiation of class "boost::_bi::add_value<T> [with T=boost::program_options::detail::cmdline *]" at line 1055 instantiation of class "boost::_bi::list_av_2<A1, A2> [with A1=boost::program_options::detail::cmdline *, A2=boost::arg<1>]" at line 200 of
Can you modify that line, replacing:
<snip> Will do ASAP and report back. Thanks, Markus

Markus Schöpflin wrote:
Vladimir Prus wrote:
Did it work before? I recall some bind-releated problems on this platform were present previously.
certainly the following was added due to this kind of problem: http://tinyurl.com/bez3z Kevin -- | Kevin Wheatley, Cinesite (Europe) Ltd | Nobody thinks this | | Senior Technology | My employer for certain | | And Network Systems Architect | Not even myself |

Vladimir Prus wrote:
Markus Sch?pflin wrote:
Vladimir Prus wrote:
Hello, just before feature freeze, I've committed some changes to program_options:
Seems like this broke program_options on Tru64/cxx.
Did it work before? I recall some bind-releated problems on this platform were present previously.
cxx: Error: /vol2/boost/boost/boost/bind.hpp, line 978: #266 "value" is ambiguous detected during: instantiation of class "boost::_bi::add_value<T> [with T=boost::program_options::detail::cmdline *]" at line 1055 instantiation of class "boost::_bi::list_av_2<A1, A2> [with A1=boost::program_options::detail::cmdline *, A2=boost::arg<1>]" at line 200 of
Yes, I recall adding _bi:: at line 207, for example. If you make me a test case that exhibits these lookup-related problems, I'll add it to the tests and make sure that they are (and stay) fixed.

Peter Dimov wrote:
Vladimir Prus wrote:
Markus Sch?pflin wrote:
Vladimir Prus wrote:
Hello, just before feature freeze, I've committed some changes to program_options:
Seems like this broke program_options on Tru64/cxx.
Did it work before? I recall some bind-releated problems on this platform were present previously.
cxx: Error: /vol2/boost/boost/boost/bind.hpp, line 978: #266 "value" is ambiguous detected during: instantiation of class "boost::_bi::add_value<T> [with T=boost::program_options::detail::cmdline *]" at line 1055 instantiation of class "boost::_bi::list_av_2<A1, A2> [with A1=boost::program_options::detail::cmdline *, A2=boost::arg<1>]" at line 200 of
Yes, I recall adding _bi:: at line 207, for example. If you make me a test case that exhibits these lookup-related problems, I'll add it to the tests and make sure that they are (and stay) fixed.
I think the attached program should reproduce the problem, but only Markus can confirm that. - Volodya

Peter Dimov wrote:
Yes, I recall adding _bi:: at line 207, for example. If you make me a test case that exhibits these lookup-related problems, I'll add it to the tests and make sure that they are (and stay) fixed.
Attached is a minimal test case that exibits this problem. It does not compile with the current "bind.hpp" and compiles cleanly when the patch I posted in another thread is applied. Markus #include <boost/bind.hpp> template<class T> void value(); void foo() { } void foo(int) { } void foo(int, int) { } void foo(int, int, int) { } void foo(int, int, int, int) { } void foo(int, int, int, int, int) { } void foo(int, int, int, int, int, int) { } void foo(int, int, int, int, int, int, int) { } void foo(int, int, int, int, int, int, int, int) { } void foo(int, int, int, int, int, int, int, int, int) { } int main() { boost::bind(foo); boost::bind(foo, 0); boost::bind(foo, 0, 0); boost::bind(foo, 0, 0, 0); boost::bind(foo, 0, 0, 0, 0); boost::bind(foo, 0, 0, 0, 0, 0); boost::bind(foo, 0, 0, 0, 0, 0, 0); boost::bind(foo, 0, 0, 0, 0, 0, 0, 0); boost::bind(foo, 0, 0, 0, 0, 0, 0, 0, 0); boost::bind(foo, 0, 0, 0, 0, 0, 0, 0, 0, 0); }

Markus Schöpflin wrote:
Peter Dimov wrote:
Yes, I recall adding _bi:: at line 207, for example. If you make me a test case that exhibits these lookup-related problems, I'll add it to the tests and make sure that they are (and stay) fixed.
Attached is a minimal test case that exibits this problem.
Ah, _that_ test case. bind_lookup_problem is still fine.

Vladimir Prus wrote:
Can you modify that line, replacing:
template<class T> struct add_value { typedef value<T> type; };
template<class T> struct add_value< value<T> > { typedef value<T> type; };
with
template<class T> struct add_value { typedef boost::_bi::value<T> type; };
template<class T> struct add_value< value<T> > { typedef boost::_bi::value<T> type; };
?
template<class T> struct add_value { typedef _bi::value<T> type; }; should be enough, if my theory is right.

Attached patch to "bind.hpp" fixes the issue on this platform. If it's ok, I can apply it. Next I will try your minimal test case to see if it reproduces the problem. Markus Index: bind.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/bind.hpp,v retrieving revision 1.44 diff -u -r1.44 bind.hpp --- bind.hpp 15 Mar 2005 14:15:30 -0000 1.44 +++ bind.hpp 26 Apr 2005 13:05:41 -0000 @@ -154,9 +154,9 @@ list0() {} - template<class T> T & operator[] (value<T> & v) const { return v.get(); } + template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); } - template<class T> T const & operator[] (value<T> const & v) const { return v.get(); } + template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); } template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); } @@ -261,9 +261,9 @@ A1 operator[] (boost::arg<1> (*) ()) const { return a1_; } A2 operator[] (boost::arg<2> (*) ()) const { return a2_; } - template<class T> T & operator[] (value<T> & v) const { return v.get(); } + template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); } - template<class T> T const & operator[] (value<T> const & v) const { return v.get(); } + template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); } template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); } @@ -322,9 +322,9 @@ A2 operator[] (boost::arg<2> (*) ()) const { return a2_; } A3 operator[] (boost::arg<3> (*) ()) const { return a3_; } - template<class T> T & operator[] (value<T> & v) const { return v.get(); } + template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); } - template<class T> T const & operator[] (value<T> const & v) const { return v.get(); } + template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); } template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); } @@ -387,9 +387,9 @@ A3 operator[] (boost::arg<3> (*) ()) const { return a3_; } A4 operator[] (boost::arg<4> (*) ()) const { return a4_; } - template<class T> T & operator[] (value<T> & v) const { return v.get(); } + template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); } - template<class T> T const & operator[] (value<T> const & v) const { return v.get(); } + template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); } template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); } @@ -458,9 +458,9 @@ A4 operator[] (boost::arg<4> (*) ()) const { return a4_; } A5 operator[] (boost::arg<5> (*) ()) const { return a5_; } - template<class T> T & operator[] (value<T> & v) const { return v.get(); } + template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); } - template<class T> T const & operator[] (value<T> const & v) const { return v.get(); } + template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); } template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); } @@ -533,9 +533,9 @@ A5 operator[] (boost::arg<5> (*) ()) const { return a5_; } A6 operator[] (boost::arg<6> (*) ()) const { return a6_; } - template<class T> T & operator[] (value<T> & v) const { return v.get(); } + template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); } - template<class T> T const & operator[] (value<T> const & v) const { return v.get(); } + template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); } template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); } @@ -612,9 +612,9 @@ A6 operator[] (boost::arg<6> (*) ()) const { return a6_; } A7 operator[] (boost::arg<7> (*) ()) const { return a7_; } - template<class T> T & operator[] (value<T> & v) const { return v.get(); } + template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); } - template<class T> T const & operator[] (value<T> const & v) const { return v.get(); } + template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); } template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); } @@ -696,9 +696,9 @@ A7 operator[] (boost::arg<7> (*) ()) const { return a7_; } A8 operator[] (boost::arg<8> (*) ()) const { return a8_; } - template<class T> T & operator[] (value<T> & v) const { return v.get(); } + template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); } - template<class T> T const & operator[] (value<T> const & v) const { return v.get(); } + template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); } template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); } @@ -784,9 +784,9 @@ A8 operator[] (boost::arg<8> (*) ()) const { return a8_; } A9 operator[] (boost::arg<9> (*) ()) const { return a9_; } - template<class T> T & operator[] (value<T> & v) const { return v.get(); } + template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); } - template<class T> T const & operator[] (value<T> const & v) const { return v.get(); } + template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); } template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); } @@ -975,12 +975,12 @@ template<class T> struct add_value { - typedef value<T> type; + typedef _bi::value<T> type; }; template<class T> struct add_value< value<T> > { - typedef value<T> type; + typedef _bi::value<T> type; }; template<class T> struct add_value< reference_wrapper<T> >

Markus Schöpflin wrote:
Attached patch to "bind.hpp" fixes the issue on this platform. If it's ok, I can apply it.
Yes, please go ahead if our release manager doesn't object. But the proper procedure is really to first add a test case that fails and then apply a patch that cures the failure, since without a test, we can easily reintroduce the problem at a later date without anybody noticing.

Peter Dimov wrote:
Markus Schöpflin wrote:
Attached patch to "bind.hpp" fixes the issue on this platform. If it's ok, I can apply it.
Yes, please go ahead if our release manager doesn't object. But the proper procedure is really to first add a test case that fails and then apply a patch that cures the failure, since without a test, we can easily reintroduce the problem at a later date without anybody noticing.
If you supply me with a good name for the test I will gladly add the test I posted to the bind test suite. ;-) Markus

Peter Dimov wrote:
Markus Schöpflin wrote:
If you supply me with a good name for the test I will gladly add the test I posted to the bind test suite. ;-)
You mean the test Vladimir posted? bind_lookup_problem is fine with me. ;-)
Nope, the one I posted. ;-) I'll add it and apply the patch. If I do anything wrong, feel free to shout at me. Markus

Peter Dimov wrote:
Markus Schöpflin wrote:
Attached patch to "bind.hpp" fixes the issue on this platform. If it's ok, I can apply it.
Yes, please go ahead if our release manager doesn't object. But the proper procedure is really to first add a test case that fails and then apply a patch that cures the failure, since without a test, we can easily reintroduce the problem at a later date without anybody noticing.
A test case has been added and the patch has been applied. All tests for bind and for program_options now pass for this platform. Thanks, Markus

Markus Sch?pflin wrote:
Peter Dimov wrote:
Markus Sch?pflin wrote:
Attached patch to "bind.hpp" fixes the issue on this platform. If it's ok, I can apply it.
Yes, please go ahead if our release manager doesn't object. But the proper procedure is really to first add a test case that fails and then apply a patch that cures the failure, since without a test, we can easily reintroduce the problem at a later date without anybody noticing.
A test case has been added and the patch has been applied. All tests for bind and for program_options now pass for this platform.
Thanks! - Volodya

Vladimir Prus wrote:
just before feature freeze, I've committed some changes to program_options:
- the command line parser was refactored. For historic reasons, it has its own data structures for representing options, and now it uses the options_description class. The internals were also cleaned up.
- the 'implicit' option flag was removed. I've asked for comments on this some time ago, and no objections was raised.
- some methods of 'options_description' and 'option_description' classes were removed
- In 1.32, the 'additional_parser' could return only a single option. There's a new method of command line parser -- 'add_style_parser', which can be used to specify a function that can return vector<option>. This might be convenient, for example, for parsing response files
Except for 'implicit' removal, those changes should not affect users of the library. However, I'd appreciate if user test the new version and report any problems.
I recently had some problems with changed semantics of a 0 (zero) as the style parameter in parse_command_line(argc, argv, opts_desc, 0, ...); here------------------------------------------^ where the '0' in earlier versions was interpreted as the default_style, but it is interpreted now as is (as zero). Was this change a bugfix? Regards Hartmut

Hi Hartmut,
Vladimir Prus wrote:
just before feature freeze, I've committed some changes to program_options: I recently had some problems with changed semantics of a 0 (zero) as the style parameter in
parse_command_line(argc, argv, opts_desc, 0, ...); here------------------------------------------^
where the '0' in earlier versions was interpreted as the default_style, but it is interpreted now as is (as zero).
Was this change a bugfix?
No, it was a regression. A fix and a test for this problem are now committed. OTOH, you can rewrite the above as: command_line_parser(argc, argv).options(desc).additional_parser(whatever).run() Some kind of named parameters, which does not require to pass '0' for 'style' at all. But parse_command_line function will be still there anyway. Thanks, Volodya

Vladimir Prus wrote:
just before feature freeze, I've committed some changes to program_options: I recently had some problems with changed semantics of a 0 (zero) as the style parameter in
parse_command_line(argc, argv, opts_desc, 0, ...); here------------------------------------------^
where the '0' in earlier versions was interpreted as the default_style, but it is interpreted now as is (as zero).
Was this change a bugfix?
No, it was a regression. A fix and a test for this problem are now committed.
Thanks for fixing!
OTOH, you can rewrite the above as:
command_line_parser(argc, argv).options(desc).additional_parser(whatever).run()
Some kind of named parameters, which does not require to pass '0' for 'style' at all.
But parse_command_line function will be still there anyway.
Yeah, I know. The parse_command_line is more convenient. Regards Hartmut
participants (5)
-
Hartmut Kaiser
-
Kevin Wheatley
-
Markus Schöpflin
-
Peter Dimov
-
Vladimir Prus