Skip to content

Commit

Permalink
Add ranges::fill, ranges::fill_n (#41)
Browse files Browse the repository at this point in the history
* Add ranges::fill, ranges::fill_n

* Update algorithm_ranges.cc

* Update algorithm_ranges.cc
  • Loading branch information
lackhole committed Aug 24, 2024
1 parent 6b9405f commit edc98d7
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 7 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ Implementation available in C++14 ~ :

| Header | Total | | C++17 | C++20 | C++23 | C++26 |
|-------------------------------------|---------------------------------------------------------|---|--------------------------------------------------------|---------------------------------------------------------|--------------------------------------------------------|--------------------------------------------------------|
| | ![](https://img.shields.io/badge/306/691-grey)![][p044] | | ![](https://img.shields.io/badge/44/113-grey)![][p039] | ![](https://img.shields.io/badge/229/429-grey)![][p053] | ![](https://img.shields.io/badge/59/144-grey)![][p041] | ![](https://img.shields.io/badge/13/132-grey)![][p010] |
| | ![](https://img.shields.io/badge/308/691-grey)![][p045] | | ![](https://img.shields.io/badge/44/113-grey)![][p039] | ![](https://img.shields.io/badge/231/429-grey)![][p054] | ![](https://img.shields.io/badge/59/144-grey)![][p041] | ![](https://img.shields.io/badge/15/132-grey)![][p011] |
| | | | | | | |
| [algorithm](#algorithm) | ![](https://img.shields.io/badge/51/115-grey)![][p044] | | ![](https://img.shields.io/badge/2/4-grey)![][p050] | ![](https://img.shields.io/badge/43/96-grey)![][p045] | ![](https://img.shields.io/badge/8/18-grey)![][p044] | ![](https://img.shields.io/badge/5/23-grey)![][p022] |
| [algorithm](#algorithm) | ![](https://img.shields.io/badge/53/115-grey)![][p046] | | ![](https://img.shields.io/badge/2/4-grey)![][p050] | ![](https://img.shields.io/badge/45/96-grey)![][p047] | ![](https://img.shields.io/badge/8/18-grey)![][p044] | ![](https://img.shields.io/badge/7/23-grey)![][p030] |
| [array](#array) | ![](https://img.shields.io/badge/1/1-grey)![][p100] | | | ![](https://img.shields.io/badge/1/1-grey)![][p100] | | |
| [bit](#bit) | ![](https://img.shields.io/badge/1/14-grey)![][p007] | | | ![](https://img.shields.io/badge/1/13-grey)![][p008] | ![](https://img.shields.io/badge/0/1-grey)![][p000] | |
| [concepts](#concepts) | ![](https://img.shields.io/badge/30/30-grey)![][p100] | | | ![](https://img.shields.io/badge/30/30-grey)![][p100] | ![](https://img.shields.io/badge/1/1-grey)![][p100] | |
Expand Down Expand Up @@ -235,8 +235,8 @@ Description
| `ranges::copy_backward` | ![][c20ok] | |
| `ranges::move` | ![][c20no] | |
| `ranges::move_backward` | ![][c20no] | |
| `ranges::fill` | ![][c20no] | ![][c26no] |
| `ranges::fill_n` | ![][c20no] | ![][c26no] |
| `ranges::fill` | ![][c20ok] | ![][c26ok] |
| `ranges::fill_n` | ![][c20ok] | ![][c26ok] |
| `ranges::transform` | ![][c20no] | |
| `ranges::generate` | ![][c20no] | |
| `ranges::generate_n` | ![][c20no] | |
Expand Down
7 changes: 4 additions & 3 deletions include/preview/__algorithm/ranges/equal.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "preview/__ranges/end.h"
#include "preview/__ranges/input_range.h"
#include "preview/__ranges/iterator_t.h"
#include "preview/__ranges/range_value_t.h"
#include "preview/__type_traits/conjunction.h"

namespace preview {
Expand Down Expand Up @@ -85,21 +86,21 @@ struct equal_niebloid {
}

template<
typename T,
typename R2,
typename T = range_value_t<R2>,
typename Pred = equal_to,
typename Proj1 = identity, typename Proj2 = identity,
std::enable_if_t<check_range<std::initializer_list<T>, R2, Pred, Proj1, Proj2>::value, int> = 0
>
PREVIEW_NODISCARD constexpr bool
operator()(std::initializer_list<T>&& il, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const {
operator()(std::initializer_list<T> il, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const {
return (*this)(ranges::begin(il), ranges::end(il), ranges::begin(r2), ranges::end(r2),
std::ref(pred), std::ref(proj1), std::ref(proj2));
}

template<
typename R1,
typename U,
typename U = range_value_t<R1>,
typename Pred = equal_to,
typename Proj1 = identity, typename Proj2 = identity,
std::enable_if_t<check_range<R1, std::initializer_list<U>, Pred, Proj1, Proj2>::value, int> = 0
Expand Down
52 changes: 52 additions & 0 deletions include/preview/__algorithm/ranges/fill.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// Created by yonggyulee on 2024. 8. 24.
//

#ifndef PREVIEW_ALGORITHM_RANGES_FILL_H_
#define PREVIEW_ALGORITHM_RANGES_FILL_H_

#include <type_traits>

#include "preview/__core/inline_variable.h"
#include "preview/__iterator/iter_value_t.h"
#include "preview/__iterator/output_iterator.h"
#include "preview/__iterator/sentinel_for.h"
#include "preview/__ranges/begin.h"
#include "preview/__ranges/borrowed_iterator_t.h"
#include "preview/__ranges/end.h"
#include "preview/__ranges/output_range.h"
#include "preview/__ranges/range_value_t.h"
#include "preview/__type_traits/conjunction.h"

namespace preview {
namespace ranges {
namespace detail {

struct fill_niebloid {
template<typename O, typename S, typename T = iter_value_t<O>, std::enable_if_t<conjunction<
sentinel_for<S, O>,
output_iterator<O, const T&>
>::value, int> = 0>
constexpr O operator()(O first, S last, const T& value) const {
// Must not use std::memset because it may be optimized away by the compiler
while (first != last)
*first++ = value;
return first;
}

template<typename R, typename T = range_value_t<R>, std::enable_if_t<
output_range<R, const T&>
::value, int> = 0>
constexpr borrowed_iterator_t<R> operator()(R&& r, const T& value) const {
return (*this)(ranges::begin(r), ranges::end(r), value);
}
};

} // namespace detail

PREVIEW_INLINE_VARIABLE constexpr detail::fill_niebloid fill{};

} // namespace ranges
} // namespace preview

#endif // PREVIEW_ALGORITHM_RANGES_FILL_H_
40 changes: 40 additions & 0 deletions include/preview/__algorithm/ranges/fill_n.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// Created by yonggyulee on 2024. 8. 24.
//

#ifndef PREVIEW_ALGORITHM_RANGES_FILL_N_H_
#define PREVIEW_ALGORITHM_RANGES_FILL_N_H_

#include <type_traits>

#include "preview/__core/inline_variable.h"
#include "preview/__iterator/iter_difference_t.h"
#include "preview/__iterator/iter_value_t.h"
#include "preview/__iterator/output_iterator.h"

namespace preview {
namespace ranges {
namespace detail {

struct fill_n_niebloid {
template<typename O, typename T = iter_value_t<O>, std::enable_if_t<
output_iterator<O, const T&>
::value, int> = 0>
constexpr O operator()(O first, iter_difference_t<O> n, const T& value) const {
while (n != 0) {
*first = value;
++first;
--n;
}
return first;
}
};

} // namespace detail

PREVIEW_INLINE_VARIABLE constexpr detail::fill_n_niebloid fill_n{};

} // namespace ranges
} // namespace preview

#endif // PREVIEW_ALGORITHM_RANGES_FILL_N_H_
2 changes: 2 additions & 0 deletions include/preview/algorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "preview/__algorithm/ranges/count.h"
#include "preview/__algorithm/ranges/count_if.h"
#include "preview/__algorithm/ranges/equal.h"
#include "preview/__algorithm/ranges/fill.h"
#include "preview/__algorithm/ranges/fill_n.h"
#include "preview/__algorithm/ranges/find.h"
#include "preview/__algorithm/ranges/find_end.h"
#include "preview/__algorithm/ranges/find_first_of.h"
Expand Down
33 changes: 33 additions & 0 deletions test/algorithm_ranges.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,39 @@ TEST(VERSIONED(AlgorithmRanges), any_of) {
EXPECT_FALSE(ranges::any_of(v, DivisibleBy(11)));
}

TEST(VERSIONED(AlgorithmRanges), fill) {
std::vector<int> v{0, 1, 2, 3, 4, 5};

// set all elements to -1 using overload (1)
ranges::fill(v.begin(), v.end(), -1);
EXPECT_TRUE(ranges::equal(v, std::vector<int>(v.size(), -1)));

// set all element to 10 using overload (2)
ranges::fill(v, 10);
EXPECT_TRUE(ranges::equal(v, views::repeat(10, v.size())));

std::vector<std::complex<double>> nums{{1, 3}, {2, 2}, {4, 8}};
ranges::fill(nums, {4, 2}); // T gets deduced
EXPECT_TRUE(ranges::equal(nums, {{4, 2}, {4, 2}, {4, 2}}));
}

TEST(VERSIONED(AlgorithmRanges), fill_n) {
constexpr auto n{8};

std::vector<std::string> v(n, "AB");
ranges::fill_n(v.begin(), n, "BA");
EXPECT_TRUE(ranges::equal(v, views::repeat("BA"s, n)));

std::vector<std::complex<double>> nums{{1, 3}, {2, 2}, {4, 8}};
ranges::fill_n(nums.begin(), 2, {4, 2});
EXPECT_TRUE(ranges::equal(nums, {{4, 2}, {4, 2}, {4, 8}}));

std::vector<int> v2;
ranges::fill_n(std::back_inserter(v2), n, 100);
EXPECT_EQ(v2.size(), n);
EXPECT_TRUE(ranges::equal(v2, views::repeat(100, n)));
}

TEST(VERSIONED(AlgorithmRanges), for_each) {
std::vector<int> nums {3, 4, 2, 8, 15, 267};
auto print = [](const auto& n) { std::cout << ' ' << n; };
Expand Down

0 comments on commit edc98d7

Please sign in to comment.