Skip to content

Commit

Permalink
view::generate
Browse files Browse the repository at this point in the history
  • Loading branch information
OleErikPeistorpet committed Jun 8, 2024
1 parent 922f1d0 commit 5812977
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 3 deletions.
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ Should be something like:

for (int i{}; i < outerLimit; i++)
{
auto v = std::views::iota(0, innerLimit)
| oel::view::transform([i](auto j) { return i * j; });
arr.append(v);
auto fn = [i, j = 0]() mutable { return i * j++; };
arr.append(oel::view::generate(fn, innerLimit));
}

Another good way, using `resize_for_overwrite`:
Expand Down
22 changes: 22 additions & 0 deletions unit_test/view_gtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,25 @@ TEST(viewTest, viewTransformAsOutput)
EXPECT_EQ(-2, test[1].second);
}

struct Ints
{
int i;

int operator()() { return i++; }
};

TEST(viewTest, viewGenerate)
{
auto d = view::generate(Ints{1}, 2) | oel::to_dynarray();

ASSERT_EQ(2U, d.size());
EXPECT_EQ(1, d[0]);
EXPECT_EQ(2, d[1]);

d.assign(oel::view::generate(Ints{}, 0));
EXPECT_TRUE(d.empty());
}

TEST(viewTest, viewMoveEndDifferentType)
{
auto nonEmpty = [i = -1](int j) { return i + j; };
Expand All @@ -265,6 +284,9 @@ TEST(viewTest, viewMoveMutableEmptyAndSize)
EXPECT_EQ(1U, v.size());
}

using IntGenIter = oel::iterator_t<decltype( view::generate(Ints{}, 0) )>;
static_assert(std::input_or_output_iterator<IntGenIter>);

TEST(viewTest, chainWithStd)
{
auto f = [](int i) { return -i; };
Expand Down
51 changes: 51 additions & 0 deletions view/generate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#pragma once

// Copyright 2021 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 "counted.h"
#include "../auxi/assignable.h"

/** @file
*/

namespace oel
{

template< typename Generator >
class _generateIterator
{
typename _detail::AssignableWrap<Generator>::Type _g;

public:
using iterator_category = std::input_iterator_tag;
using reference = decltype( std::declval<Generator &>()() );
using pointer = void;
using value_type = std::remove_cv_t< std::remove_reference_t<reference> >;
using difference_type = ptrdiff_t;

constexpr explicit _generateIterator(Generator g) : _g{std::move(g)} {}

constexpr reference operator*()
{
return static_cast<Generator &>(_g)();
}

constexpr _generateIterator & operator++() OEL_ALWAYS_INLINE { return *this; }
constexpr void operator++(int) & OEL_ALWAYS_INLINE {}
};


namespace view
{
//! Returns a view that generates `count` elements by calling the given generator function
/**
* Like `generate_n` in the Range-v3 library, but this is only for use within OE-Lib. */
inline constexpr auto generate =
[](auto generator, ptrdiff_t count) { return counted(_generateIterator{std::move(generator)}, count); };
}

} // oel
1 change: 1 addition & 0 deletions views.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/

#include "view/counted.h"
#include "view/generate.h"
#include "view/move.h"
#include "view/owning.h"
#include "view/subrange.h"
Expand Down

0 comments on commit 5812977

Please sign in to comment.