From ac439331d6ccc3c4f0ac8dba17668e95a9a1ee90 Mon Sep 17 00:00:00 2001 From: Ole Erik Peistorpet Date: Fri, 25 Aug 2023 13:25:55 +0200 Subject: [PATCH] Made OwningView, using it in view::all Also MoveView, TransformView::base() const & noexcept --- view/all.h | 19 +++++-------- view/detail/owning.h | 67 ++++++++++++++++++++++++++++++++++++++++++++ view/move.h | 4 +-- view/transform.h | 4 +-- 4 files changed, 78 insertions(+), 16 deletions(-) create mode 100644 view/detail/owning.h diff --git a/view/all.h b/view/all.h index da014274..7293215c 100644 --- a/view/all.h +++ b/view/all.h @@ -8,6 +8,7 @@ #include "counted.h" #include "subrange.h" +#include "detail/owning.h" /** @file */ @@ -26,25 +27,19 @@ namespace _detail } #endif - template< typename I > - constexpr auto operator()(view::counted v) const { return v; } - - template< typename I, typename S > - constexpr auto operator()(view::subrange v) const { return v; } - template< typename SizedRange > constexpr auto operator()(SizedRange & r) const -> decltype( view::counted(begin(r), oel::ssize(r)) ) { return view::counted(begin(r), oel::ssize(r)); } - template< typename Range, typename... None > - constexpr auto operator()(Range & r, None...) const + template< typename Range > + constexpr auto operator()(Range && r) const { - return view::subrange(begin(r), end(r)); + if constexpr (std::is_lvalue_reference_v) + return view::subrange(begin(r), end(r)); + else + return OwningView{static_cast(r)}; } - - template< typename R > - void operator()(R &&) const = delete; }; } diff --git a/view/detail/owning.h b/view/detail/owning.h new file mode 100644 index 00000000..57728b7d --- /dev/null +++ b/view/detail/owning.h @@ -0,0 +1,67 @@ +#pragma once + +// Copyright 2020 Ole Erik Peistorpet +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +#include "../../util.h" + +namespace oel::_detail +{ + template< typename Range > + class OwningView + { + using _iter = iterator_t; + + Range _r; + + public: + using difference_type = iter_difference_t<_iter>; + + OwningView() = default; + OwningView(OwningView &&) = default; + OwningView(const OwningView &) = delete; + OwningView & operator =(OwningView &&) = default; + OwningView & operator =(const OwningView &) = delete; + + constexpr explicit OwningView(Range && r) : _r{std::move(r)} {} + + OEL_ALWAYS_INLINE constexpr _iter begin() { return adl_begin(_r); } + + template< typename R = Range > + OEL_ALWAYS_INLINE 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); + } + + // Might want to be more generic here, don't know if _r.empty exists + constexpr bool empty() { return _r.empty(); } + + constexpr decltype(auto) operator[](difference_type index) + OEL_REQUIRES(iter_is_random_access<_iter>) + { + return adl_begin(_r)[index]; + } + + constexpr Range && base() && noexcept { return std::move(_r); } + constexpr const Range & base() const & noexcept { return _r; } + }; +} + +#if OEL_STD_RANGES + +template< typename R > +inline constexpr bool std::ranges::enable_borrowed_range< oel::_detail::OwningView > + = std::ranges::enable_borrowed_range< std::remove_cv_t >; + +template< typename R > +inline constexpr bool std::ranges::enable_view< oel::_detail::OwningView > = true; + +#endif diff --git a/view/move.h b/view/move.h index 9a34ba8c..746cd353 100644 --- a/view/move.h +++ b/view/move.h @@ -77,8 +77,8 @@ namespace _detail OEL_ALWAYS_INLINE constexpr decltype(auto) operator[](difference_type index) OEL_REQUIRES(iter_is_random_access< iterator_t >) { return begin()[index]; } - constexpr InputView base() && { return std::move(_base); } - constexpr const InputView & base() const & { return _base; } + constexpr InputView base() && { return std::move(_base); } + constexpr const InputView & base() const & noexcept { return _base; } }; } diff --git a/view/transform.h b/view/transform.h index a59b95ae..188aee3f 100644 --- a/view/transform.h +++ b/view/transform.h @@ -91,8 +91,8 @@ namespace _detail OEL_ALWAYS_INLINE constexpr auto size() -> decltype( std::declval().size() ) { return _m.first.size(); } - constexpr View base() && { return std::move(_m.first); } - constexpr const View & base() const & { return _m.first; } + constexpr View base() && { return std::move(_m.first); } + constexpr const View & base() const & noexcept { return _m.first; } }; template< typename F >