Skip to content

Commit

Permalink
Replaced _detail::CountOrEnd with rangeIsForwardOrSized and UDist
Browse files Browse the repository at this point in the history
  • Loading branch information
OleErikPeistorpet committed Jun 13, 2024
1 parent 1d40667 commit 655868d
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 72 deletions.
26 changes: 14 additions & 12 deletions auxi/impl_algo.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


#include "contiguous_iterator_to_ptr.h"
#include "range_traits.h"
#include "../util.h" // for as_unsigned

#include <cstring>

Expand Down Expand Up @@ -128,26 +128,28 @@ namespace oel::_detail



// If r is sized or multi-pass, returns element count as size_t, else end(r)
template< typename Range, typename... None >
inline auto CountOrEnd(Range & r, None...)
auto UDist(Range & r, None...)
{
if constexpr (iter_is_forward< iterator_t<Range> >)
using I = decltype(begin(r));
if constexpr (iter_is_forward<I>)
{
size_t n{};
auto it = begin(r);
auto it = begin(r);
auto const l = end(r);
std::make_unsigned_t< iter_difference_t<I> > n{};
while (it != l) { ++it; ++n; }

return n;
}
else
{ return end(r);
}
}

template< typename Range >
auto CountOrEnd(Range & r)
-> decltype( static_cast<size_t>(_detail::Size(r)) )
{ return static_cast<size_t>(_detail::Size(r)); }
auto UDist(Range & r)
-> decltype( as_unsigned(_detail::Size(r)) )
{ return as_unsigned(_detail::Size(r)); }


template< typename Range >
inline constexpr auto rangeIsForwardOrSized =
!std::is_same_v< decltype( _detail::UDist(std::declval<Range &>()) ), void >;
}
1 change: 0 additions & 1 deletion auxi/range_algo_detail.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@


#include "impl_algo.h"
#include "../util.h" // for as_unsigned

#include <algorithm>

Expand Down
136 changes: 78 additions & 58 deletions dynarray.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,7 @@ class dynarray
*
* Any elements held before the call are either assigned to or destroyed. */
template< typename InputRange >
auto assign(InputRange && source)
-> borrowed_iterator_t<InputRange> { return _doAssign(adl_begin(source), _detail::CountOrEnd(source)); }
auto assign(InputRange && source) -> borrowed_iterator_t<InputRange>;

void assign(size_type count, const T & val) { clear(); append(count, val); }

Expand All @@ -141,8 +140,8 @@ class dynarray
*
* Unlike std::vector, `end(source)` is not needed if `source.size()` is valid. */
template< typename InputRange >
auto append(InputRange && source)
-> borrowed_iterator_t<InputRange> { return _doAppend(adl_begin(source), _detail::CountOrEnd(source)); }
auto append(InputRange && source) -> borrowed_iterator_t<InputRange>;

//! Equivalent to `std::vector::insert(end(), il)`
void append(std::initializer_list<T> il) { append<>(il); }
/**
Expand Down Expand Up @@ -340,7 +339,6 @@ class dynarray
_m.reservEnd = _m.data + capToCheck;
}


void _moveInternBase(_internBase & src) noexcept
{
_internBase & dest = _m;
Expand Down Expand Up @@ -430,6 +428,17 @@ class dynarray
}


template< typename InputRange >
auto _emplBackRange(InputRange & src)
{
auto it = adl_begin(src);
auto l = adl_end(src);
for (; it != l; ++it)
emplace_back(*it);

return it;
}

template< typename InputIter >
InputIter _doAssign(InputIter src, size_type const count)
{
Expand Down Expand Up @@ -490,33 +499,6 @@ class dynarray
}
}

template< typename InputIter, typename Sentinel >
InputIter _doAssign(InputIter first, Sentinel const last)
{ // single-pass iterator and unknown count
clear();
for (; first != last; ++first)
emplace_back(*first);

return first;
}

template< typename InputIter, typename Sentinel >
InputIter _doAppend(InputIter first, Sentinel const last)
{ // single-pass iterator and unknown count
auto const oldSize = size();
OEL_TRY_
{
for (; first != last; ++first)
emplace_back(*first);
}
OEL_CATCH_ALL
{
erase_to_end(begin() + oldSize);
OEL_RETHROW;
}
return first;
}

template< typename InputIter >
InputIter _doAppend(InputIter src, size_type const count)
{
Expand Down Expand Up @@ -635,11 +617,11 @@ typename dynarray<T, Alloc>::iterator
OEL_DYNARR_INSERT_STEP1
#undef OEL_DYNARR_INSERT_STEP1

auto first = adl_begin(src);
auto const count = _detail::CountOrEnd(src);
static_assert( _detail::rangeIsForwardOrSized<Range>,
"insert_range requires that source models std::ranges::forward_range or that source.size() is valid" );

static_assert( std::is_same_v<decltype(count), size_t const>,
"insert_range requires that source models std::ranges::forward_range or that source.size() is valid" );
auto first = adl_begin(src);
auto const count = _detail::UDist(src);

size_t const bytesAfterPos{sizeof(T) * (_m.end - pPos)};
T * dLast;
Expand Down Expand Up @@ -723,6 +705,66 @@ inline void dynarray<T, Alloc>::append(size_type count, const T & val)
_m.end += count;
}

template< typename T, typename Alloc >
template< typename InputRange >
inline auto dynarray<T, Alloc>::append(InputRange && source)
-> borrowed_iterator_t<InputRange>
{
if constexpr (_detail::rangeIsForwardOrSized<InputRange>)
{
return _doAppend(adl_begin(source), _detail::UDist(source));
}
else
{ auto const oldSize = size();
OEL_TRY_
{
return _emplBackRange(source);
}
OEL_CATCH_ALL
{
erase_to_end(begin() + oldSize);
OEL_RETHROW;
}
}
}

template< typename T, typename Alloc >
template< typename InputRange >
inline auto dynarray<T, Alloc>::assign(InputRange && source)
-> borrowed_iterator_t<InputRange>
{
if constexpr (_detail::rangeIsForwardOrSized<InputRange>)
{
return _doAssign(adl_begin(source), _detail::UDist(source));
}
else
{ clear();
return _emplBackRange(source);
}
}


template< typename T, typename Alloc >
dynarray<T, Alloc>::dynarray(size_type n, for_overwrite_t, Alloc a)
: _m(a)
{
_initReserve(n);
_m.end = _m.reservEnd;
_detail::DefaultInit<allocator_type>::call(_m.data, _m.reservEnd, _m);

(void) _debugSizeUpdater{_m};
}

template< typename T, typename Alloc >
dynarray<T, Alloc>::dynarray(size_type n, Alloc a)
: _m(a)
{
_initReserve(n);
_m.end = _m.reservEnd;
_uninitFill::call(_m.data, _m.reservEnd, _m);

(void) _debugSizeUpdater{_m};
}

template< typename T, typename Alloc >
dynarray<T, Alloc>::dynarray(dynarray && other, Alloc a)
Expand Down Expand Up @@ -769,28 +811,6 @@ dynarray<T, Alloc> & dynarray<T, Alloc>::operator =(const dynarray & other) &
return *this;
}

template< typename T, typename Alloc >
dynarray<T, Alloc>::dynarray(size_type n, for_overwrite_t, Alloc a)
: _m(a)
{
_initReserve(n);
_m.end = _m.reservEnd;
_detail::DefaultInit<allocator_type>::call(_m.data, _m.reservEnd, _m);

(void) _debugSizeUpdater{_m};
}

template< typename T, typename Alloc >
dynarray<T, Alloc>::dynarray(size_type n, Alloc a)
: _m(a)
{
_initReserve(n);
_m.end = _m.reservEnd;
_uninitFill::call(_m.data, _m.reservEnd, _m);

(void) _debugSizeUpdater{_m};
}

template< typename T, typename Alloc >
dynarray<T, Alloc>::~dynarray() noexcept
{
Expand Down
4 changes: 3 additions & 1 deletion unit_test/util_gtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,8 @@ TEST(utilTest, detailCountOrEnd_disabledSize)
A src{1};
auto v = oel::view::subrange(TooSimpleIter<A::iterator>{src.begin()}, src.end());

auto n = oel::_detail::CountOrEnd(v);
static_assert(oel::_detail::rangeIsForwardOrSized<decltype(v)>);

auto n = oel::_detail::UDist(v);
EXPECT_EQ(1u, n);
}

0 comments on commit 655868d

Please sign in to comment.