Skip to content

Commit 6577c58

Browse files
committed
Merge pull request #357 from RcppCore/feature/updated-tinyformat
refreshed tinyformat.h against upstream, keeping local mods (closes #356)
2 parents 7c6ac5b + f23cc20 commit 6577c58

File tree

1 file changed

+33
-8
lines changed

1 file changed

+33
-8
lines changed

inst/include/Rcpp/utils/tinyformat.h

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
157178
namespace tinyformat {
158179

159180
//------------------------------------------------------------------------------
@@ -203,7 +224,7 @@ template<int n> struct is_wchar<wchar_t[n]> {};
203224
template<typename T, typename fmtT, bool convertible = is_convertible<T, fmtT>::value>
204225
struct 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)
540561
inline 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

Comments
 (0)