Commit 6bd1d409 authored by Peter Griess's avatar Peter Griess

Avoid static_assert in tuple_element for Clang/libc++

Summary:
- Clang/libc++ has a static_assert that blows when tuple_element is
invoked with a tuple of length 0. Unfortunately if we embed this
construct in an enable_if, it still gets evaluated. To work around
this, wrap this in a last_element struct and specialize the 0-element
case there explicitly.

Test Plan:
- fbconfig -r folly && fbmake runtests
- ./configure && make check on Ubuntu/FC/Mac

Reviewed By: andrei.alexandrescu@fb.com

FB internal diff: D998591
parent 3b3fa008
......@@ -122,6 +122,23 @@ typename std::tuple_element<
return getLastElement(vs...);
}
// This class exists to specialize away std::tuple_element in the case where we
// have 0 template arguments. Without this, Clang/libc++ will blow a
// static_assert even if tuple_element is protected by an enable_if.
template <class... Ts>
struct last_element {
typedef typename std::enable_if<
sizeof...(Ts) >= 1,
typename std::tuple_element<
sizeof...(Ts) - 1, std::tuple<Ts...>
>::type>::type type;
};
template <>
struct last_element<> {
typedef void type;
};
} // namespace detail
/*******************************************************************************
......@@ -459,9 +476,8 @@ template <class T, class... Ts>
typename std::enable_if<sizeof...(Ts) >= 2
&& detail::IsSomeString<
typename std::remove_pointer<
typename std::tuple_element<
sizeof...(Ts) - 1, std::tuple<Ts...>
>::type>::type>::value>::type
typename detail::last_element<Ts...>::type
>::type>::value>::type
toAppend(const T& v, const Ts&... vs) {
toAppend(v, detail::getLastElement(vs...));
toAppend(vs...);
......@@ -499,9 +515,8 @@ template <class Delimiter, class T, class... Ts>
typename std::enable_if<sizeof...(Ts) >= 2
&& detail::IsSomeString<
typename std::remove_pointer<
typename std::tuple_element<
sizeof...(Ts) - 1, std::tuple<Ts...>
>::type>::type>::value>::type
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...);
......
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