as<T>(s)
andas_optional<T>(s)
read quite well,convert_to(t, s)
is not bad either- this interface still lacks the possibility to specify an own
qi
/karma
format, but they could be possibly added as optional arguments for the functionsas<T>(s, [in], [out])
,as_optional<T>(s, [in], [out])
andconvert_to(t, s, [in], [out])
- that, however, can make the interface already quite a bit more complicated…
Created
May 12, 2011 07:53
-
-
Save pyrtsa/968125 to your computer and use it in GitHub Desktop.
Sketching the interface for the Boost.Coerce library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// === The planned interface (work in progress) ================================ | |
namespace boost { namespace coerce { | |
// Does traits::as<T,S> provide the interface for extending the library? | |
namespace traits { | |
template <typename Target, typename Source, typename Enable = void> | |
struct as; | |
} | |
class bad_cast : public std::bad_cast {}; | |
template <typename Target, typename Source> | |
Target as(Source const & source); // throws on failure | |
template <typename Target, typename Source> | |
optional<Target> as_optional(Source const & source); // won't throw | |
// Might not be needed; equivalent to: as_optional<T>(x).get_value_or(t) | |
template <typename Target, typename Source> | |
Target as_default(Source const & source, Target const & default_); | |
// Ugly interface for those who don't default construct *) | |
template <typename Target, typename Source> | |
bool convert_to(Target & target, Source const & source); // true on success | |
// ________ | |
// *) I don't think types with no default constructor should be first class | |
// citizens for this library. The last interface, however, allows one to use | |
// the same machinery to convert to a non-default-constructible type. | |
}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// (skipping includes etc.) | |
namespace coerce = boost::coerce; | |
struct lacking_default_ctor { | |
int value; | |
explicit lacking_default_ctor(int value) : value(value) {} | |
}; | |
BOOST_FUSION_ADAPT_STRUCT(lacking_default_ctor, (int, value)) | |
std::string value = "2.5"; | |
// --- begin examples ---------------------------------------------------------- | |
// Examples 1 and 2a are probably the most common cases. | |
try { | |
int i = coerce::as<int>(value); /* example 1 */ | |
// ... | |
} catch (coerce::bad_cast &) { | |
// ... | |
} | |
boost::optional<double> d1 = coerce::as_optional<double>("1."); /* example 2a */ | |
// Works pretty readably with auto: | |
auto d2 = coerce::as_optional<double>("123.4"); /* example 2b */ | |
// as_optional competes with as_default, even if 14 chars longer: | |
double d3 = coerce::as_optional<double>(value).get_value_or(0); /* example 2c */ | |
double d4 = coerce::as_default<double>(value, 0); | |
// Alternative use for as_optional: | |
if (auto d = coerce::as_optional<double>(value)) { /* example 2d */ | |
std::cout << "Converted " << value << " to: " << d.get() << std::endl; | |
} else { | |
std::cerr << "Failed to convert " << value << " to double!" << std::endl; | |
} | |
float f = coerce::as_default<float>("1.2.3", 1.0f); /* example 3 */ | |
lacking_default_ctor lack(-1); | |
if (coerce::convert_to(lack, "123")) { /* example 4 */ | |
// ok | |
} else { | |
// handle error | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment