@@ -128,6 +128,10 @@ namespace Rcpp {
128128}
129129#define TINYFORMAT_ERROR (REASON ) ::Rcpp::stop(REASON)
130130
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+
131135// don't use C++11 features (support older compilers)
132136#define TINYFORMAT_NO_VARIADIC_TEMPLATES
133137
@@ -148,12 +152,29 @@ namespace Rcpp {
148152# endif
149153#endif
150154
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+
151164#if defined(__GLIBCXX__) && __GLIBCXX__ < 20080201
152165// std::showpos is broken on old libstdc++ as provided with OSX. See
153166// http://gcc.gnu.org/ml/libstdc++/2007-11/msg00075.html
154167# define TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND
155168#endif
156169
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+
157178namespace tinyformat {
158179
159180// ------------------------------------------------------------------------------
@@ -203,7 +224,7 @@ template<int n> struct is_wchar<wchar_t[n]> {};
203224template <typename T, typename fmtT, bool convertible = is_convertible<T, fmtT>::value>
204225struct formatValueAsType
205226{
206- static void invoke (std::ostream& /* out*/ , const T& /* value*/ ) {}
227+ static void invoke (std::ostream& /* out*/ , const T& /* value*/ ) { /* assert(0); */ }
207228};
208229// Specialized version for types that can actually be converted to fmtT, as
209230// indicated by the "convertible" template parameter.
@@ -311,8 +332,8 @@ inline void formatValue(std::ostream& out, const char* /*fmtBegin*/,
311332 // void* respectively and format that instead of the value itself. For the
312333 // %p conversion it's important to avoid dereferencing the pointer, which
313334 // 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;
316337 if (canConvertToChar && *(fmtEnd-1 ) == ' c' )
317338 detail::formatValueAsType<T, char >::invoke (out, value);
318339 else if (canConvertToVoidPtr && *(fmtEnd-1 ) == ' p' )
@@ -502,14 +523,14 @@ class FormatArg
502523
503524 private:
504525 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,
506527 const char * fmtEnd, int ntrunc, const void * value)
507528 {
508529 formatValue (out, fmtBegin, fmtEnd, ntrunc, *static_cast <const T*>(value));
509530 }
510531
511532 template <typename T>
512- static int toIntImpl (const void * value)
533+ TINYFORMAT_HIDDEN static int toIntImpl (const void * value)
513534 {
514535 return convertToInt<T>::invoke (*static_cast <const T*>(value));
515536 }
@@ -540,7 +561,7 @@ inline int parseIntAndAdvance(const char*& c)
540561inline const char * printFormatStringLiteral (std::ostream& out, const char * fmt)
541562{
542563 const char * c = fmt;
543- for (; true ; ++c)
564+ for (;; ++c)
544565 {
545566 switch (*c)
546567 {
@@ -848,7 +869,7 @@ class FormatListN : public FormatList
848869 template <typename ... Args>
849870 FormatListN (const Args&... args)
850871 : FormatList(&m_formatterStore[0 ], N),
851- m_formatterStore{ FormatArg (args)...}
872+ m_formatterStore TINYFORMAT_BRACED_INIT_WORKAROUND({ FormatArg (args)... })
852873 { static_assert (sizeof ...(args) == N, " Number of args must be N" ); }
853874#else // C++98 version
854875 void init (int ) {}
@@ -857,7 +878,7 @@ class FormatListN : public FormatList
857878 template <TINYFORMAT_ARGTYPES(n)> \
858879 FormatListN (TINYFORMAT_VARARGS(n)) \
859880 : FormatList(&m_formatterStore[0 ], n) \
860- { init (0 , TINYFORMAT_PASSARGS (n)); } \
881+ {/* assert*n == N); */ init (0 , TINYFORMAT_PASSARGS (n)); } \
861882 \
862883 template <TINYFORMAT_ARGTYPES(n)> \
863884 void init (int i, TINYFORMAT_VARARGS(n)) \
@@ -871,7 +892,11 @@ class FormatListN : public FormatList
871892#endif
872893
873894 private:
895+ #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES
896+ std::array<FormatArg, N> m_formatterStore;
897+ #else // C++98 version
874898 FormatArg m_formatterStore[N];
899+ #endif
875900};
876901
877902// Special 0-arg version - MSVC says zero-sized C array in struct is nonstandard
0 commit comments