+inline typename std::enable_if<
+ !std::is_same<StringPiece, Tgt>::value,
+ Expected<Tgt, detail::ParseToError<Tgt>>>::type
+tryTo(StringPiece src) {
+ Tgt result{};
+ using Error = detail::ParseToError<Tgt>;
+ using Check = typename std::conditional<
+ std::is_arithmetic<Tgt>::value,
+ detail::CheckTrailingSpace,
+ detail::ReturnUnit<Error>>::type;
+ return parseTo(src, result).then(Check(), [&](Unit) {
+ return std::move(result);
+ });
+}
+
+template <class Tgt, class Src>
+inline typename std::enable_if<
+ IsSomeString<Src>::value && !std::is_same<StringPiece, Tgt>::value,
+ Tgt>::type
+to(Src const& src) {
+ return to<Tgt>(StringPiece(src.data(), src.size()));
+}
+
+template <class Tgt>
+inline
+ typename std::enable_if<!std::is_same<StringPiece, Tgt>::value, Tgt>::type
+ to(StringPiece src) {
+ Tgt result{};
+ using Error = detail::ParseToError<Tgt>;
+ using Check = typename std::conditional<
+ std::is_arithmetic<Tgt>::value,
+ detail::CheckTrailingSpace,
+ detail::ReturnUnit<Error>>::type;
+ auto tmp = detail::parseToWrap(src, result);
+ return tmp
+ .thenOrThrow(Check(), [&](Error e) { throw makeConversionError(e, src); })
+ .thenOrThrow(
+ [&](Unit) { return std::move(result); },
+ [&](Error e) { throw makeConversionError(e, tmp.value()); });
+}
+
+/**
+ * tryTo/to that take the strings by pointer so the caller gets information
+ * about how much of the string was consumed by the conversion. These do not
+ * check for trailing whitepsace.
+ */
+template <class Tgt>
+Expected<Tgt, detail::ParseToError<Tgt>> tryTo(StringPiece* src) {