diff --git a/auxi/impl_algo.h b/auxi/impl_algo.h index 62d0be2c..b31384d5 100644 --- a/auxi/impl_algo.h +++ b/auxi/impl_algo.h @@ -7,7 +7,7 @@ #include "contiguous_iterator_to_ptr.h" -#include "range_traits.h" +#include "util.h" // for as_(un)signed #include @@ -38,7 +38,7 @@ namespace oel::_detail { // Dereference to detect out of range errors if the iterator has internal check #if OEL_MEM_BOUND_DEBUG_LVL (void) *src; - (void) *(src + (nElems - 1)); + (void) *(src + (as_signed(nElems) - 1)); #endif std::memcpy(dest, to_pointer_contiguous(src), sizeof(*src) * nElems); } @@ -88,11 +88,11 @@ namespace oel::_detail if constexpr (std::is_trivial_v and sizeof...(Args) == 0) { - std::memset(first, 0, sizeof(T) * (last - first)); + std::memset(first, 0, sizeof(T) * as_unsigned(last - first)); } else if constexpr (isByte) { - std::memset(first, static_cast(args)..., last - first); + std::memset(first, static_cast(args)..., as_unsigned(last - first)); } else { T *const init = first; diff --git a/auxi/range_algo_detail.h b/auxi/range_algo_detail.h index 772de714..0e1e854c 100644 --- a/auxi/range_algo_detail.h +++ b/auxi/range_algo_detail.h @@ -52,8 +52,8 @@ namespace oel::_detail //////////////////////////////////////////////////////////////////////////////// - template< typename InputIter, typename RandomAccessIter > - InputIter CopyUnsf(InputIter src, size_t const n, RandomAccessIter const dest) + template< typename InputIter, typename Integral, typename RandomAccessIter > + InputIter CopyUnsf(InputIter src, Integral const n, RandomAccessIter const dest) { if constexpr (can_memmove_with) { @@ -61,14 +61,14 @@ namespace oel::_detail if (n != 0) { // Dereference to detect out of range errors if the iterator has internal check (void) *dest; - (void) *(dest + (n - 1)); + (void) *(dest + (as_signed(n) - 1)); } #endif - _detail::MemcpyCheck(src, n, to_pointer_contiguous(dest)); - return src + n; + _detail::MemcpyCheck(src, as_unsigned(n), to_pointer_contiguous(dest)); + return src + as_signed(n); } else - { for (size_t i{}; i < n; ++i) + { for (Integral i{}; i < n; ++i) { dest[i] = *src; ++src; diff --git a/dynarray.h b/dynarray.h index d1ee9439..71c09321 100644 --- a/dynarray.h +++ b/dynarray.h @@ -242,17 +242,27 @@ class dynarray T & back() noexcept { return *_detail::MakeDynarrIter (_m, _m.end - 1); } const T & back() const noexcept { return *_detail::MakeDynarrIter(_m, _m.end - 1); } - T & operator[](size_type index) noexcept { OEL_ASSERT(index < size()); return _m.data[index]; } - const T & operator[](size_type index) const noexcept { OEL_ASSERT(index < size()); return _m.data[index]; } + template< typename Integral > + T & operator[](Integral index) noexcept + { + OEL_ASSERT(as_unsigned(index) < size()); + return _m.data[index]; + } + template< typename Integral > + const T & operator[](Integral index) const noexcept + { + OEL_ASSERT(as_unsigned(index) < size()); + return _m.data[index]; + } - T & at(size_type index) OEL_ALWAYS_INLINE + T & at(difference_type index) OEL_ALWAYS_INLINE { const auto & cSelf = *this; return const_cast(cSelf.at(index)); } - const T & at(size_type index) const + const T & at(difference_type index) const { - if (index < size()) // would be unsafe with signed size_type + if (static_cast(index) < size()) return _m.data[index]; else _detail::OutOfRange::raise("Bad index dynarray::at"); @@ -446,7 +456,7 @@ class dynarray } _detail::MemcpyCheck(src, count, _m.data); - return src + count; + return src + as_signed(count); } else { auto cpy = [](InputIter src_, T *__restrict dest, T * dLast) @@ -482,7 +492,7 @@ class dynarray while (_m.end < newEnd) { // each iteration updates _m.end for exception safety _alloTrait::construct(_m, _m.end, *src); - ++src; ++_m.end; + ++_m.end; ++src; } return src; } @@ -509,7 +519,7 @@ class dynarray } OEL_CATCH_ALL { - erase_to_end(begin() + oldSize); + erase_to_end(begin() + as_signed(oldSize)); OEL_RETHROW; } return first; @@ -524,7 +534,7 @@ class dynarray if constexpr (can_memmove_with) { _detail::MemcpyCheck(src, count, _m.end); - src += count; + src += as_signed(count); _m.end += count; } else @@ -555,8 +565,8 @@ class dynarray { auto const newData = _allocateWrap::allocate(_m, newCap); // Exception free from here - auto const nBefore = pos - _m.data; - auto const nAfter = _m.end - pos; + auto const nBefore = as_unsigned(pos - _m.data); + auto const nAfter = as_unsigned(_m.end - pos); T *const newPos = _detail::Relocate(_m.data, nBefore, newData); _m.end = _detail::Relocate(pos, nAfter, newPos + count); @@ -610,7 +620,7 @@ typename dynarray::iterator _alloTrait::construct(_m, reinterpret_cast(&tmp), static_cast(args)...); if (_m.end < _m.reservEnd) { // Relocate [pos, end) to [pos + 1, end + 1) - size_t const bytesAfterPos{sizeof(T) * (_m.end - pPos)}; + auto const bytesAfterPos = sizeof(T) * as_unsigned(_m.end - pPos); std::memmove( static_cast(pPos + 1), static_cast(pPos), @@ -641,7 +651,7 @@ typename dynarray::iterator static_assert( std::is_same_v, "insert_range requires that source models std::ranges::forward_range or that source.size() is valid" ); - size_t const bytesAfterPos{sizeof(T) * (_m.end - pPos)}; + auto const bytesAfterPos = sizeof(T) * as_unsigned(_m.end - pPos); T * dLast; if (_spareCapacity() >= count) { @@ -874,7 +884,7 @@ typename dynarray::iterator dynarray::erase(iterator pos) _ std::memmove( // relocate [pos + 1, end) to [pos, end - 1) static_cast(ptr), static_cast(next), - sizeof(T) * (_m.end - next) ); + sizeof(T) * as_unsigned(_m.end - next) ); --_m.end; } else @@ -900,7 +910,7 @@ typename dynarray::iterator dynarray::erase(iterator first, std::memmove( // relocate [last, end) to [first, first + nAfter) static_cast(dest), static_cast(pLast), - sizeof(T) * nAfter ); + sizeof(T) * as_unsigned(nAfter) ); _m.end = dest + nAfter; } else if (dest < pLast) // must avoid self-move-assigning the elements diff --git a/unit_test/CMakeLists.txt b/unit_test/CMakeLists.txt index 76a797c3..c2ec8492 100644 --- a/unit_test/CMakeLists.txt +++ b/unit_test/CMakeLists.txt @@ -47,7 +47,7 @@ else() if(MEM_BOUND_DEBUG) target_compile_options(oel-test PRIVATE -fno-strict-aliasing) endif() - target_compile_options(oel-test PRIVATE -Wall -Wextra -Wold-style-cast -Wshadow -Wconversion -Wno-sign-conversion) + target_compile_options(oel-test PRIVATE -Wall -Wextra -Wold-style-cast -Wshadow -Wconversion -Wsign-conversion) endif() target_link_libraries(oel-test gtest_main) diff --git a/view/owning.h b/view/owning.h index 2472c012..725b9085 100644 --- a/view/owning.h +++ b/view/owning.h @@ -45,8 +45,17 @@ class owning constexpr bool empty() { return _r.empty(); } constexpr decltype(auto) operator[](difference_type index) - OEL_REQUIRES(requires{ _r[index]; }) { return _r[index]; } - + OEL_REQUIRES(requires{ _r[index]; }) + { + #ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsign-conversion" + #endif + return _r[index]; + #ifdef __GNUC__ + #pragma GCC diagnostic pop + #endif + } constexpr Range base() && { return std::move(_r); } constexpr const Range & base() const & noexcept { return _r; } void base() const && = delete;