From c080e504e4d74027b985b1ed675c172c083cea76 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Thu, 27 Dec 2012 21:23:46 -0800 Subject: Use cxxstdio --- src/common/cxxstdio.hpp | 123 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 97 insertions(+), 26 deletions(-) (limited to 'src/common/cxxstdio.hpp') 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 +#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 + constexpr + E get_enum_min_value(decltype(E::min_value)) + { + return E::min_value; + } + template + constexpr + E get_enum_min_value(E def) + { + return def; + } + + template + constexpr + E get_enum_max_value(decltype(E::max_value)) + { + return E::max_value; + } + template + constexpr + E get_enum_max_value(E def) + { + return def; + } +#else + template + constexpr + E get_enum_min_value(E) + { + return E::min_value; + } + template + constexpr + E get_max_value(E) + { + return E::max_value; + } +#endif + template class EnumConverter { E& out; typedef typename underlying_type::type U; +#if 0 + constexpr static + U min_value = U(get_enum_min_value(E(std::numeric_limits::min()))); + constexpr static + U max_value = U(get_enum_max_value(E(std::numeric_limits::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::print(file, args); \ - }) - -#define FSCANF(file, fmt, args...) \ - ({ \ - struct format_impl \ - { \ - constexpr static \ - const char *scan_format() { return fmt; } \ - }; \ - cxxstdio::ScanFormatter::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::print(file, ## args);\ + }()) + +#define FSCANF(file, fmt, args...) \ + ([&]() -> int \ + { \ + struct format_impl \ + { \ + constexpr static \ + const char *scan_format() { return fmt; } \ + }; \ + return cxxstdio::ScanFormatter::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 -- cgit v1.2.3-70-g09d2