Boost logo

Boost :

Subject: [boost] Review Request: Introduction of boost::string namespace and string-conversion functions
From: Vladimir.Batov_at_[hidden]
Date: 2009-02-11 14:21:39


Based on the previous string-conversion-related discussion that revolved
around lexical_cast (started with
http://lists.boost.org/Archives/boost/2009/01/147013.php) and Dave's
suggestion (http://lists.boost.org/Archives/boost/2009/02/147995.php) I
would like to propose to create a new

        boost::string

namespace where I'd expect all string-related functionality might be
logically housed. Dave already mentioned that "Jeff Garland had a really
nice set of proposed extensions to
std::string that could live in the same space".

My immediate interest/proposal in that namespace would be the
string-conversion functionality. The basics of that functionality are
currently handled by lexical_cast but need extended and unambiguously
tagged as *string*-related conversions. During discussion I've got a
strong impression that the majority of people, the lexical_cast author
(Kevlin) and the maintainer (Alex) strongly favor leaving lexical_cast
as-is and having a fresh start capitalizing on the past experiences.

Therefore I'd like to propose the string-conversion functionality that'd
be housed inside that mentioned boost::string namespace. This proposal of
mine probably is not as conventional as I have no implementation code to
show. That is because before committing to it any further (or dragging
someone else into it) I would initially like to see if we can agree on

1) creating boost::string (or some other as descriptive name) namespace;
2) the interface for that proposed string-conversion functionality.

After that I expect the implementation to be largely a technical issue.

>From the user point the interface I'd like to propose might look like the
following:

int i;
std::string s;

1) int i_from_s = boost::string::to<int>(s); // throws
2) std::string s_from_i = boost::string::from<int>(i);
3) bool s_is_i = boost::string::is<int>(i);

The above convert a string to an integer (#1), an integer to a string (#2)
and check if conversion is possible (#3). #1 and #2 behave like
lexical_cast currently does (throw on failure). #3 is a non-throwing check
if #1 will succeed (to avoid handling an exception thrown by #1). For
example,

int i_from_s = boost::string::is<int>(s)
        ? boost::string::to<int>(s) // safe to request conversion
        : some-failure-value;

I like to/from names as they allow me to read the code as it was merely
English -- "string to int", "string from int".

I expect string::to() and string:;from() to return a helper object as Dave
suggested

namespace string
{
        template <class T>
        struct value
        {
                operator T() const; // throws iff parse unsuccessful
                bool good() const; // true iff parse will succeed
                ...
        };
}

That'll allow as to make the interface consistent and
extendable/chainable:

4) int i_from_s = boost::string::to<int>(s)(-1);

The above is a non-throwing variation of #1 with the default value
provided for failed conversion.

5) int i_from_s = boost::string::to<int>(s)(std::hex);
6) std::string s_from_i = boost::string::from<int>(i)(std::hex);

The above is variations of #1 and #2 with the std::hex
manipulator/formatter applied.

That "chained" approach would allow to keep the interface consistency
without sacrificing the flexibility. For example,

7) int i_from_s =
boost::string::to<int>(s)(-1)(std::hex)(yet-another-manipulator);

or add some other features when the need arises.

Off the cuff the actual conversion might look something along the
following lines:

template<class T, class Char>
boost::string::value::operator T()
{
        std::basic_istringstream<Char> stream(string_);

        if (manipulators) stream >> manipulator_ >> ... >> value_;
        else stream >> value_;

        if (stream.fail())
                if (no_default) throw something;
                else return default_value_;
        return value_;
}
 
Thanks,
Vladimir.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk