X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FConv.h;h=468d33cb08a74d467b9ed9366499f30aa87dc88e;hb=4d37864c657590b5460ee02eb68fd0b3b22237f7;hp=9fc196965763bfddcfb997c1f1e4b781abd2637c;hpb=89cc32931877aa684e1a1f06776f564a49d39eab;p=folly.git diff --git a/folly/Conv.h b/folly/Conv.h index 9fc19696..468d33cb 100644 --- a/folly/Conv.h +++ b/folly/Conv.h @@ -187,6 +187,33 @@ to(const Src& value) { namespace detail { +#ifdef _MSC_VER +// MSVC can't quite figure out the LastElementImpl::call() stuff +// in the base implementation, so we have to use tuples instead, +// which result in significantly more templates being compiled, +// though the runtime performance is the same. + +template +auto getLastElement(Ts&&... ts) -> decltype( + std::get(std::forward_as_tuple(std::forward(ts)...))) { + return std::get( + std::forward_as_tuple(std::forward(ts)...)); +} + +inline void getLastElement() {} + +template +struct LastElementType : std::tuple_element> {}; + +template <> +struct LastElementType<0> { + using type = void; +}; + +template +struct LastElement + : std::decay::type> {}; +#else template struct LastElementImpl { static void call(Ignored...) {} @@ -210,6 +237,7 @@ template struct LastElement : std::decay::call(std::declval()...))> { }; +#endif } // namespace detail @@ -928,6 +956,27 @@ to(const Ts&... vs) { return result; } +/** + * Special version of to for floating point. When calling + * folly::to(double), generic implementation above will + * firstly reserve 24 (or 25 when negative value) bytes. This will + * introduce a malloc call for most mainstream string implementations. + * + * But for most cases, a floating point doesn't need 24 (or 25) bytes to + * be converted as a string. + * + * This special version will not do string reserve. + */ +template +typename std::enable_if< + IsSomeString::value && std::is_floating_point::value, + Tgt>::type +to(Src value) { + Tgt result; + toAppend(value, &result); + return result; +} + /** * toDelim(SomeString str) returns itself. */