diff --git a/auxi/dynarray_detail.h b/auxi/dynarray_detail.h index 7463cd34..add5a7bc 100644 --- a/auxi/dynarray_detail.h +++ b/auxi/dynarray_detail.h @@ -28,7 +28,7 @@ namespace oel::_detail struct DebugAllocationHeader { std::uintptr_t id; - size_t nObjects; + ptrdiff_t nObjects; }; inline constexpr DebugAllocationHeader headerNoAllocation{}; @@ -42,7 +42,7 @@ namespace oel::_detail inline bool HasValidIndex(const T * arrayElem, const DebugAllocationHeader & h) { auto index = arrayElem - reinterpret_cast(&h + 1); - return static_cast(index) < h.nObjects; + return static_cast(index) < static_cast(h.nObjects); } template< typename Alloc, typename Ptr > diff --git a/dynarray.h b/dynarray.h index 63d69c78..8f74f854 100644 --- a/dynarray.h +++ b/dynarray.h @@ -206,9 +206,9 @@ class dynarray [[nodiscard]] bool empty() const noexcept { return _m.data == _m.end; } - size_type size() const noexcept { return _m.end - _m.data; } + size_type size() const noexcept { return static_cast(_m.end - _m.data); } - size_type capacity() const noexcept { return _m.reservEnd - _m.data; } + size_type capacity() const noexcept { return static_cast(_m.reservEnd - _m.data); } constexpr size_type max_size() const noexcept { return _alloTrait::max_size(_m) - _allocateWrap::sizeForHeader; } @@ -242,15 +242,21 @@ 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]; } + T & at(size_type index) OEL_ALWAYS_INLINE { const auto & cSelf = *this; return const_cast(cSelf.at(index)); } - const T & at(size_type index) const; - - 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]; } + const T & at(size_type index) const + { + if (index < size()) // would be unsafe with signed size_type + return _m.data[index]; + else + _detail::OutOfRange::raise("Bad index dynarray::at"); + } friend bool operator==(const dynarray & left, const dynarray & right) { @@ -290,7 +296,7 @@ class dynarray : ::oel::_detail::DynarrBase{}, _usedAlloc_7KQw{std::move(a)} { } - _memOwner(_memOwner && other) noexcept + constexpr _memOwner(_memOwner && other) noexcept : ::oel::_detail::DynarrBase{other}, _usedAlloc_7KQw{std::move(other)} { other.reservEnd = other.end = other.data = nullptr; @@ -299,7 +305,10 @@ class dynarray ~_memOwner() { if (data) - ::oel::_detail::DebugAllocateWrapper<_usedAlloc_7KQw, value_type *>::dealloc(*this, data, reservEnd - data); + { + ::oel::_detail::DebugAllocateWrapper<_usedAlloc_7KQw, value_type *> + ::dealloc(*this, data, static_cast(reservEnd - data)); + } } } _m; // the only non-static data member @@ -330,7 +339,7 @@ class dynarray size_type _unusedCapacity() const { - return _m.reservEnd - _m.end; + return static_cast(_m.reservEnd - _m.end); } size_type _calcCapUnchecked(size_type const newSize) const @@ -375,13 +384,13 @@ class dynarray { if constexpr (allocator_can_realloc) { - T *const p = _allocateWrap::realloc(_m, _m.data, newCap); + auto const p = _allocateWrap::realloc(_m, _m.data, newCap); _m.data = p; _m.end = p + oldSize; _m.reservEnd = p + newCap; } else - { T *const newData = _allocateWrap::allocate(_m, newCap); + { auto const newData = _allocateWrap::allocate(_m, newCap); _m.end = _detail::Relocate(_m.data, oldSize, newData); _resetData(newData, newCap); } @@ -445,14 +454,14 @@ class dynarray while (dest != dLast) { *dest = *src_; - ++src_; ++dest; + ++dest; ++src_; } return src_; }; T * newEnd; if (capacity() < count) { - T *const newData = _allocateChecked(count); + auto const newData = _allocateChecked(count); // Old elements might hold some limited resource, probably good to destroy them before constructing new _detail::Destroy(_m.data, _m.end); _resetData(newData, count); @@ -520,7 +529,7 @@ class dynarray } else { T *__restrict dest = _m.end; - T *const dLast = dest + count; + auto const dLast = dest + count; OEL_TRY_ { while (dest != dLast) @@ -800,7 +809,7 @@ inline void dynarray::append(size_type count, const T &__restrict val) if (_unusedCapacity() < count) _growBy(count); - T *const pos = _m.end; + auto const pos = _m.end; _uninitFill::template call< _detail::ForwardT >(pos, pos + count, _m, val); _debugSizeUpdater guard{_m}; @@ -821,7 +830,7 @@ inline void dynarray::pop_back() noexcept template< typename T, typename Alloc > void dynarray::erase_to_end(iterator first) noexcept { - T *const newEnd = to_pointer_contiguous(first); + T *const newEnd{to_pointer_contiguous(first)}; OEL_ASSERT(_m.data <= newEnd and newEnd <= _m.end); _detail::Destroy(newEnd, _m.end); @@ -856,12 +865,12 @@ typename dynarray::iterator dynarray::erase(iterator pos) _ { _debugSizeUpdater guard{_m}; - T *const ptr = to_pointer_contiguous(pos); + T *const ptr{to_pointer_contiguous(pos)}; OEL_ASSERT(_m.data <= ptr and ptr < _m.end); if constexpr (is_trivially_relocatable::value) { ptr-> ~T(); - T *const next = ptr + 1; + auto const next = ptr + 1; std::memmove( // relocate [pos + 1, end) to [pos, end - 1) static_cast(ptr), static_cast(next), @@ -880,8 +889,8 @@ typename dynarray::iterator dynarray::erase(iterator first, { _debugSizeUpdater guard{_m}; - T * dest = to_pointer_contiguous(first); - const T *const pLast = to_pointer_contiguous(last); + T * dest{to_pointer_contiguous(first)}; + const T *const pLast{to_pointer_contiguous(last)}; OEL_ASSERT(_m.data <= dest and dest <= pLast and pLast <= _m.end); if constexpr (is_trivially_relocatable::value) @@ -904,16 +913,6 @@ typename dynarray::iterator dynarray::erase(iterator first, } -template< typename T, typename Alloc > -const T & dynarray::at(size_type i) const -{ - if (i < size()) // would be unsafe with signed size_type - return _m.data[i]; - else - _detail::OutOfRange::raise("Bad index dynarray::at"); -} - - template< typename InputRange, typename Alloc = allocator<> > explicit dynarray(InputRange &&, Alloc = {}) -> dynarray< diff --git a/unit_test/dynarray_construct_assignop_swap_gtest.cpp b/unit_test/dynarray_construct_assignop_swap_gtest.cpp index f431fa55..05b7a478 100644 --- a/unit_test/dynarray_construct_assignop_swap_gtest.cpp +++ b/unit_test/dynarray_construct_assignop_swap_gtest.cpp @@ -282,7 +282,7 @@ TEST_F(dynarrayConstructTest, constructRangeNoCopyAssign) TEST_F(dynarrayConstructTest, constructForwardRangeNoSize) { - for (size_t const n : {0, 1, 59}) + for (auto const n : {0u, 1u, 59u}) { std::forward_list li(n, -6); dynarray d(li); @@ -373,12 +373,12 @@ void testConstructMoveElements() g_allocCount.clear(); T::clearCount(); // not propagating, not equal, cannot steal the memory - for (auto const na : {0, 1, 101}) + for (auto const na : {0u, 1u, 101u}) { using Alloc = StatefulAllocator; dynarray a(reserve, na, Alloc{1}); - for (int i = 0; i < na; ++i) + for (unsigned i{}; i < na; ++i) a.emplace_back(i + 0.5); auto const capBefore = a.capacity(); @@ -398,7 +398,7 @@ void testConstructMoveElements() EXPECT_EQ(capBefore, a.capacity()); ASSERT_EQ(na, ssize(b)); - for (int i = 0; i < na; ++i) + for (unsigned i{}; i < na; ++i) EXPECT_TRUE(b[i].hasValue() and *b[i] == i + 0.5); } EXPECT_EQ(T::nConstructions, T::nDestruct); @@ -471,8 +471,8 @@ void testAssignMoveElements() for (auto const nb : {0, 1, 2}) { using Alloc = StatefulAllocator; - dynarray a(reserve, na, Alloc{1}); - dynarray b(reserve, nb, Alloc{2}); + dynarray a(reserve, as_unsigned(na), Alloc{1}); + dynarray b(reserve, as_unsigned(nb), Alloc{2}); ASSERT_FALSE(a.get_allocator() == b.get_allocator()); @@ -497,7 +497,7 @@ void testAssignMoveElements() EXPECT_EQ(capBefore, a.capacity()); ASSERT_EQ(na, ssize(b)); - for (int i = 0; i < na; ++i) + for (unsigned i{}; i < as_unsigned(na); ++i) EXPECT_TRUE(b[i].hasValue() and *b[i] == i + 0.5); } EXPECT_EQ(T::nConstructions, T::nDestruct); diff --git a/unit_test/dynarray_mutate_gtest.cpp b/unit_test/dynarray_mutate_gtest.cpp index fff3ef36..6d1bef03 100644 --- a/unit_test/dynarray_mutate_gtest.cpp +++ b/unit_test/dynarray_mutate_gtest.cpp @@ -292,7 +292,7 @@ TEST_F(dynarrayTest, assignNonForwardRange) decltype(das) copyDest; copyDest.assign(view::counted(das.cbegin(), 2)); - copyDest.assign( view::counted(begin(das), das.size()) ); + copyDest.assign( view::counted(begin(das), ssize(das)) ); EXPECT_TRUE(das == copyDest); @@ -394,7 +394,7 @@ TEST_F(dynarrayTest, appendNonForwardRange) EXPECT_EQ(it, end); EXPECT_EQ(3u, dest.size()); for (int i = 0; i < 3; ++i) - EXPECT_EQ(i + 1, dest[i]); + EXPECT_EQ( i + 1, dest[oel::as_unsigned(i)] ); } #endif @@ -413,7 +413,7 @@ TEST_F(dynarrayTest, insertRTrivial) dest.emplace_back(1); dest.emplace_back(2); - dest.insert_range(dest.begin() + insertOffset, toInsert); + dest.insert_range(dest.begin() + oel::as_signed(insertOffset), toInsert); EXPECT_TRUE(dest.size() == initSize + toInsert.size()); for (size_t i = 0; i < toInsert.size(); ++i) @@ -453,7 +453,7 @@ TEST_F(dynarrayTest, insertR) if (countThrow < toInsert.size()) { #if OEL_HAS_EXCEPTIONS - TrivialRelocat::countToThrowOn = countThrow; + TrivialRelocat::countToThrowOn = oel::as_signed(countThrow); EXPECT_THROW( dest.insert_range(dest.begin() + insertOffset, toInsert), TestException ); #endif EXPECT_TRUE(initSize <= dest.size() and dest.size() <= initSize + countThrow); @@ -500,7 +500,7 @@ TEST_F(dynarrayTest, emplace) { TrivialRelocat::countToThrowOn = -1; g_allocCount.countToThrowOn = -1; - dynarrayTrackingAlloc dest(oel::reserve, nReserve); + dynarrayTrackingAlloc dest(oel::reserve, oel::as_unsigned(nReserve)); dest.emplace(dest.begin(), firstVal); dest.emplace(dest.begin(), secondVal); @@ -519,7 +519,7 @@ TEST_F(dynarrayTest, emplace) { dest.emplace(dest.begin() + insertOffset); EXPECT_EQ(initSize + 1, ssize(dest)); - EXPECT_FALSE( dest.at(insertOffset).hasValue() ); + EXPECT_FALSE( dest.at(oel::as_unsigned(insertOffset)).hasValue() ); } if (insertOffset == 0) { @@ -961,9 +961,9 @@ TEST_F(dynarrayTest, misc) dest0.reserve(1); dest0 = daSrc; - dest0.append( view::counted(daSrc.cbegin(), daSrc.size()) ); + dest0.append( view::counted(daSrc.cbegin(), ssize(daSrc)) ); dest0.append(view::counted(fASrc, 2)); - auto srcEnd = dest0.append( view::counted(begin(dequeSrc), dequeSrc.size()) ); + auto srcEnd = dest0.append( view::counted(begin(dequeSrc), oel::ssize(dequeSrc)) ); EXPECT_TRUE(end(dequeSrc) == srcEnd); dynarray dest1; diff --git a/unit_test/range_algo_gtest.cpp b/unit_test/range_algo_gtest.cpp index a8231fa4..3bfc2047 100644 --- a/unit_test/range_algo_gtest.cpp +++ b/unit_test/range_algo_gtest.cpp @@ -15,14 +15,14 @@ namespace view = oel::view; -TEST(rangeTest, eraseUnstable) +TEST(rangeTest, unorderedErase) { std::deque d{"aa", "bb", "cc"}; - oel::unordered_erase(d, 1); + oel::unordered_erase(d, 1u); EXPECT_EQ(2U, d.size()); EXPECT_EQ("cc", d.back()); - oel::unordered_erase(d, 1); + oel::unordered_erase(d, 1u); EXPECT_EQ(1U, d.size()); EXPECT_EQ("aa", d.front()); } diff --git a/unit_test/util_gtest.cpp b/unit_test/util_gtest.cpp index 98bcdae2..7554e619 100644 --- a/unit_test/util_gtest.cpp +++ b/unit_test/util_gtest.cpp @@ -164,8 +164,8 @@ TEST(utilTest, makeUnique) EXPECT_TRUE(ps[0].empty()); EXPECT_TRUE(ps[1].empty()); - auto a = oel::make_unique_for_overwrite(5); - for (int i = 0; i < 5; ++i) + auto a = oel::make_unique_for_overwrite(5); + for (size_t i{}; i < 5u; ++i) a[i] = i; } diff --git a/unit_test/view_gtest.cpp b/unit_test/view_gtest.cpp index 6b5fe0da..1821f73a 100644 --- a/unit_test/view_gtest.cpp +++ b/unit_test/view_gtest.cpp @@ -80,7 +80,7 @@ TEST(viewTest, viewCounted) #endif { oel::dynarray i{1, 2}; - auto test = view::counted(i.begin(), i.size()); + auto test = view::counted(i.begin(), ssize(i)); EXPECT_EQ(i.size(), test.size()); EXPECT_EQ(1, test[0]); EXPECT_EQ(2, test[1]); @@ -148,7 +148,7 @@ constexpr auto multBy2(StdArrInt2 a) { constexpr auto operator()(int i) const { return 2 * i; } } mult2{}; auto v = view::transform(a, mult2); - std::ptrdiff_t i{}; + size_t i{}; for (auto val : v) res[i++] = val; diff --git a/view/counted.h b/view/counted.h index 0712ab6a..2d2b9a51 100644 --- a/view/counted.h +++ b/view/counted.h @@ -33,8 +33,7 @@ class counted > constexpr Iterator end() const { return _begin + _size; } - constexpr std::make_unsigned_t - size() const noexcept OEL_ALWAYS_INLINE { return _size; } + constexpr auto size() const noexcept OEL_ALWAYS_INLINE { return std::make_unsigned_t(_size); } constexpr bool empty() const noexcept { return 0 == _size; } diff --git a/view/owning.h b/view/owning.h index 0b744db1..2472c012 100644 --- a/view/owning.h +++ b/view/owning.h @@ -37,14 +37,12 @@ class owning constexpr auto end() -> decltype( adl_end(std::declval()) ) { return adl_end(_r); } - template< typename R = Range > OEL_ALWAYS_INLINE - constexpr auto size() - -> decltype(as_unsigned( _detail::Size(std::declval()) )) - { - return _detail::Size(_r); - } + template< typename R = Range, + typename SizeT = decltype(as_unsigned( _detail::Size(std::declval()) )) + > OEL_ALWAYS_INLINE + constexpr SizeT size() { return static_cast(_detail::Size(_r)); } - constexpr bool empty() { return _r.empty(); } + constexpr bool empty() { return _r.empty(); } constexpr decltype(auto) operator[](difference_type index) OEL_REQUIRES(requires{ _r[index]; }) { return _r[index]; } diff --git a/view/subrange.h b/view/subrange.h index d1e1c1fe..511d1a47 100644 --- a/view/subrange.h +++ b/view/subrange.h @@ -30,10 +30,13 @@ class subrange //! Provided only if begin() can be subtracted from end() template< typename I = Iterator, - enable_if< !disable_sized_sentinel_for > = 0 + enable_if< !disable_sized_sentinel_for > = 0, + typename Ret = decltype( as_unsigned(std::declval() - std::declval()) ) > - constexpr auto size() const - -> decltype( as_unsigned(std::declval() - std::declval()) ) { return _m.second() - _m.first; } + constexpr Ret size() const + { + return static_cast(_m.second() - _m.first); + } constexpr bool empty() const { return _m.first == _m.second(); }