@@ -128,6 +128,10 @@ namespace Rcpp {
128
128
}
129
129
#define TINYFORMAT_ERROR (REASON ) ::Rcpp::stop(REASON)
130
130
131
+ // Define for C++11 variadic templates which make the code shorter & more
132
+ // general. If you don't define this, C++11 support is autodetected below.
133
+ // #define TINYFORMAT_USE_VARIADIC_TEMPLATES
134
+
131
135
// don't use C++11 features (support older compilers)
132
136
#define TINYFORMAT_NO_VARIADIC_TEMPLATES
133
137
@@ -148,12 +152,29 @@ namespace Rcpp {
148
152
# endif
149
153
#endif
150
154
155
+ #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES
156
+ # include < array>
157
+ # if defined(_MSC_VER) && _MSC_VER <= 1800 // VS2013
158
+ # define TINYFORMAT_BRACED_INIT_WORKAROUND (x ) (x)
159
+ # else
160
+ # define TINYFORMAT_BRACED_INIT_WORKAROUND (x ) {x}
161
+ # endif
162
+ #endif
163
+
151
164
#if defined(__GLIBCXX__) && __GLIBCXX__ < 20080201
152
165
// std::showpos is broken on old libstdc++ as provided with OSX. See
153
166
// http://gcc.gnu.org/ml/libstdc++/2007-11/msg00075.html
154
167
# define TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND
155
168
#endif
156
169
170
+ #ifdef __APPLE__
171
+ // Workaround OSX linker warning: xcode uses different default symbol
172
+ // visibilities for static libs vs executables (see issue #25)
173
+ # define TINYFORMAT_HIDDEN __attribute__ ((visibility(" hidden" )))
174
+ #else
175
+ # define TINYFORMAT_HIDDEN
176
+ #endif
177
+
157
178
namespace tinyformat {
158
179
159
180
// ------------------------------------------------------------------------------
@@ -203,7 +224,7 @@ template<int n> struct is_wchar<wchar_t[n]> {};
203
224
template <typename T, typename fmtT, bool convertible = is_convertible<T, fmtT>::value>
204
225
struct formatValueAsType
205
226
{
206
- static void invoke (std::ostream& /* out*/ , const T& /* value*/ ) {}
227
+ static void invoke (std::ostream& /* out*/ , const T& /* value*/ ) { /* assert(0); */ }
207
228
};
208
229
// Specialized version for types that can actually be converted to fmtT, as
209
230
// indicated by the "convertible" template parameter.
@@ -311,8 +332,8 @@ inline void formatValue(std::ostream& out, const char* /*fmtBegin*/,
311
332
// void* respectively and format that instead of the value itself. For the
312
333
// %p conversion it's important to avoid dereferencing the pointer, which
313
334
// could otherwise lead to a crash when printing a dangling (const char*).
314
- const bool canConvertToChar = detail::is_convertible<T,char >::value;
315
- const bool canConvertToVoidPtr = detail::is_convertible<T, const void *>::value;
335
+ bool canConvertToChar = detail::is_convertible<T,char >::value;
336
+ bool canConvertToVoidPtr = detail::is_convertible<T, const void *>::value;
316
337
if (canConvertToChar && *(fmtEnd-1 ) == ' c' )
317
338
detail::formatValueAsType<T, char >::invoke (out, value);
318
339
else if (canConvertToVoidPtr && *(fmtEnd-1 ) == ' p' )
@@ -502,14 +523,14 @@ class FormatArg
502
523
503
524
private:
504
525
template <typename T>
505
- static void formatImpl (std::ostream& out, const char * fmtBegin,
526
+ TINYFORMAT_HIDDEN static void formatImpl (std::ostream& out, const char * fmtBegin,
506
527
const char * fmtEnd, int ntrunc, const void * value)
507
528
{
508
529
formatValue (out, fmtBegin, fmtEnd, ntrunc, *static_cast <const T*>(value));
509
530
}
510
531
511
532
template <typename T>
512
- static int toIntImpl (const void * value)
533
+ TINYFORMAT_HIDDEN static int toIntImpl (const void * value)
513
534
{
514
535
return convertToInt<T>::invoke (*static_cast <const T*>(value));
515
536
}
@@ -540,7 +561,7 @@ inline int parseIntAndAdvance(const char*& c)
540
561
inline const char * printFormatStringLiteral (std::ostream& out, const char * fmt)
541
562
{
542
563
const char * c = fmt;
543
- for (; true ; ++c)
564
+ for (;; ++c)
544
565
{
545
566
switch (*c)
546
567
{
@@ -848,7 +869,7 @@ class FormatListN : public FormatList
848
869
template <typename ... Args>
849
870
FormatListN (const Args&... args)
850
871
: FormatList(&m_formatterStore[0 ], N),
851
- m_formatterStore{ FormatArg (args)...}
872
+ m_formatterStore TINYFORMAT_BRACED_INIT_WORKAROUND({ FormatArg (args)... })
852
873
{ static_assert (sizeof ...(args) == N, " Number of args must be N" ); }
853
874
#else // C++98 version
854
875
void init (int ) {}
@@ -857,7 +878,7 @@ class FormatListN : public FormatList
857
878
template <TINYFORMAT_ARGTYPES(n)> \
858
879
FormatListN (TINYFORMAT_VARARGS(n)) \
859
880
: FormatList(&m_formatterStore[0 ], n) \
860
- { init (0 , TINYFORMAT_PASSARGS (n)); } \
881
+ {/* assert*n == N); */ init (0 , TINYFORMAT_PASSARGS (n)); } \
861
882
\
862
883
template <TINYFORMAT_ARGTYPES(n)> \
863
884
void init (int i, TINYFORMAT_VARARGS(n)) \
@@ -871,7 +892,11 @@ class FormatListN : public FormatList
871
892
#endif
872
893
873
894
private:
895
+ #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES
896
+ std::array<FormatArg, N> m_formatterStore;
897
+ #else // C++98 version
874
898
FormatArg m_formatterStore[N];
899
+ #endif
875
900
};
876
901
877
902
// Special 0-arg version - MSVC says zero-sized C array in struct is nonstandard
0 commit comments