Commit e339df03 authored by Dominik Charousset's avatar Dominik Charousset

Work around broken libc++ even when using Clang

Use a SFINAE check to detect a broken STL without relying on compiler
identification. Relates #685.
parent df20c706
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "caf/config.hpp" #include "caf/config.hpp"
#include "caf/detail/comparable.hpp" #include "caf/detail/comparable.hpp"
#include "caf/detail/type_traits.hpp"
namespace caf { namespace caf {
namespace detail { namespace detail {
...@@ -271,17 +272,29 @@ private: ...@@ -271,17 +272,29 @@ private:
// GCC < 4.9 has a broken STL: vector::erase accepts iterator instead of // GCC < 4.9 has a broken STL: vector::erase accepts iterator instead of
// const_iterator. // const_iterator.
// TODO: remove when dropping support for GCC 4.8. // TODO: remove when dropping support for GCC 4.8.
#if defined(CAF_GCC) && CAF_COMPILER_VERSION < 49000 template <class Iter>
iterator gcc48_iterator_workaround(const_iterator i) { struct is_valid_erase_iter {
template <class U>
static auto sfinae(U* x) -> decltype(std::declval<vector_type&>().erase(*x),
std::true_type{});
template <class U>
static auto sfinae(...) -> std::false_type;
static constexpr bool value = decltype(sfinae<Iter>(nullptr))::value;
};
template <class I, class E = enable_if_t<!is_valid_erase_iter<I>::value>>
iterator gcc48_iterator_workaround(I i) {
auto j = begin(); auto j = begin();
std::advance(j, std::distance(cbegin(), i)); std::advance(j, std::distance(cbegin(), i));
return j; return j;
} }
#else
const_iterator gcc48_iterator_workaround(const_iterator i) { template <class I, class E = enable_if_t<is_valid_erase_iter<I>::value>>
const_iterator gcc48_iterator_workaround(I i) {
return i; return i;
} }
#endif
vector_type xs_; vector_type xs_;
}; };
......
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