Skip to content

Commit

Permalink
_moveView, _transformView in namespace oel, simpler _transformView::end
Browse files Browse the repository at this point in the history
  • Loading branch information
OleErikPeistorpet committed Sep 29, 2023
1 parent 01c212a commit a65cef6
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 99 deletions.
4 changes: 2 additions & 2 deletions dynarray.h
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ dynarray<T, Alloc>::dynarray(dynarray && other, const Alloc & a)
: _m(a)
{
OEL_CONST_COND if (!_alloTrait::is_always_equal::value and a != other._m)
append(view::move(other));
append(other | view::move);
else
_moveInternBase(other._m);
}
Expand All @@ -784,7 +784,7 @@ dynarray<T, Alloc> & dynarray<T, Alloc>::operator =(dynarray && other) &
Alloc & myA = _m;
OEL_CONST_COND if (!_alloTrait::propagate_on_container_move_assignment::value and myA != other._m)
{
assign(view::move(other));
assign(other | view::move);
}
else // take allocated memory from other
{
Expand Down
98 changes: 43 additions & 55 deletions view/move.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,52 +13,22 @@

namespace oel
{
namespace view
{

struct _moveFn
template< typename View >
class _moveView
{
/** @brief Create view, for chaining like std::views
@code
std::string moveFrom[2] {"abc", "def"};
dynarray movedStrings(moveFrom | view::move);
@endcode */
template< typename InputRange >
friend constexpr auto operator |(InputRange && r, _moveFn)
{
return _moveFn{}(static_cast<InputRange &&>(r));
}
//! Same as `std::views::as_rvalue(r)` (C++23)
template< typename InputRange >
constexpr auto operator()(InputRange && r) const;
};
//! Very similar to views::move in the Range-v3 library and std::views::as_rvalue
inline constexpr _moveFn move;

}

////////////////////////////////////////////////////////////////////////////////
View _base;

namespace _detail
{
template< typename InputView >
class MoveView
{
InputView _base;

public:
using difference_type = iter_difference_t< iterator_t<InputView> >;
public:
using difference_type = iter_difference_t< iterator_t<View> >;

MoveView() = default;
constexpr explicit MoveView(InputView v) : _base{std::move(v)} {}
_moveView() = default;
constexpr explicit _moveView(View v) : _base{std::move(v)} {}

constexpr auto begin()
{
return std::move_iterator{_base.begin()};
}
constexpr auto begin() { return std::move_iterator{_base.begin()}; }

template< typename V = InputView, typename /*EnableIfHasEnd*/ = sentinel_t<V> >
constexpr auto end()
template< typename V = View, typename /*EnableIfHasEnd*/ = sentinel_t<V> >
constexpr auto end()
{
#if OEL_HAS_STD_MOVE_SENTINEL
if constexpr (!std::is_same_v< iterator_t<V>, sentinel_t<V> >)
Expand All @@ -68,35 +38,53 @@ namespace _detail
return std::move_iterator{_base.end()};
}

constexpr bool empty() { return _base.empty(); }
template< typename V = View > OEL_ALWAYS_INLINE
constexpr auto size()
-> decltype( std::declval<V>().size() ) { return _base.size(); }

template< typename V = InputView >
OEL_ALWAYS_INLINE constexpr auto size()
-> decltype( std::declval<V>().size() ) { return _base.size(); }
constexpr bool empty() { return _base.empty(); }

OEL_ALWAYS_INLINE constexpr decltype(auto) operator[](difference_type index)
OEL_REQUIRES(iter_is_random_access< iterator_t<InputView> >) { return begin()[index]; }
constexpr decltype(auto) operator[](difference_type index)
OEL_REQUIRES(iter_is_random_access< iterator_t<View> >) OEL_ALWAYS_INLINE { return begin()[index]; }

constexpr InputView base() && { return std::move(_base); }
constexpr const InputView & base() const & noexcept { return _base; }
};
}
constexpr View base() && { return std::move(_base); }
constexpr const View & base() const & noexcept { return _base; }
};

namespace view
{

template< typename InputRange >
constexpr auto view::_moveFn::operator()(InputRange && r) const
struct _moveFn
{
return _detail::MoveView{all( static_cast<InputRange &&>(r) )};
template< typename InputRange >
friend constexpr auto operator |(InputRange && r, _moveFn)
{
return _moveView{all( static_cast<InputRange &&>(r) )};
}

template< typename InputRange >
constexpr auto operator()(InputRange && r) const { return static_cast<InputRange &&>(r) | _moveFn{}; }
};
/** @brief Very similar to views::move in the Range-v3 library and std::views::as_rvalue
@code
std::string moveFrom[2] {"abc", "def"};
oel::dynarray movedStrings(moveFrom | view::move);
@endcode
* Expect compile error if passed a transform having function with non-const `operator()` */
inline constexpr _moveFn move;

}

} // oel


#if OEL_STD_RANGES

template< typename V >
inline constexpr bool std::ranges::enable_borrowed_range< oel::_detail::MoveView<V> >
inline constexpr bool std::ranges::enable_borrowed_range< oel::_moveView<V> >
= std::ranges::enable_borrowed_range< std::remove_cv_t<V> >;

template< typename V >
inline constexpr bool std::ranges::enable_view< oel::_detail::MoveView<V> > = true;
inline constexpr bool std::ranges::enable_view< oel::_moveView<V> > = true;

#endif
75 changes: 33 additions & 42 deletions view/transform.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,60 +41,51 @@ inline constexpr _transformFn transform;

} // view

////////////////////////////////////////////////////////////////////////////////

namespace _detail
template< typename View, typename Func >
class _transformView
{
template< typename View, typename Func >
class TransformView
{
using _iter = transform_iterator< Func, iterator_t<View> >;
using _iter = transform_iterator< Func, iterator_t<View> >;

TightPair< View, typename _detail::AssignableWrap<Func>::Type > _m;
_detail::TightPair< View, typename _detail::AssignableWrap<Func>::Type > _m;

template< typename F_ = Func,
enable_if< std::is_empty_v<F_> > = 0
>
constexpr _iter _makeSent(iterator_t<View> last)
public:
using difference_type = iter_difference_t<_iter>;

_transformView() = default;
constexpr _transformView(View v, Func f) : _m{std::move(v), std::move(f)} {}

constexpr _iter begin()
{
return {_m.second(), last};
return {_detail::MoveIfNotCopyable(_m.second()), _m.first.begin()};
}

template< typename Sentinel, typename... None >
constexpr sentinel_wrapper<Sentinel> _makeSent(Sentinel last, None...)
//! Return type either same as `begin()` or oel::sentinel_wrapper
template< typename V = View, typename /*EnableIfHasEnd*/ = sentinel_t<V> >
constexpr auto end()
{
return {last};
if constexpr (std::is_empty_v<Func> and std::is_same_v< iterator_t<V>, sentinel_t<V> >)
return _iter(_m.second(), _m.first.end());
else
return sentinel_wrapper< sentinel_t<V> >{_m.first.end()};
}

public:
using difference_type = iter_difference_t<_iter>;
template< typename V = View > OEL_ALWAYS_INLINE
constexpr auto size()
-> decltype( std::declval<V>().size() ) { return _m.first.size(); }

TransformView() = default;
constexpr bool empty() { return _m.first.empty(); }

constexpr TransformView(View v, Func f)
: _m{std::move(v), std::move(f)} {}
constexpr View base() && { return std::move(_m.first); }
constexpr const View & base() const & noexcept { return _m.first; }
};

constexpr _iter begin()
{
return {_detail::MoveIfNotCopyable( _m.second() ), _m.first.begin()};
}

template< typename V_ = View, typename /*EnableIfHasEnd*/ = sentinel_t<V_> >
OEL_ALWAYS_INLINE constexpr auto end()
{
return _makeSent(_m.first.end());
}

constexpr bool empty() { return _m.first.empty(); }
////////////////////////////////////////////////////////////////////////////////

template< typename V_ = View >
OEL_ALWAYS_INLINE constexpr auto size()
-> decltype( std::declval<V_>().size() ) { return _m.first.size(); }

constexpr View base() && { return std::move(_m.first); }
constexpr const View & base() const & noexcept { return _m.first; }
};

namespace _detail
{
template< typename F >
struct TransfPartial
{
Expand All @@ -103,7 +94,7 @@ namespace _detail
template< typename Range >
friend constexpr auto operator |(Range && r, TransfPartial t)
{
return TransformView{view::all( static_cast<Range &&>(r) ), std::move(t)._f};
return _transformView{view::all( static_cast<Range &&>(r) ), std::move(t)._f};
}
};
}
Expand All @@ -114,15 +105,15 @@ constexpr auto view::_transformFn::operator()(UnaryFunc f) const
return _detail::TransfPartial<UnaryFunc>{std::move(f)};
}

} // namespace oel
} // oel

#if OEL_STD_RANGES

template< typename V, typename F >
inline constexpr bool std::ranges::enable_borrowed_range< oel::_detail::TransformView<V, F> >
inline constexpr bool std::ranges::enable_borrowed_range< oel::_transformView<V, F> >
= std::ranges::enable_borrowed_range< std::remove_cv_t<V> >;

template< typename V, typename F >
inline constexpr bool std::ranges::enable_view< oel::_detail::TransformView<V, F> > = true;
inline constexpr bool std::ranges::enable_view< oel::_transformView<V, F> > = true;

#endif

0 comments on commit a65cef6

Please sign in to comment.