Boost logo

Boost Users :

From: Boris (boriss_at_[hidden])
Date: 2008-04-02 14:06:57


On Wed, 02 Apr 2008 17:32:56 +0200, John Maddock <john_at_[hidden]>
wrote:

John,

> [...]
>> I don't know why the code using Boost.Spirit compiles (is this
>> implementation-dependent or guaranteed behavior)? It would make using
>> regular expressions in templates much easier though as regular
>> expressions don't seem to depend on the Char type of strings
>> (assuming this is a feature I can rely on)?
>
> Well that depends on the regular expression, something like
> "[\x{0370}-\x{03ff}]+" most certainly does depend upon the character
> type!
> ;-)

I converted a JSON parser called TinyJSON (see
http://blog.beef.de/projects/tinyjson/) to a template recently so it can
be used with char- and wchar_t-based strings (among others). As it's a
JSON parser text has to be parsed which typically means tokens have to be
compared. A JSON object starts for example with { which is '{' for
char-based parsers and L'{' for wchar_t-based parsers.

You can't write either '{' nor L'{' though as the literal type does not
depend on the template parameter. When I found out that Boost.Spirit still
works for various string types (std::string, std::wstring,
std::basic_string<int>) even though char-based literals are used to define
the rules (like regular expressions) I was pretty much surprised. I
created a couple of test cases to verify that the parser works but I'm not
sure if I tricked myself.

The idea of making the JSON parser a template is of course to make it work
with any string type no matter what charT type it is based on. As the JSON
parser is a text processing class though I'm not sure if there is a hidden
additional requirement related to encoding. Then the template would not
only be dependent on a type but on something else which would not be
obvious to the user (and which would make me think that making the JSON
parser a template is actually not a good idea)?

I searched Usenet to see if anyone else ran into a similar problem and
found this thread:
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/23dc9ccc60d0ba95/de1ebb6ba16264d7

With Boost.Spirit the problem can be solved:

template< typename Char >
bool isPassword( std::basic_string<Char> const& s )
{
   // return s == "password"; <-- This works only for std::string
   // return s == L"password"; <-- This works only for std::wstring

   // This works for any string type:
   boost::spirit::rxstrlit<> expr("password");
   return boost::spirit::parse(s.c_str(), expr).full;
}

I wonder if I missed anything? Is this the cheap, simple and efficient
solution for literal strings in templates Alf was looking for in his
thread on Usenet? Or is there an implicit requirement about encoding which
I currently don't see and which makes code like above a bad idea?

Boris


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net