Commit 46e3ed29 authored by Marcin Pawlowski's avatar Marcin Pawlowski Committed by Sara Golemon

made toAppendDelim better

Summary:
preallocate once and for all, so that we
are really malloc efficient in toAppendDelim

Test Plan: unit tests

Reviewed By: marcelo.juchem@fb.com

FB internal diff: D1496310

Tasks: 4886092
parent 1cab639b
...@@ -655,7 +655,14 @@ size_t estimateSpaceToReserve(size_t sofar, const T& v) { ...@@ -655,7 +655,14 @@ size_t estimateSpaceToReserve(size_t sofar, const T& v) {
template<class...Ts> template<class...Ts>
void reserveInTarget(const Ts&...vs) { void reserveInTarget(const Ts&...vs) {
getLastElement(vs...)->reserve(detail::estimateSpaceToReserve(0, vs...)); getLastElement(vs...)->reserve(estimateSpaceToReserve(0, vs...));
}
template<class Delimiter, class...Ts>
void reserveInTargetDelim(const Delimiter& d, const Ts&...vs) {
static_assert(sizeof...(vs) >= 2, "Needs at least 2 args");
size_t fordelim = (sizeof...(vs) - 2) * estimateSpaceToReserve(0, d);
getLastElement(vs...)->reserve(estimateSpaceToReserve(fordelim, vs...));
} }
/** /**
...@@ -679,6 +686,29 @@ toAppendStrImpl(const T& v, const Ts&... vs) { ...@@ -679,6 +686,29 @@ toAppendStrImpl(const T& v, const Ts&... vs) {
toAppend(v, getLastElement(vs...)); toAppend(v, getLastElement(vs...));
toAppendStrImpl(vs...); toAppendStrImpl(vs...);
} }
template <class Delimiter, class T, class Tgt>
typename std::enable_if<
IsSomeString<typename std::remove_pointer<Tgt>::type>
::value>::type
toAppendDelimStrImpl(const Delimiter& delim, const T& v, Tgt result) {
toAppend(v, result);
}
template <class Delimiter, class T, class... Ts>
typename std::enable_if<sizeof...(Ts) >= 2
&& IsSomeString<
typename std::remove_pointer<
typename detail::last_element<Ts...>::type
>::type>::value>::type
toAppendDelimStrImpl(const Delimiter& delim, const T& v, const Ts&... vs) {
// we are really careful here, calling toAppend with just one element does
// not try to estimate space needed (as we already did that). If we call
// toAppend(v, delim, ....) we would do unnecesary size calculation
toAppend(v, detail::getLastElement(vs...));
toAppend(delim, detail::getLastElement(vs...));
toAppendDelimStrImpl(delim, vs...);
}
} // folly::detail } // folly::detail
...@@ -726,15 +756,15 @@ toAppendDelim(const Delimiter& delim, const T& v, Tgt* tgt) { ...@@ -726,15 +756,15 @@ toAppendDelim(const Delimiter& delim, const T& v, Tgt* tgt) {
/** /**
* Append to string with a delimiter in between elements. * Append to string with a delimiter in between elements.
*/ */
template <class Delimiter, class T, class... Ts> template <class Delimiter, class... Ts>
typename std::enable_if<sizeof...(Ts) >= 2 typename std::enable_if<sizeof...(Ts) >= 3
&& IsSomeString< && IsSomeString<
typename std::remove_pointer< typename std::remove_pointer<
typename detail::last_element<Ts...>::type typename detail::last_element<Ts...>::type
>::type>::value>::type >::type>::value>::type
toAppendDelim(const Delimiter& delim, const T& v, const Ts&... vs) { toAppendDelim(const Delimiter& delim, const Ts&... vs) {
toAppend(v, delim, detail::getLastElement(vs...)); detail::reserveInTargetDelim(delim, vs...);
toAppendDelim(delim, vs...); detail::toAppendDelimStrImpl(delim, vs...);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment