Interest check: constant input matching manipulator

Hi, Recently, I observed in an online community a question on whether C++ had a direct replacement for a call to scanf("a=%d", a) for some int a, using std::cin. The response given was to read the input as a string and then parse it. Another user noted that "iostreams would be more useful if it had the ability to match constant portions of the input". Looking at what already exists in the standard library and Boost, there does indeed seem to be no direct way to match such expected constant input. Boost.Regex and Boost.Tokenizer are indirect in this case (and possibly overkill), and Boost.Format is about output stream formatting only. Boost.Spirit appears to provide a way with file_iterator, but a manipulator seems more appropriate here considering that the functionality is quite simple. Does anyone think that adding such a manipulator to Boost would be desirable? I expect the syntax to be along these lines (names and namespaces to be decided): std::cin >> match("a=") >> a; where a failure to match would place the input stream in a failed state. It would also be possible to use a std::basic_string instead of a string literal converted to a pointer to its first element as the argument. I have already written such a manipulator, so if anyone is interested, I can provide my sample source. Regards, Eugene Wee

Eugene Wee wrote:
Does anyone think that adding such a manipulator to Boost would be desirable? I expect the syntax to be along these lines (names and namespaces to be decided): std::cin >> match("a=") >> a; where a failure to match would place the input stream in a failed state. It would also be possible to use a std::basic_string instead of a string literal converted to a pointer to its first element as the argument.
Spirit2 already provides such functionality: #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/qi_stream.hpp> [...] using namespace boost::spirit; using namespace boost::spirit::qi; std::cin >> match("a=" >> int_, a); Regards, François

On Wednesday, April 08, 2009 3:20 PM Francois Barel wrote:
Eugene Wee wrote:
Does anyone think that adding such a manipulator to Boost would be
+1
desirable? I expect the syntax to be along these lines (names and namespaces to be decided): std::cin >> match("a=") >> a;
I'm not entirely comfortable with "match." What about "literal" or "exactly?"
Spirit2 already provides such functionality:
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/qi_stream.hpp> [...] using namespace boost::spirit; using namespace boost::spirit::qi; std::cin >> match("a=" >> int_, a);
That's a lot of noise and the syntax is non-obvious for the purpose at hand. I suspect unwarranted compilation overhead, too. Something simpler seems in order: #include <boost/something/literal.hpp> ... using boost::something::literal; int a; std::cin >> literal("a=") >> a; _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

On Wed, Apr 8, 2009 at 16:24, Stewart, Robert <Robert.Stewart@sig.com> wrote:
That's a lot of noise and the syntax is non-obvious for the purpose at hand. I suspect unwarranted compilation overhead, too. Something simpler seems in order:
#include <boost/something/literal.hpp> ... using boost::something::literal;
int a; std::cin >> literal("a=") >> a;
Do we need any (new) syntax at all? What if we just make RValues always do that where reasonable? Then we can spell it add_const if actually needed... In fact, can someone come up with a good use case for needing more than just character and string literals? I feel like anything more than that might be better left to spirit/regex/whatever.

AMDG Scott McMurray wrote:
On Wed, Apr 8, 2009 at 16:24, Stewart, Robert <Robert.Stewart@sig.com> wrote:
That's a lot of noise and the syntax is non-obvious for the purpose at hand. I suspect unwarranted compilation overhead, too. Something simpler seems in order:
#include <boost/something/literal.hpp> ... using boost::something::literal;
int a; std::cin >> literal("a=") >> a;
Do we need any (new) syntax at all? What if we just make RValues always do that where reasonable? Then we can spell it add_const if actually needed...
In fact, can someone come up with a good use case for needing more than just character and string literals? I feel like anything more than that might be better left to spirit/regex/whatever.
You can't overload operator>> for a built in type and a std::istream. In Christ, Steven Watanabe

Hi, Franciois Barel:
Spirit2 already provides such functionality:
Ah, I missed that, thanks. That said... Rob Stewart:
I'm not entirely comfortable with "match." What about "literal" or "exactly?"
Yes, "literal" would be fine to me, though I feel that people might not exactly understand what "exactly" means :)
That's a lot of noise and the syntax is non-obvious for the purpose at hand.
I agree. It may be more powerful, but I think there is a benefit to keeping it simple. Scott McMurray:
In fact, can someone come up with a good use case for needing more than just character and string literals? I feel like anything more than that might be better left to spirit/regex/whatever.
That is my opinion as well. What I have in mind really is a direct supplement to meet what the scanf() family can do with format strings that include more than just the format specifiers, but I am not sure if turning this into an input stream version of Boost.Format is a good idea, so I shall stick with proposing a manipulator for now. Regards, Eugene Wee

Hi, I have decided to upload my code to the Vault: http://www.boostpro.com/vault/index.php?action=downloadfile&filename=iomanip.hpp&directory=Input%20-%20Output I have included a rename of "match" to "literal" and a version of the manipulator to match with characters rather than only strings, though for now the implementation still works via std::basic_string. Regards, Eugene Wee

On Wednesday, April 08, 2009 9:35 PM Steven Watanabe wrote:
Scott McMurray wrote:
Do we need any (new) syntax at all? What if we just make RValues always do that where reasonable? Then we can spell it add_const if actually needed...
You can't overload operator>> for a built in type and a std::istream.
I presume you're referring to 17.4.3.1/1, but the necessary operators would be in the global namespace and they don't conflict with the existing overloads because of the const arguments: template < class IStream , class Char = IStream::char_type , class Traits = IStream::traits_type , class Allocator = std::allocator<Char>
IStream & operator >>(IStream & _stream, std::basic_string<Char,Traits,Allocator> const & _literal); template <class IStream> IStream & operator >>(IStream & _stream, typename IStream::char_type const * _literal); Did I miss something? _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

AMDG Stewart, Robert wrote:
I presume you're referring to 17.4.3.1/1, but the necessary operators would be in the global namespace and they don't conflict with the existing overloads because of the const arguments:
template < class IStream , class Char = IStream::char_type , class Traits = IStream::traits_type , class Allocator = std::allocator<Char>
IStream & operator >>(IStream & _stream, std::basic_string<Char,Traits,Allocator> const & _literal);
template <class IStream> IStream & operator >>(IStream & _stream, typename IStream::char_type const * _literal);
Did I miss something?
Such an overload is legal but useless because it won't be found by ADL. In Christ, Steven Watanabe

On Thursday, April 09, 2009 10:11 AM Steven Watanabe wrote:
Stewart, Robert wrote:
Did I miss something?
Such an overload is legal but useless because it won't be found by ADL.
Doh! I was too focused on other aspects to think about the need for ADL to find an operator overload. For that to work, of course, the operators must be in namespace std and that's undefined due to 17.4.3.1/1. IOW, I did miss something. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Hi, On Thu, Apr 9, 2009 at 10:17 PM, Stewart, Robert <Robert.Stewart@sig.com> wrote:
Doh! I was too focused on other aspects to think about the need for ADL to find an operator overload. For that to work, of course, the operators must be in namespace std and that's undefined due to 17.4.3.1/1. IOW, I did miss something.
Of course, that means that Scott McMurray's idea is still applicable as an addition to the C++ standard :) But... I have been trying to figure out exactly why "such an overload is legal but useless because it won't be found by ADL". What exactly are the applicable lookup rules here? Simple examples based on Rob's suggestion and adaptations of my own manipulator code do seem to work, and I had the impression that ADL is an extension of unqualified name lookup (but I am also aware, with a rather hazy view, that the lookup rules for templates are a little different). Thanks, Eugene Wee
participants (5)
-
Eugene Wee
-
Francois Barel
-
Scott McMurray
-
Steven Watanabe
-
Stewart, Robert