|
Boost : |
Subject: Re: [boost] Boost review of the Convert library is ongoing
From: alex (alexhighviz_at_[hidden])
Date: 2014-05-20 07:15:25
>> ... This is about needing to specify what the "contract" for a converter
is.
>In my view there is no "contract for converter"... apart from the
>*requirement* it is a "callable" with a certain signature.
That is indeed exactly where we disagree.
>
>> Conversion to/from string requires a different contract than
>> conversion between types, encryption or conversion from Celsius to
>> Fahrenheit.
>
>I fail to see how/why these mentioned different type
>conversions/transformations "require different contracts".
Perhaps it is better to say 'would benefit from different contracts'.
For instance:
type-to-type converters would benefit from contracts that specify mechanisms
for checking for reversibility, loss of precision, overflow, etc.
type-string converters would benefit from contracts that specify mechanisms
for giving formatting instructions
unit-to-unit converters would benefit from all kinds of consistency and
equivalence test... see the Boost Unit library
encryptions converters would benefit from contracts that specify mechanisms
to specify/query encryption strength
>> The user still needs to supply a Default Construction function it is just
>> not the default constructor. I can see that this requirement follows from
>> the stringstream implementation.
>
>No, it's not a requirement of std::sstream but rather imposed by
>boost::convert::from.
>
Yes, but why? Isn't the underlying reason that sstream requires a reference?
my_type val;
stream >> val;
>> But it does not seem a reasonable
>> requirement for a generic converter (nor is the requirement of Copy
>> Constructible). All you can reasonably require is some function that
creates
>> a TypeOut from a TypeIn.
>
>I was not able to come up with a better implementation that would not have
>those requirements. If you have such an implementation, I'll incorporate
>it gladly.
>
How about reducing the API to the following? The only requirement on TypeOut
would be the requirements put by boost::optional (or your closely related
result-type).
api.hpp
#include <boost/optional.hpp>
namespace boost
template<typename TypeOut> struct convert
template<typename TypeIn, typename Converter>
static boost::optional<TypeOut> from(TypeIn const& in, Converter const&
converter)
{
boost::optional<TypeOut> out;
converter(in, out);
return out;
}
};
}
In sstream.hpp you would have(with some simplification)
template<typename T> struct convert_default_maker
{
static T make() { return T(); }
};
// in sstream.hpp
template<TypeIn, TypeOut>
void boost::basic_stringstream_converter::operator()(const TypeIn& in,
boost::optional<TypeOut>& out)
{
TypeOut out_value = boost::convert_default_maker<TypeOut>::make();
stream_.str(std::basic_string< char_type>());
stream_ << in;
stream_ >> out_value;
out = boost::make_optional(!stream_.fail(), out_value);
}
And for class with expensive constructor:
template<T> struct large_vector
{
large_vector(const T& v) : m_vector(v, 1000000){}
std::vector<T> m_vector;
};
template<TypeIn, TypeOut>
void boost::large_vector_converter operator() (const TypeIn& in, boost::
optional <TypeOut>& out)
{
try {
out = large_vector< TypeIn >(in);
} catch() {
out = boost::none;
}
}
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk