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) {
template<class...Ts>
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) {
toAppend(v, getLastElement(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
......@@ -726,15 +756,15 @@ toAppendDelim(const Delimiter& delim, const T& v, Tgt* tgt) {
/**
* Append to string with a delimiter in between elements.
*/
template <class Delimiter, class T, class... Ts>
typename std::enable_if<sizeof...(Ts) >= 2
template <class Delimiter, class... Ts>
typename std::enable_if<sizeof...(Ts) >= 3
&& IsSomeString<
typename std::remove_pointer<
typename detail::last_element<Ts...>::type
>::type>::value>::type
toAppendDelim(const Delimiter& delim, const T& v, const Ts&... vs) {
toAppend(v, delim, detail::getLastElement(vs...));
toAppendDelim(delim, vs...);
toAppendDelim(const Delimiter& delim, const Ts&... vs) {
detail::reserveInTargetDelim(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