format: add invalid_specifier exception

This commit is contained in:
Danny Robson 2016-04-27 16:12:24 +10:00
parent 61ba8e5186
commit df9d0ce432
4 changed files with 37 additions and 10 deletions

View File

@ -17,10 +17,3 @@
#include "format.hpp" #include "format.hpp"
#include <utility> #include <utility>
//std::string
//util::format (std::string &&fmt)
//{
// return std::move (fmt);
//}

View File

@ -11,7 +11,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
* Copyright 2015 Danny Robson <danny@nerdcruft.net> * Copyright 2015-2016 Danny Robson <danny@nerdcruft.net>
*/ */
#ifndef __UTIL_FORMAT_HPP #ifndef __UTIL_FORMAT_HPP
@ -37,6 +37,19 @@ namespace util {
class format_error : public error class format_error : public error
{ using error::error; }; { using error::error; };
template <typename ValueT>
class invalid_specifier : public format_error {
public:
using value_type = ValueT;
invalid_specifier (char specifier);
char specifier (void) const;
private:
char m_specifier;
};
// missing format specifier // missing format specifier
class missing_error : public error class missing_error : public error
{ using error::error; }; { using error::error; };

View File

@ -165,7 +165,7 @@ namespace util {
throw util::format::format_error ("missing format specifier"); throw util::format::format_error ("missing format specifier");
if (!is_valid_specifier<typename std::decay<ValueT>::type> (&*spec)) if (!is_valid_specifier<typename std::decay<ValueT>::type> (&*spec))
throw util::format::format_error ("invalid/unhandled format specifier"); throw util::format::invalid_specifier<ValueT> (*spec);
if (*spec == 'x') { if (*spec == 'x') {
dest << std::hex << val << std::dec; dest << std::hex << val << std::dec;
@ -194,4 +194,25 @@ namespace util {
return out.str (); return out.str ();
} }
} }
///////////////////////////////////////////////////////////////////////////
// TODO: we'd like to use typeid here for type naming, but we don't allow
// RTTI. revisit this when introspection is more advanced.
template <typename ValueT>
format::invalid_specifier<ValueT>::invalid_specifier (char _specifier):
format_error (
format::render ("invalid specifier '%c' for type '%s'",
_specifier,
"unimplemented")
),
m_specifier (_specifier)
{ ; }
//-------------------------------------------------------------------------
template <typename ValueT>
char
format::invalid_specifier<ValueT>::specifier (void) const
{ return m_specifier; }
} }

View File

@ -17,7 +17,7 @@ main (void)
util::format::render ("%s"); util::format::render ("%s");
}, "missing value"); }, "missing value");
tap.expect_throw<util::format::format_error> ([] (void) { tap.expect_throw<util::format::invalid_specifier<int>> ([] (void) {
util::format::render ("%<", 42); util::format::render ("%<", 42);
}, "invalid specifier"); }, "invalid specifier");