|
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