summaryrefslogtreecommitdiff
path: root/src/io/cxxstdio.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/io/cxxstdio.hpp')
-rw-r--r--src/io/cxxstdio.hpp133
1 files changed, 34 insertions, 99 deletions
diff --git a/src/io/cxxstdio.hpp b/src/io/cxxstdio.hpp
index 66419df..20d3a33 100644
--- a/src/io/cxxstdio.hpp
+++ b/src/io/cxxstdio.hpp
@@ -1,6 +1,5 @@
-#ifndef TMWA_IO_CXXSTDIO_HPP
-#define TMWA_IO_CXXSTDIO_HPP
-// cxxstdio.hpp - pass C++ types through scanf/printf
+#pragma once
+// cxxstdio.hpp - pass C++ types through printf
//
// Copyright © 2011-2013 Ben Longbons <b.r.longbons@gmail.com>
//
@@ -19,44 +18,29 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-# include "../sanity.hpp"
+#include "fwd.hpp"
-# include <cstdarg>
-# include <cstdio>
+#include <cstdarg>
+#include <cstdio>
-# include "../compat/cast.hpp"
+#include "../compat/cast.hpp"
-# include "../generic/enum.hpp"
+#include "../generic/enum.hpp"
-# include "fwd.hpp"
+#include "../diagnostics.hpp"
+namespace tmwa
+{
namespace cxxstdio
{
- // other implementations of do_vprint or do_vscan are injected by ADL.
+ // other implementations of do_vprint are injected by ADL.
inline __attribute__((format(printf, 2, 0)))
int do_vprint(FILE *out, const char *fmt, va_list ap)
{
return vfprintf(out, fmt, ap);
}
- inline __attribute__((format(scanf, 2, 0)))
- int do_vscan(FILE *in, const char *fmt, va_list ap)
- {
- 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
- inline
- int do_vscan(const char *, const char *, va_list) = delete;
-# endif
-
template<class T>
inline __attribute__((format(printf, 2, 3)))
int do_print(T&& t, const char *fmt, ...)
@@ -69,19 +53,6 @@ namespace cxxstdio
return rv;
}
- template<class T>
- inline __attribute__((format(scanf, 2, 3)))
- int do_scan(T&& t, const char *fmt, ...)
- {
- int rv;
- va_list ap;
- va_start(ap, fmt);
- rv = do_vscan(std::forward<T>(t), fmt, ap);
- va_end(ap);
- return rv;
- }
-
-
template<class T, typename=typename std::enable_if<!std::is_class<T>::value>::type>
typename remove_enum<T>::type decay_for_printf(T v)
{
@@ -95,13 +66,10 @@ namespace cxxstdio
return std::forward<T>(v);
}
- template<class T, typename = typename std::enable_if<!std::is_enum<T>::value>::type>
- T& convert_for_scanf(T& v)
- {
- return v;
- }
+ inline
+ const char *convert_for_printf(const char *) = delete;
-# if 0
+#if 0
template<class E>
constexpr
E get_enum_min_value(decltype(E::min_value))
@@ -127,7 +95,7 @@ namespace cxxstdio
{
return def;
}
-# else
+#else
template<class E>
constexpr
E get_enum_min_value(E)
@@ -140,24 +108,24 @@ namespace cxxstdio
{
return E::max_value;
}
-# endif
+#endif
template<class E>
class EnumConverter
{
E& out;
typedef typename underlying_type<E>::type U;
-# if 0
+#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
+#else
constexpr static
U min_value = U(get_enum_min_value(E()));
constexpr static
U max_value = U(get_enum_max_value(E()));
-# endif
+#endif
U mid;
public:
EnumConverter(E& e)
@@ -165,11 +133,13 @@ namespace cxxstdio
{}
~EnumConverter()
{
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wtype-limits"
+ DIAG_PUSH();
+ DIAG_I(type_limits);
if (min_value <= mid && mid <= max_value)
-# pragma GCC diagnostic pop
+ {
+ DIAG_POP();
out = E(mid);
+ }
}
U *operator &()
{
@@ -177,12 +147,6 @@ namespace cxxstdio
}
};
- template<class T, typename = typename std::enable_if<std::is_enum<T>::value>::type>
- EnumConverter<T> convert_for_scanf(T& v)
- {
- return v;
- }
-
template<class Format>
class PrintFormatter
{
@@ -192,63 +156,35 @@ namespace cxxstdio
int print(T&& t, A&&... a)
{
constexpr static
- const char *print_format = Format::print_format();
+ const char *print_format = Format::print_format().format_string();
return do_print(std::forward<T>(t), print_format,
decay_for_printf(convert_for_printf(std::forward<A>(a)))...);
}
};
- template<class Format>
- class ScanFormatter
- {
- public:
- template<class T, class... A>
- static
- int scan(T&& t, A&&... a)
- {
- constexpr static
- const char *scan_format = Format::scan_format();
- return do_scan(std::forward<T>(t), scan_format,
- &convert_for_scanf(*a)...);
- }
- };
-
-# define XPRINTF(out, fmt, ...) \
+#define XPRINTF(out, fmt, ...) \
({ \
struct format_impl \
{ \
constexpr static \
- const char *print_format() { return fmt; } \
+ FormatString print_format() { return fmt; } \
}; \
cxxstdio::PrintFormatter<format_impl>::print(out, ## __VA_ARGS__); \
})
-# define XSCANF(out, fmt, ...) \
- ({ \
- struct format_impl \
- { \
- constexpr static \
- const char *scan_format() { return fmt; } \
- }; \
- cxxstdio::ScanFormatter<format_impl>::scan(out, ## __VA_ARGS__); \
- })
-
-# define FPRINTF(file, fmt, ...) XPRINTF(/*no_cast<FILE *>*/(file), fmt, ## __VA_ARGS__)
-# define FSCANF(file, fmt, ...) XSCANF(no_cast<FILE *>(file), fmt, ## __VA_ARGS__)
-# define PRINTF(fmt, ...) FPRINTF(stdout, fmt, ## __VA_ARGS__)
-# define SPRINTF(str, fmt, ...) XPRINTF(base_cast<AString&>(str), fmt, ## __VA_ARGS__)
-# define SNPRINTF(str, n, fmt, ...) XPRINTF(base_cast<VString<n-1>&>(str), fmt, ## __VA_ARGS__)
-# define SCANF(fmt, ...) FSCANF(stdin, fmt, ## __VA_ARGS__)
-# define SSCANF(str, fmt, ...) XSCANF(maybe_cast<ZString>(str), fmt, ## __VA_ARGS__)
+#define FPRINTF(file, fmt, ...) XPRINTF(/*no_cast<FILE *>*/(file), fmt, ## __VA_ARGS__)
+#define PRINTF(fmt, ...) FPRINTF(stdout, fmt, ## __VA_ARGS__)
+#define SPRINTF(str, fmt, ...) XPRINTF(base_cast<AString&>(str), fmt, ## __VA_ARGS__)
+#define SNPRINTF(str, n, fmt, ...) XPRINTF(base_cast<VString<n-1>&>(str), fmt, ## __VA_ARGS__)
-# define STRPRINTF(fmt, ...) \
+#define STRPRINTF(fmt, ...) \
({ \
AString _out_impl; \
SPRINTF(_out_impl, fmt, ## __VA_ARGS__); \
_out_impl; \
})
-# define STRNPRINTF(n, fmt, ...) \
+#define STRNPRINTF(n, fmt, ...) \
({ \
VString<n - 1> _out_impl; \
SNPRINTF(_out_impl, n, fmt, ## __VA_ARGS__); \
@@ -256,5 +192,4 @@ namespace cxxstdio
})
} // namespace cxxstdio
-
-#endif // TMWA_IO_CXXSTDIO_HPP
+} // namespace tmwa