diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2016-09-21 16:00:03 +0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2016-09-21 16:54:53 +0200 |
commit | 4036185cb4bacbf6acaaa1a906924dfa2cdd9413 (patch) | |
tree | b7169ae0d7a120e433dcecbd20333f0dbd1e8f8a /src/libutil/types.hh | |
parent | 3f8e620b1907968c47bdbe955095301159dc78ad (diff) |
Some notational convenience for formatting strings
We can now write
throw Error("file '%s' not found", path);
instead of
throw Error(format("file '%s' not found") % path);
and similarly
printError("file '%s' not found", path);
instead of
printMsg(lvlError, format("file '%s' not found") % path);
Diffstat (limited to 'src/libutil/types.hh')
-rw-r--r-- | src/libutil/types.hh | 69 |
1 files changed, 65 insertions, 4 deletions
diff --git a/src/libutil/types.hh b/src/libutil/types.hh index bd192b850..b9a93d27d 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -41,6 +41,45 @@ struct FormatOrString }; +/* A helper for formatting strings. ‘fmt(format, a_0, ..., a_n)’ is + equivalent to ‘boost::format(format) % a_0 % ... % + ... a_n’. However, ‘fmt(s)’ is equivalent to ‘s’ (so no %-expansion + takes place). */ + +inline void formatHelper(boost::format & f) +{ +} + +template<typename T, typename... Args> +inline void formatHelper(boost::format & f, T x, Args... args) +{ + formatHelper(f % x, args...); +} + +inline std::string fmt(const std::string & s) +{ + return s; +} + +inline std::string fmt(const char * s) +{ + return s; +} + +inline std::string fmt(const FormatOrString & fs) +{ + return fs.s; +} + +template<typename... Args> +inline std::string fmt(const std::string & fs, Args... args) +{ + boost::format f(fs); + formatHelper(f, args...); + return f.str(); +} + + /* BaseError should generally not be caught, as it has Interrupted as a subclass. Catch Error instead. */ class BaseError : public std::exception @@ -49,14 +88,28 @@ protected: string prefix_; // used for location traces etc. string err; public: - unsigned int status; // exit status - BaseError(const FormatOrString & fs, unsigned int status = 1); + unsigned int status = 1; // exit status + + template<typename... Args> + BaseError(unsigned int status, Args... args) + : err(fmt(args...)) + , status(status) + { + } + + template<typename... Args> + BaseError(Args... args) + : err(fmt(args...)) + { + } + #ifdef EXCEPTION_NEEDS_THROW_SPEC ~BaseError() throw () { }; const char * what() const throw () { return err.c_str(); } #else const char * what() const noexcept { return err.c_str(); } #endif + const string & msg() const { return err; } const string & prefix() const { return prefix_; } BaseError & addPrefix(const FormatOrString & fs); @@ -66,7 +119,7 @@ public: class newClass : public superClass \ { \ public: \ - newClass(const FormatOrString & fs, unsigned int status = 1) : superClass(fs, status) { }; \ + using superClass::superClass; \ }; MakeError(Error, BaseError) @@ -75,7 +128,15 @@ class SysError : public Error { public: int errNo; - SysError(const FormatOrString & fs); + + template<typename... Args> + SysError(Args... args) + : Error(addErrno(fmt(args...))) + { } + +private: + + std::string addErrno(const std::string & s); }; |