Skip to content

Commit 651f245

Browse files
committed
Created the cpp98templates.h deprecating the usage of tinyformat.h
for C++ 98 Variadic Template support.
1 parent dff8c59 commit 651f245

File tree

3 files changed

+294
-128
lines changed

3 files changed

+294
-128
lines changed

cpp98templates.h

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
// Copyright (C) 2011, Chris Foster [chris42f (at) gmail (d0t) com]
2+
// Copyright 2020 @ Evandro Coan, https://github.com/evandrocoan
3+
//
4+
// C++ 98 Variadic Templates Support Header Version: 1.0.0
5+
// Always ensure you are using the latest version by checking:
6+
// https://github.com/evandrocoan/cppdebugger
7+
//
8+
// Boost Software License - Version 1.0
9+
//
10+
// Permission is hereby granted, free of charge, to any person or organization
11+
// obtaining a copy of the software and accompanying documentation covered by
12+
// this license (the "Software") to use, reproduce, display, distribute,
13+
// execute, and transmit the Software, and to prepare derivative works of the
14+
// Software, and to permit third-parties to whom the Software is furnished to
15+
// do so, all subject to the following:
16+
//
17+
// The copyright notices in the Software and this entire statement, including
18+
// the above license grant, this restriction and the following disclaimer,
19+
// must be included in all copies of the Software, in whole or in part, and
20+
// all derivative works of the Software, unless such copies or derivative
21+
// works are solely in the form of machine-executable object code generated by
22+
// a source language processor.
23+
//
24+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26+
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
27+
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
28+
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
29+
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30+
// DEALINGS IN THE SOFTWARE.
31+
32+
//------------------------------------------------------------------------------
33+
// Tools for emulating variadic templates in C++98. The basic idea here is
34+
// stolen from the boost preprocessor metaprogramming library and cut down to
35+
// be just general enough for what we need.
36+
37+
#define CPP98VARIADICTEMPLATE_OPEN_PAREN (
38+
#define CPP98VARIADICTEMPLATE_CLOSE_PAREN )
39+
40+
#define CPP98VARIADICTEMPLATE_ARGTYPES(n,begin,end,...) CPP98VARIADICTEMPLATE_ARGTYPES_ ## n (begin,end,__VA_ARGS__)
41+
#define CPP98VARIADICTEMPLATE_VARARGS(n,...) CPP98VARIADICTEMPLATE_VARARGS_ ## n (__VA_ARGS__)
42+
#define CPP98VARIADICTEMPLATE_PASSARGS(n,begin,end,...) CPP98VARIADICTEMPLATE_PASSARGS_ ## n (begin,end,__VA_ARGS__)
43+
44+
// To keep it as transparent as possible, the macros below have been generated
45+
// using python via the excellent cog code generation script. This avoids
46+
// the need for a bunch of complex (but more general) preprocessor tricks as
47+
// used in boost.preprocessor.
48+
//
49+
// To rerun the code generation in place, use `cog -r cpp98templates.h`
50+
// (see http://nedbatchelder.com/code/cog). Alternatively you can just create
51+
// extra versions by hand.
52+
53+
/*[[[cog
54+
maxParams = 16
55+
56+
def makeCommaSepLists(lineTemplate, elemTemplate, startInd=1):
57+
for j in range(startInd,maxParams+1):
58+
list = ', '.join([elemTemplate % {'i':i} for i in range(startInd,j+1)])
59+
cog.outl(lineTemplate % {'j':j, 'list':list})
60+
61+
cog.outl('#define CPP98VARIADICTEMPLATE_ARGTYPES_0(...)')
62+
makeCommaSepLists('#define CPP98VARIADICTEMPLATE_ARGTYPES_%(j)d(begin,end,...) begin __VA_ARGS__ %(list)s end',
63+
'class T%(i)d')
64+
65+
cog.outl()
66+
cog.outl('#define CPP98VARIADICTEMPLATE_VARARGS_0(...)')
67+
makeCommaSepLists('#define CPP98VARIADICTEMPLATE_VARARGS_%(j)d(...) __VA_ARGS__ %(list)s',
68+
'const T%(i)d& v%(i)d')
69+
70+
cog.outl()
71+
cog.outl('#define CPP98VARIADICTEMPLATE_PASSARGS_0(...)')
72+
makeCommaSepLists('#define CPP98VARIADICTEMPLATE_PASSARGS_%(j)d(begin,end,...) __VA_ARGS__ %(list)s', 'begin v%(i)d end')
73+
74+
cog.outl()
75+
cog.outl('#define CPP98VARIADICTEMPLATE_FOREACH_ARGNUM(m) \\\n m(0) ' +
76+
' '.join(['m(%d)' % (j,) for j in range(1,maxParams+1)]))
77+
]]]*/
78+
#define CPP98VARIADICTEMPLATE_ARGTYPES_0(...)
79+
#define CPP98VARIADICTEMPLATE_ARGTYPES_1(begin,end,...) begin __VA_ARGS__ class T1 end
80+
#define CPP98VARIADICTEMPLATE_ARGTYPES_2(begin,end,...) begin __VA_ARGS__ class T1, class T2 end
81+
#define CPP98VARIADICTEMPLATE_ARGTYPES_3(begin,end,...) begin __VA_ARGS__ class T1, class T2, class T3 end
82+
#define CPP98VARIADICTEMPLATE_ARGTYPES_4(begin,end,...) begin __VA_ARGS__ class T1, class T2, class T3, class T4 end
83+
#define CPP98VARIADICTEMPLATE_ARGTYPES_5(begin,end,...) begin __VA_ARGS__ class T1, class T2, class T3, class T4, class T5 end
84+
#define CPP98VARIADICTEMPLATE_ARGTYPES_6(begin,end,...) begin __VA_ARGS__ class T1, class T2, class T3, class T4, class T5, class T6 end
85+
#define CPP98VARIADICTEMPLATE_ARGTYPES_7(begin,end,...) begin __VA_ARGS__ class T1, class T2, class T3, class T4, class T5, class T6, class T7 end
86+
#define CPP98VARIADICTEMPLATE_ARGTYPES_8(begin,end,...) begin __VA_ARGS__ class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8 end
87+
#define CPP98VARIADICTEMPLATE_ARGTYPES_9(begin,end,...) begin __VA_ARGS__ class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9 end
88+
#define CPP98VARIADICTEMPLATE_ARGTYPES_10(begin,end,...) begin __VA_ARGS__ class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10 end
89+
#define CPP98VARIADICTEMPLATE_ARGTYPES_11(begin,end,...) begin __VA_ARGS__ class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11 end
90+
#define CPP98VARIADICTEMPLATE_ARGTYPES_12(begin,end,...) begin __VA_ARGS__ class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12 end
91+
#define CPP98VARIADICTEMPLATE_ARGTYPES_13(begin,end,...) begin __VA_ARGS__ class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13 end
92+
#define CPP98VARIADICTEMPLATE_ARGTYPES_14(begin,end,...) begin __VA_ARGS__ class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14 end
93+
#define CPP98VARIADICTEMPLATE_ARGTYPES_15(begin,end,...) begin __VA_ARGS__ class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 end
94+
#define CPP98VARIADICTEMPLATE_ARGTYPES_16(begin,end,...) begin __VA_ARGS__ class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15, class T16 end
95+
96+
#define CPP98VARIADICTEMPLATE_VARARGS_0(...)
97+
#define CPP98VARIADICTEMPLATE_VARARGS_1(...) __VA_ARGS__ const T1& v1
98+
#define CPP98VARIADICTEMPLATE_VARARGS_2(...) __VA_ARGS__ const T1& v1, const T2& v2
99+
#define CPP98VARIADICTEMPLATE_VARARGS_3(...) __VA_ARGS__ const T1& v1, const T2& v2, const T3& v3
100+
#define CPP98VARIADICTEMPLATE_VARARGS_4(...) __VA_ARGS__ const T1& v1, const T2& v2, const T3& v3, const T4& v4
101+
#define CPP98VARIADICTEMPLATE_VARARGS_5(...) __VA_ARGS__ const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5
102+
#define CPP98VARIADICTEMPLATE_VARARGS_6(...) __VA_ARGS__ const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6
103+
#define CPP98VARIADICTEMPLATE_VARARGS_7(...) __VA_ARGS__ const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7
104+
#define CPP98VARIADICTEMPLATE_VARARGS_8(...) __VA_ARGS__ const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8
105+
#define CPP98VARIADICTEMPLATE_VARARGS_9(...) __VA_ARGS__ const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9
106+
#define CPP98VARIADICTEMPLATE_VARARGS_10(...) __VA_ARGS__ const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10
107+
#define CPP98VARIADICTEMPLATE_VARARGS_11(...) __VA_ARGS__ const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11
108+
#define CPP98VARIADICTEMPLATE_VARARGS_12(...) __VA_ARGS__ const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12
109+
#define CPP98VARIADICTEMPLATE_VARARGS_13(...) __VA_ARGS__ const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13
110+
#define CPP98VARIADICTEMPLATE_VARARGS_14(...) __VA_ARGS__ const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13, const T14& v14
111+
#define CPP98VARIADICTEMPLATE_VARARGS_15(...) __VA_ARGS__ const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13, const T14& v14, const T15& v15
112+
#define CPP98VARIADICTEMPLATE_VARARGS_16(...) __VA_ARGS__ const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13, const T14& v14, const T15& v15, const T16& v16
113+
114+
#define CPP98VARIADICTEMPLATE_PASSARGS_0(...)
115+
#define CPP98VARIADICTEMPLATE_PASSARGS_1(begin,end,...) __VA_ARGS__ begin v1 end
116+
#define CPP98VARIADICTEMPLATE_PASSARGS_2(begin,end,...) __VA_ARGS__ begin v1 end, begin v2 end
117+
#define CPP98VARIADICTEMPLATE_PASSARGS_3(begin,end,...) __VA_ARGS__ begin v1 end, begin v2 end, begin v3 end
118+
#define CPP98VARIADICTEMPLATE_PASSARGS_4(begin,end,...) __VA_ARGS__ begin v1 end, begin v2 end, begin v3 end, begin v4 end
119+
#define CPP98VARIADICTEMPLATE_PASSARGS_5(begin,end,...) __VA_ARGS__ begin v1 end, begin v2 end, begin v3 end, begin v4 end, begin v5 end
120+
#define CPP98VARIADICTEMPLATE_PASSARGS_6(begin,end,...) __VA_ARGS__ begin v1 end, begin v2 end, begin v3 end, begin v4 end, begin v5 end, begin v6 end
121+
#define CPP98VARIADICTEMPLATE_PASSARGS_7(begin,end,...) __VA_ARGS__ begin v1 end, begin v2 end, begin v3 end, begin v4 end, begin v5 end, begin v6 end, begin v7 end
122+
#define CPP98VARIADICTEMPLATE_PASSARGS_8(begin,end,...) __VA_ARGS__ begin v1 end, begin v2 end, begin v3 end, begin v4 end, begin v5 end, begin v6 end, begin v7 end, begin v8 end
123+
#define CPP98VARIADICTEMPLATE_PASSARGS_9(begin,end,...) __VA_ARGS__ begin v1 end, begin v2 end, begin v3 end, begin v4 end, begin v5 end, begin v6 end, begin v7 end, begin v8 end, begin v9 end
124+
#define CPP98VARIADICTEMPLATE_PASSARGS_10(begin,end,...) __VA_ARGS__ begin v1 end, begin v2 end, begin v3 end, begin v4 end, begin v5 end, begin v6 end, begin v7 end, begin v8 end, begin v9 end, begin v10 end
125+
#define CPP98VARIADICTEMPLATE_PASSARGS_11(begin,end,...) __VA_ARGS__ begin v1 end, begin v2 end, begin v3 end, begin v4 end, begin v5 end, begin v6 end, begin v7 end, begin v8 end, begin v9 end, begin v10 end, begin v11 end
126+
#define CPP98VARIADICTEMPLATE_PASSARGS_12(begin,end,...) __VA_ARGS__ begin v1 end, begin v2 end, begin v3 end, begin v4 end, begin v5 end, begin v6 end, begin v7 end, begin v8 end, begin v9 end, begin v10 end, begin v11 end, begin v12 end
127+
#define CPP98VARIADICTEMPLATE_PASSARGS_13(begin,end,...) __VA_ARGS__ begin v1 end, begin v2 end, begin v3 end, begin v4 end, begin v5 end, begin v6 end, begin v7 end, begin v8 end, begin v9 end, begin v10 end, begin v11 end, begin v12 end, begin v13 end
128+
#define CPP98VARIADICTEMPLATE_PASSARGS_14(begin,end,...) __VA_ARGS__ begin v1 end, begin v2 end, begin v3 end, begin v4 end, begin v5 end, begin v6 end, begin v7 end, begin v8 end, begin v9 end, begin v10 end, begin v11 end, begin v12 end, begin v13 end, begin v14 end
129+
#define CPP98VARIADICTEMPLATE_PASSARGS_15(begin,end,...) __VA_ARGS__ begin v1 end, begin v2 end, begin v3 end, begin v4 end, begin v5 end, begin v6 end, begin v7 end, begin v8 end, begin v9 end, begin v10 end, begin v11 end, begin v12 end, begin v13 end, begin v14 end, begin v15 end
130+
#define CPP98VARIADICTEMPLATE_PASSARGS_16(begin,end,...) __VA_ARGS__ begin v1 end, begin v2 end, begin v3 end, begin v4 end, begin v5 end, begin v6 end, begin v7 end, begin v8 end, begin v9 end, begin v10 end, begin v11 end, begin v12 end, begin v13 end, begin v14 end, begin v15 end, begin v16 end
131+
132+
#define CPP98VARIADICTEMPLATE_FOREACH_ARGNUM(m) \
133+
m(0) m(1) m(2) m(3) m(4) m(5) m(6) m(7) m(8) m(9) m(10) m(11) m(12) m(13) m(14) m(15) m(16)
134+
//[[[end]]]

debugger.hpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
// https://github.com/bitcoin/bitcoin/issues/9423 -- tinyformat: Too many conversion specifiers in format string
4848
#define TINYFORMAT_ERROR(reasonString) throw std::runtime_error(reasonString)
4949
#include "tinyformat.h"
50+
#include "cpp98templates.h"
5051

5152
#if defined(TINYFORMAT_USE_VARIADIC_TEMPLATES)
5253
// https://github.com/laanwj/bitcoin/blob/3b092bd9b6b3953d5c3052d57e4827dbd85941fd/src/util.h
@@ -66,12 +67,12 @@
6667

6768
#else
6869
// Create a nth "variadic" template, see `tinyformat.h` variables TINYFORMAT_ARGTYPES_1, 2, 3... etc
69-
#define TINYFORMAT_FORMATTER_CREATE_NTH_FORMAT(n) \
70-
template<class T0 TINYFORMAT_ARGTYPES(n,,,,)> \
71-
inline std::string secure_tinyformat(const T0& v0 TINYFORMAT_VARARGS(n,,)) \
70+
#define CPP98VARIADICTEMPLATE_FORMATTER_CREATE_NTH_FORMAT(n) \
71+
template<class T0 CPP98VARIADICTEMPLATE_ARGTYPES(n,,,,)> \
72+
inline std::string secure_tinyformat(const T0& v0 CPP98VARIADICTEMPLATE_VARARGS(n,,)) \
7273
{ \
7374
try { \
74-
return tfm::format( v0 TINYFORMAT_PASSARGS(n,,,,) ); \
75+
return tfm::format( v0 CPP98VARIADICTEMPLATE_PASSARGS(n,,,,) ); \
7576
} \
7677
catch (std::runtime_error &error) { \
7778
return std::string( error.what() ) + std::string( ": '" ) + std::string( v0 ) + std::string( "'" ); \
@@ -82,9 +83,9 @@
8283
}
8384

8485
// Create the "variadic" templates for C++ 98 from 1 up to the maximum defined on
85-
// `tinyformat.h` variables TINYFORMAT_ARGTYPES_1, 2, 3... etc
86-
TINYFORMAT_FOREACH_ARGNUM(TINYFORMAT_FORMATTER_CREATE_NTH_FORMAT)
87-
#undef TINYFORMAT_FORMATTER_CREATE_NTH_FORMAT
86+
// `tinyformat.h` variables CPP98VARIADICTEMPLATE_ARGTYPES_1, 2, 3... etc
87+
CPP98VARIADICTEMPLATE_FOREACH_ARGNUM(CPP98VARIADICTEMPLATE_FORMATTER_CREATE_NTH_FORMAT)
88+
#undef CPP98VARIADICTEMPLATE_FORMATTER_CREATE_NTH_FORMAT
8889
#endif
8990

9091

0 commit comments

Comments
 (0)