Skip to content

Commit

Permalink
Relying on CTAD, using ssize in namespace view
Browse files Browse the repository at this point in the history
Replaced counted and subrange view creation functions with the classes.
Using CTAD in MoveView implementation.
Also changed protected counted, subrange members to private
  • Loading branch information
OleErikPeistorpet committed Sep 29, 2023
1 parent e3024d3 commit ec2ea9b
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 63 deletions.
2 changes: 1 addition & 1 deletion unit_test/dynarray_mutate_gtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ TEST_F(dynarrayTest, insertRTrivial)
{
// Should hit static_assert
//dynarray<double> d;
//d.insert_range( d.begin(), oel::basic_view< std::istream_iterator<double> >({}, {}) );
//d.insert_range( d.begin(), oel::view::subrange(std::istream_iterator<double>{}, std::istream_iterator<double>{}) );

size_t const initSize = 2;
auto toInsert = {-1.0, -2.0};
Expand Down
17 changes: 9 additions & 8 deletions unit_test/view_gtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "views.h"
#include "dynarray.h"
#include "util.h"

#include "gtest/gtest.h"
#include <array>
Expand All @@ -24,16 +25,16 @@ constexpr auto transformIterFromIntPtr(const int * p)
template< typename S >
constexpr oel::sentinel_wrapper<S> makeSentinel(S se) { return {se}; }

TEST(viewTest, basicView)
TEST(viewTest, viewSubrange)
{
using BV = oel::basic_view<int *>;
using V = view::subrange<int *, int *>;

static_assert(std::is_trivially_constructible<BV, BV &>::value);
static_assert(std::is_trivially_constructible<V, V &>::value);

#if OEL_STD_RANGES
static_assert(std::ranges::contiguous_range<BV>);
static_assert(std::ranges::view<BV>);
static_assert(std::ranges::borrowed_range<BV>);
static_assert(std::ranges::contiguous_range<V>);
static_assert(std::ranges::view<V>);
static_assert(std::ranges::borrowed_range<V>);
#endif
static constexpr int src[3]{};
{
Expand All @@ -45,9 +46,9 @@ TEST(viewTest, basicView)
EXPECT_EQ(3, ssize(v));
}

TEST(viewTest, countedView)
TEST(viewTest, viewCounted)
{
using CV = oel::counted_view<int *>;
using CV = view::counted<int *>;

static_assert(std::is_trivially_constructible<CV, CV &>::value);

Expand Down
5 changes: 5 additions & 0 deletions util.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ constexpr auto ssize(SizedRangeLike && r)
return std::common_type_t< ptrdiff_t, decltype(as_signed( _detail::Size(r) )) >(_detail::Size(r));
}

namespace view
{
using oel::ssize;
}


/** @brief Check if index is valid (within bounds for operator[])
*
Expand Down
10 changes: 5 additions & 5 deletions view/all.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ namespace _detail
}
#endif

template< typename I, typename S >
constexpr auto operator()(basic_view<I, S> v) const { return v; }

template< typename I >
constexpr auto operator()(counted_view<I> v) const { return v; }
constexpr auto operator()(view::counted<I> v) const { return v; }

template< typename I, typename S >
constexpr auto operator()(view::subrange<I, S> v) const { return v; }

template< typename SizedRange >
constexpr auto operator()(SizedRange & r) const
Expand All @@ -49,7 +49,7 @@ namespace _detail
}


//! View creation functions. The API tries to mimic views in std::ranges
//! View types and view creation functions. The API tries to mimic views in std::ranges
namespace view
{
//! Substitute for std::views::all
Expand Down
24 changes: 8 additions & 16 deletions view/counted.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

// Copyright 2015 Ole Erik Peistorpet
// Copyright 2019 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)
Expand All @@ -11,20 +11,20 @@
/** @file
*/

namespace oel
namespace oel::view
{

/** @brief Wrapper for iterator and size
*
* Satisfies the std::ranges::range concept only if Iterator is random-access. */
template< typename Iterator >
class counted_view
class counted
{
public:
using difference_type = iter_difference_t<Iterator>;

counted_view() = default;
constexpr counted_view(Iterator f, difference_type n) : _begin{std::move(f)}, _size{n} {}
counted() = default;
constexpr counted(Iterator first, difference_type n) : _begin{std::move(first)}, _size{n} {}

constexpr Iterator begin() { return _detail::MoveIfNotCopyable(_begin); }
//! Provided only if Iterator is random-access
Expand All @@ -41,28 +41,20 @@ class counted_view
constexpr decltype(auto) operator[](difference_type index) const
OEL_REQUIRES(iter_is_random_access<Iterator>) OEL_ALWAYS_INLINE { return _begin[index]; }

protected:
private:
Iterator _begin;
difference_type _size;
};

namespace view
{

//! Create a counted_view from iterator and count (convertible to iter_difference_t for iterator)
inline constexpr auto counted =
[](auto iterator, auto count) { return counted_view(std::move(iterator), count); };

}

} // namespace oel

#if OEL_STD_RANGES

template< typename I >
inline constexpr bool std::ranges::enable_borrowed_range< oel::counted_view<I> > = true;
inline constexpr bool std::ranges::enable_borrowed_range< oel::view::counted<I> > = true;

template< typename I >
inline constexpr bool std::ranges::enable_view< oel::counted_view<I> > = true;
inline constexpr bool std::ranges::enable_view< oel::view::counted<I> > = true;

#endif
2 changes: 1 addition & 1 deletion view/detail/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ namespace _detail
} // oel


#if !OEL_STD_RANGES
#if __cpp_lib_concepts < 201907

// Small hack to let std::move_iterator< sentinel_wrapper<S> > compile
template< typename S >
Expand Down
24 changes: 9 additions & 15 deletions view/move.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,34 +44,28 @@ namespace _detail
template< typename InputView >
class MoveView
{
using _iter = std::move_iterator< iterator_t<InputView> >;

InputView _base;

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

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

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

template< typename V = InputView, typename /*EnableIfHasEnd*/ = sentinel_t<V> >
constexpr auto end()
{
#if OEL_STD_RANGES
using S = std::conditional_t<
std::is_same_v< iterator_t<V>, sentinel_t<V> >,
_iter,
std::move_sentinel< sentinel_t<V> >
>;
#else
using S = std::move_iterator< sentinel_t<V> >;
#if __cpp_lib_concepts >= 201907
if constexpr (!std::is_same_v< iterator_t<V>, sentinel_t<V> >)
return std::move_sentinel{_base.end()};
else
#endif
return S{_base.end()};
return std::move_iterator{_base.end()};
}

constexpr bool empty() { return _base.empty(); }
Expand All @@ -81,7 +75,7 @@ namespace _detail
-> decltype( std::declval<V>().size() ) { return _base.size(); }

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

constexpr InputView base() && { return std::move(_base); }
constexpr const InputView & base() const & { return _base; }
Expand Down
26 changes: 9 additions & 17 deletions view/subrange.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@
/** @file
*/

namespace oel
namespace oel::view
{

//! A minimal substitute for boost::iterator_range and std::ranges::subrange (C++20)
template< typename Iterator, typename Sentinel = Iterator >
class basic_view
//! A minimal substitute for std::ranges::subrange and boost::iterator_range
template< typename Iterator, typename Sentinel >
class subrange
{
public:
using difference_type = iter_difference_t<Iterator>;

basic_view() = default;
constexpr basic_view(Iterator f, Sentinel l) : _begin{std::move(f)}, _end{l} {}
subrange() = default;
constexpr subrange(Iterator first, Sentinel last) : _begin{std::move(first)}, _end{last} {}

constexpr Iterator begin() { return _detail::MoveIfNotCopyable(_begin); }

Expand All @@ -41,28 +41,20 @@ class basic_view
constexpr decltype(auto) operator[](difference_type index) const
OEL_REQUIRES(iter_is_random_access<Iterator>) OEL_ALWAYS_INLINE { return _begin[index]; }

protected:
private:
Iterator _begin;
Sentinel _end;
};

namespace view
{

//! Create a basic_view from iterator pair, or iterator and sentinel
inline constexpr auto subrange =
[](auto first, auto last) { return basic_view{std::move(first), last}; };

}

} // oel

#if OEL_STD_RANGES

template< typename I, typename S >
inline constexpr bool std::ranges::enable_borrowed_range< oel::basic_view<I, S> > = true;
inline constexpr bool std::ranges::enable_borrowed_range< oel::view::subrange<I, S> > = true;

template< typename I, typename S >
inline constexpr bool std::ranges::enable_view< oel::basic_view<I, S> > = true;
inline constexpr bool std::ranges::enable_view< oel::view::subrange<I, S> > = true;

#endif

0 comments on commit ec2ea9b

Please sign in to comment.