Ticket #6815: main.2.cpp

File main.2.cpp, 1.8 KB (added by d., 11 years ago)
Line 
1#include "templ_literal.h"
2#include <cstddef>
3#include <stdio.h>
4
5template< class >
6struct FormatSupportedType;
7
8#define SUPPORTED_TYPE(C, T) \
9template<> struct FormatSupportedType< T > \
10{ \
11 constexpr static bool supports(char c) \
12 { return ( c == C ); } \
13}
14
15SUPPORTED_TYPE('c', char);
16SUPPORTED_TYPE('d', int);
17
18template< std::size_t N >
19constexpr bool checkFormatHelper( const char (&format)[N], std::size_t current )
20{
21 return
22 current >= N ?
23 true
24 : format[current] != '%' ?
25 checkFormatHelper( format, current + 1 )
26 : format[current + 1] == '%' ?
27 checkFormatHelper( format, current + 2 )
28 :
29 false;
30}
31
32template< std::size_t N, class T, class... Ts >
33constexpr bool checkFormatHelper( const char (&format)[N], std::size_t current, const T& arg, const Ts & ... args )
34{
35 return
36 current >= N ?
37 false
38 : format[current] != '%' ?
39 checkFormatHelper( format, current + 1, arg, args... )
40 : (format[current] == '%' && format[current + 1] == '%') ?
41 checkFormatHelper( format, current + 2, arg, args... )
42 : FormatSupportedType< T >::supports(format[current + 1]) &&
43 checkFormatHelper( format, current + 2, args... );
44}
45
46template< std::size_t N, class... Ts >
47constexpr bool checkFormat( const char (&format)[N], const Ts & ... args )
48{
49 return checkFormatHelper( format, 0, args... );
50}
51
52#define safe_printf_1(FORMAT, ...) \
53 static_assert(checkFormat( FORMAT, __VA_ARGS__ ), "Format is incorrect"); \
54 printf(FORMAT, __VA_ARGS__)
55
56template< char... FORMAT, class... ARGS >
57int safe_printf_2(TemplateLiteral<FORMAT...>, ARGS... args)
58{
59 constexpr char format[] = {FORMAT... , '\0'};
60 static_assert( checkFormat(format, args... ), "Format is incorrect");
61 return printf( format, args... );
62}
63
64int main()
65{
66 safe_printf_1("%c %d", 'x', 257);
67 safe_printf_2(TEMPLATE_LITERAL("%c %d"), 'x', 257);
68}