fix for what appears to be an clang/llvm miscompilation

This commit is contained in:
arvidn 2017-06-03 20:02:50 +02:00 committed by Arvid Norberg
parent e38887cb3c
commit 700befc98a
2 changed files with 45 additions and 17 deletions

View File

@ -47,8 +47,36 @@ namespace libtorrent { namespace aux {
using base = span<T>;
using underlying_index = typename underlying_index_t<IndexType>::type;
// pull in constructors from base class
using base::base;
// disallow conversions from other index types
template <typename OtherIndex>
typed_span(typed_span<T, OtherIndex> const&) = delete;
typed_span() noexcept = default;
typed_span(typed_span const&) noexcept = default;
typed_span& operator=(typed_span const&) noexcept = default;
template <typename U, typename
= typename std::enable_if<aux::compatible_type<U, T>::value>::type>
typed_span(typed_span<U> const& v) noexcept // NOLINT
: span<T>(v) {}
typed_span(T& p) noexcept : span<T>(p) {} // NOLINT
typed_span(T* p, std::size_t const l) noexcept : span<T>(p, l) {} // NOLINT
template <typename U, std::size_t N>
typed_span(std::array<U, N>& arr) noexcept // NOLINT
: span<T>(arr.data(), arr.size()) {}
template <typename U, std::size_t N>
typed_span(U (&arr)[N]) noexcept // NOLINT
: span<T>(&arr[0], N) {}
// anything with a .data() member function is considered a container
// but only if the value type is compatible with T
template <typename Cont
, typename U = typename std::remove_reference<decltype(*std::declval<Cont>().data())>::type
, typename = typename std::enable_if<aux::compatible_type<U, T>::value>::type>
typed_span(Cont& c) : span<T>(c.data(), c.size())// NOLINT
{}
auto operator[](IndexType idx) const ->
#if TORRENT_AUTO_RETURN_TYPES

View File

@ -64,22 +64,22 @@ namespace aux {
template <typename T>
struct span
{
span() : m_ptr(nullptr), m_len(0) {}
span() noexcept : m_ptr(nullptr), m_len(0) {}
template <typename U, typename
= typename std::enable_if<aux::compatible_type<U, T>::value>::type>
span(span<U> const& v) // NOLINT
span(span<U> const& v) noexcept // NOLINT
: m_ptr(v.data()), m_len(v.size()) {}
span(T& p) : m_ptr(&p), m_len(1) {} // NOLINT
span(T* p, std::size_t const l) : m_ptr(p), m_len(l) {} // NOLINT
span(T& p) noexcept : m_ptr(&p), m_len(1) {} // NOLINT
span(T* p, std::size_t const l) noexcept : m_ptr(p), m_len(l) {} // NOLINT
template <typename U, std::size_t N>
span(std::array<U, N>& arr) // NOLINT
span(std::array<U, N>& arr) noexcept // NOLINT
: m_ptr(arr.data()), m_len(arr.size()) {}
template <typename U, std::size_t N>
span(U (&arr)[N]) // NOLINT
span(U (&arr)[N]) noexcept // NOLINT
: m_ptr(&arr[0]), m_len(N) {}
// anything with a .data() member function is considered a container
@ -90,20 +90,20 @@ namespace aux {
span(Cont& c) // NOLINT
: m_ptr(c.data()), m_len(c.size()) {}
std::size_t size() const { return m_len; }
bool empty() const { return m_len == 0; }
T* data() const { return m_ptr; }
std::size_t size() const noexcept { return m_len; }
bool empty() const noexcept { return m_len == 0; }
T* data() const noexcept { return m_ptr; }
using iterator = T*;
using reverse_iterator = std::reverse_iterator<T*>;
T* begin() const { return m_ptr; }
T* end() const { return m_ptr + m_len; }
reverse_iterator rbegin() const { return reverse_iterator(end()); }
reverse_iterator rend() const { return reverse_iterator(begin()); }
T* begin() const noexcept { return m_ptr; }
T* end() const noexcept { return m_ptr + m_len; }
reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
T& front() const { TORRENT_ASSERT(m_len > 0); return m_ptr[0]; }
T& back() const { TORRENT_ASSERT(m_len > 0); return m_ptr[m_len - 1]; }
T& front() const noexcept { TORRENT_ASSERT(m_len > 0); return m_ptr[0]; }
T& back() const noexcept { TORRENT_ASSERT(m_len > 0); return m_ptr[m_len - 1]; }
span<T> first(std::size_t const n) const
{