diff options
author | Ben Longbons <b.r.longbons@gmail.com> | 2012-12-27 21:23:46 -0800 |
---|---|---|
committer | Ben Longbons <b.r.longbons@gmail.com> | 2013-01-07 15:31:38 -0800 |
commit | c080e504e4d74027b985b1ed675c172c083cea76 (patch) | |
tree | ac084d16d9d40c0a0c950b66eb62a0e16795d486 /src/common/cxxstdio.hpp | |
parent | ae30173d71d3bfc8514dbe70b6c90c9a3324b8fc (diff) | |
download | tmwa-c080e504e4d74027b985b1ed675c172c083cea76.tar.gz tmwa-c080e504e4d74027b985b1ed675c172c083cea76.tar.bz2 tmwa-c080e504e4d74027b985b1ed675c172c083cea76.tar.xz tmwa-c080e504e4d74027b985b1ed675c172c083cea76.zip |
Use cxxstdio
Diffstat (limited to 'src/common/cxxstdio.hpp')
-rw-r--r-- | src/common/cxxstdio.hpp | 123 |
1 files changed, 97 insertions, 26 deletions
diff --git a/src/common/cxxstdio.hpp b/src/common/cxxstdio.hpp index 2bd4f4b..6f5072e 100644 --- a/src/common/cxxstdio.hpp +++ b/src/common/cxxstdio.hpp @@ -27,6 +27,8 @@ #include <string> +#include "const_array.hpp" + namespace cxxstdio { inline __attribute__((format(printf, 2, 0))) @@ -58,16 +60,20 @@ namespace cxxstdio return vfscanf(in, fmt, ap); } +#if 0 inline __attribute__((format(scanf, 2, 0))) int do_vscan(const char *in, const char *fmt, va_list ap) { return vsscanf(in, fmt, ap); } +#else + int do_vscan(const char *in, const char *fmt, va_list ap) = delete; +#endif inline __attribute__((format(scanf, 2, 0))) int do_vscan(const std::string& in, const char *fmt, va_list ap) { - return do_vscan(in.c_str(), fmt, ap); + return vsscanf(in.c_str(), fmt, ap); } @@ -109,11 +115,63 @@ namespace cxxstdio return v; } +#if 0 + template<class E> + constexpr + E get_enum_min_value(decltype(E::min_value)) + { + return E::min_value; + } + template<class E> + constexpr + E get_enum_min_value(E def) + { + return def; + } + + template<class E> + constexpr + E get_enum_max_value(decltype(E::max_value)) + { + return E::max_value; + } + template<class E> + constexpr + E get_enum_max_value(E def) + { + return def; + } +#else + template<class E> + constexpr + E get_enum_min_value(E) + { + return E::min_value; + } + template<class E> + constexpr + E get_max_value(E) + { + return E::max_value; + } +#endif + template<class E> class EnumConverter { E& out; typedef typename underlying_type<E>::type U; +#if 0 + constexpr static + U min_value = U(get_enum_min_value<E>(E(std::numeric_limits<U>::min()))); + constexpr static + U max_value = U(get_enum_max_value<E>(E(std::numeric_limits<U>::max()))); +#else + constexpr static + U min_value = U(get_enum_min_value(E())); + constexpr static + U max_value = U(get_enum_max_value(E())); +#endif U mid; public: EnumConverter(E& e) @@ -121,7 +179,10 @@ namespace cxxstdio {} ~EnumConverter() { - if (U(E::min_value) <= mid && mid <= U(E::max_value)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" + if (min_value <= mid && mid <= max_value) +#pragma GCC diagnostic pop out = E(mid); } U *operator &() @@ -201,30 +262,40 @@ namespace cxxstdio } }; -#define FPRINTF(file, fmt, args...) \ - ({ \ - struct format_impl \ - { \ - constexpr static \ - const char *print_format() { return fmt; } \ - }; \ - cxxstdio::PrintFormatter<format_impl>::print(file, args); \ - }) - -#define FSCANF(file, fmt, args...) \ - ({ \ - struct format_impl \ - { \ - constexpr static \ - const char *scan_format() { return fmt; } \ - }; \ - cxxstdio::ScanFormatter<format_impl>::scan(file, args); \ - }) - -#define PRINTF(fmt, args...) FPRINTF(stdout, fmt, args) -#define STRPRINTF(str, fmt, args...) FPRINTF(str, fmt, args) -#define SCANF(fmt, args...) FSCANF(stdin, fmt, args) -#define SSCANF(str, fmt, args...) FSCANF(str, fmt, args) +#define FPRINTF(file, fmt, args...) \ + ([&]() -> int \ + { \ + struct format_impl \ + { \ + constexpr static \ + const char *print_format() { return fmt; } \ + }; \ + return cxxstdio::PrintFormatter<format_impl>::print(file, ## args);\ + }()) + +#define FSCANF(file, fmt, args...) \ + ([&]() -> int \ + { \ + struct format_impl \ + { \ + constexpr static \ + const char *scan_format() { return fmt; } \ + }; \ + return cxxstdio::ScanFormatter<format_impl>::scan(file, ## args); \ + }()) + +#define PRINTF(fmt, args...) FPRINTF(stdout, fmt, ## args) +#define SPRINTF(str, fmt, args...) FPRINTF(str, fmt, ## args) +#define SCANF(fmt, args...) FSCANF(stdin, fmt, ## args) +#define SSCANF(str, fmt, args...) FSCANF(str, fmt, ## args) + +#define STRPRINTF(fmt, args...) \ + ([&]() -> std::string \ + { \ + std::string _out_impl; \ + SPRINTF(_out_impl, fmt, ## args); \ + return _out_impl; \ + }()) } // namespace cxxstdio |