Skip to content

Commit 359b5bc

Browse files
committed
Removed code using std::vector
1 parent ffcc80f commit 359b5bc

File tree

2 files changed

+20
-128
lines changed

2 files changed

+20
-128
lines changed

include/flux/adaptor/permutations.hpp

+9-111
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "flux/core/concepts.hpp"
88
#include "flux/core/inline_sequence_base.hpp"
99
#include "flux/adaptor/permutations_base.hpp"
10+
#include "flux/adaptor/cartesian_base.hpp" // tuple_repeated_t
1011
#include <cstddef>
1112
#include <flux/core.hpp>
1213
#include <numeric>
@@ -16,63 +17,12 @@ namespace flux {
1617
namespace detail {
1718

1819
template <flux::sequence Base, flux::distance_t SubsequenceSize>
19-
requires flux::bounded_sequence<Base> && (SubsequenceSize > 0)
20+
requires(SubsequenceSize > 0) && flux::bounded_sequence<Base> && flux::multipass_sequence<Base>
2021
struct permutations_adaptor
2122
: public flux::inline_sequence_base<permutations_adaptor<Base, SubsequenceSize>> {
2223
private:
2324
Base base_;
2425

25-
// Uninitialized: Input sequence is not cached, output can't be generated
26-
// Cached: Input sequence is cached (copied) into the cache_ member variable
27-
enum class state_t { Uninitialized, Cached };
28-
state_t state_ {state_t::Uninitialized};
29-
30-
using inner_value_t = flux::value_t<Base>;
31-
std::vector<inner_value_t> cache_;
32-
std::size_t size_;
33-
34-
[[nodiscard]] constexpr std::size_t count_permutations()
35-
{
36-
if (not is_cached()) {
37-
cache_base();
38-
}
39-
40-
return size_;
41-
}
42-
43-
[[nodiscard]] constexpr bool is_cached() const noexcept { return state_ == state_t::Cached; }
44-
45-
constexpr auto cache_base() -> void
46-
{
47-
for (const auto elem : base_) {
48-
cache_.emplace_back(elem);
49-
}
50-
51-
if (SubsequenceSize <= cache_.size()) {
52-
size_ = factorial(cache_.size()) / factorial(cache_.size() - SubsequenceSize);
53-
} else {
54-
size_ = 0;
55-
}
56-
57-
state_ = state_t::Cached;
58-
}
59-
60-
constexpr auto cache_base() -> void
61-
requires flux::sized_sequence<Base>
62-
{
63-
const auto size = static_cast<std::size_t>(flux::size(base_));
64-
cache_.resize(size);
65-
std::ranges::copy(base_, cache_.begin());
66-
67-
if (SubsequenceSize <= size) {
68-
size_ = factorial(cache_.size()) / factorial(cache_.size() - SubsequenceSize);
69-
} else {
70-
size_ = 0;
71-
}
72-
73-
state_ = state_t::Cached;
74-
}
75-
7626
public:
7727
constexpr permutations_adaptor(Base&& base) : base_(std::move(base)) { }
7828

@@ -81,9 +31,6 @@ struct permutations_adaptor
8131
using self_t = permutations_adaptor;
8232

8333
struct cursor_type {
84-
// TODO: remove vector type
85-
std::vector<std::size_t> indices_;
86-
std::vector<std::size_t> cycles_;
8734
std::size_t permutation_index_;
8835

8936
[[nodiscard]] constexpr auto operator<=>(const cursor_type& other) const
@@ -98,58 +45,23 @@ struct permutations_adaptor
9845

9946
public:
10047
// TODO: remove vector type
101-
using value_type = std::vector<inner_value_t>;
48+
using value_type = tuple_repeated_t<value_t<Base>, SubsequenceSize>;
10249

10350
inline static constexpr bool is_infinite = false;
10451

10552
static constexpr auto first(self_t& self) -> cursor_type
10653
{
107-
if (not self.is_cached()) {
108-
self.cache_base();
109-
}
110-
111-
// variable alias for readability
112-
const auto base_length = self.cache_.size();
113-
114-
// Set indices to range [0, 1, ..., size-1]
115-
std::vector<std::size_t> indices(base_length);
116-
std::iota(indices.begin(), indices.end(), 0);
117-
118-
// Set cycles to [i, i+1, ..., size] where i = size - subsequence_size
119-
std::vector<std::size_t> cycles(SubsequenceSize);
120-
std::iota(cycles.rbegin(), cycles.rend(), base_length - SubsequenceSize);
121-
122-
// return the cursor
123-
return {.indices_ = indices, .cycles_ = cycles, .permutation_index_ = 0};
124-
}
125-
126-
static constexpr auto last(self_t& self) -> cursor_type
127-
{
128-
if (not self.is_cached()) {
129-
self.cache_base();
130-
}
131-
132-
// variable aliases for readability
133-
const auto base_length = self.cache_.size();
134-
135-
// fill up the indices from 0 to size-1 in reverse because it's the end
136-
std::vector<std::size_t> indices(base_length);
137-
std::iota(indices.rbegin(), indices.rend(), 0);
138-
139-
// fill up the cycles with 0s because it's the end
140-
std::vector<std::size_t> cycles(SubsequenceSize, 0);
141-
142-
// return the cursor
143-
return {.indices_ = indices, .cycles_ = cycles, .permutation_index_ = self.count_permutations()};
54+
return {.permutation_index_ = 0};
14455
}
14556

14657
static constexpr auto is_last(self_t& self, const cursor_type& cursor) -> bool
14758
{
148-
return cursor.permutation_index_ >= self.count_permutations();
59+
return false;
14960
}
15061

15162
static constexpr auto inc(self_t& self, cursor_type& cursor) -> void
15263
{
64+
/*
15365
const auto k = SubsequenceSize;
15466
const auto n = self.cache_.size();
15567
@@ -167,26 +79,12 @@ struct permutations_adaptor
16779
return;
16880
}
16981
}
82+
*/
17083
}
17184

17285
static constexpr auto read_at(self_t& self, const cursor_type& cursor) -> value_type
17386
{
174-
if (not self.is_cached()) {
175-
self.cache_base();
176-
}
177-
return reindex_vec<inner_value_t>(self.cache_, cursor.indices_, SubsequenceSize);
178-
}
179-
180-
static constexpr auto read_at_unchecked(self_t& self, const cursor_type& cursor)
181-
-> value_type
182-
{
183-
return reindex_vec<inner_value_t>(self.cache_, cursor.indices_, SubsequenceSize);
184-
}
185-
186-
static constexpr auto size(self_t& self) -> flux::distance_t
187-
requires flux::sized_sequence<Base>
188-
{
189-
return self.count_permutations();
87+
return {};
19088
}
19189
};
19290
};
@@ -197,7 +95,7 @@ struct permutations_fn {
19795
template <sequence Seq>
19896
requires(not infinite_sequence<Seq>)
19997
[[nodiscard]]
200-
constexpr auto operator()(Seq&& seq) const -> sized_sequence auto
98+
constexpr auto operator()(Seq&& seq) const -> auto
20199
{
202100
return permutations_adaptor<std::decay_t<Seq>, SubsequenceSize>(FLUX_FWD(seq));
203101
}

test/test_permutations.cpp

+11-17
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ auto test_permutations_types() -> bool
2525
// Sequence
2626
static_assert(flux::sequence<SeqType>);
2727
static_assert(flux::multipass_sequence<SeqType>);
28-
static_assert(flux::bounded_sequence<SeqType>);
29-
static_assert(flux::sized_sequence<SeqType>);
28+
// static_assert(flux::bounded_sequence<SeqType>);
29+
// static_assert(flux::sized_sequence<SeqType>);
3030
static_assert(not flux::infinite_sequence<SeqType>);
3131
static_assert(not flux::random_access_sequence<SeqType>);
3232
static_assert(not flux::contiguous_sequence<SeqType>);
@@ -36,10 +36,10 @@ auto test_permutations_types() -> bool
3636
static_assert(flux::ordered_cursor<CurType>);
3737

3838
// Elements
39-
static_assert(std::same_as<flux::element_t<SeqType>, std::vector<int>>);
40-
static_assert(std::same_as<flux::value_t<SeqType>, std::vector<int>>);
41-
static_assert(flux::random_access_sequence<flux::element_t<SeqType>>);
42-
static_assert(flux::random_access_sequence<flux::value_t<SeqType>>);
39+
// static_assert(std::same_as<flux::element_t<SeqType>, std::vector<int>>);
40+
// static_assert(std::same_as<flux::value_t<SeqType>, std::vector<int>>);
41+
// static_assert(flux::random_access_sequence<flux::element_t<SeqType>>);
42+
// static_assert(flux::random_access_sequence<flux::value_t<SeqType>>);
4343

4444
return true;
4545
}
@@ -52,14 +52,14 @@ constexpr auto test_permutations() -> bool
5252
auto seq = flux::mut_ref(arr).permutations<3>();
5353

5454
// Sizes
55-
STATIC_CHECK(seq.size() == 6);
55+
// STATIC_CHECK(seq.size() == 6);
5656

5757
auto cur = flux::first(seq);
5858
auto test_comp = std::array {1, 2, 3};
5959

6060
// Forward Iteration Permutations
6161
while (not flux::is_last(seq, cur)) {
62-
STATIC_CHECK(check_equal(flux::read_at(seq, cur), test_comp));
62+
// STATIC_CHECK(check_equal(flux::read_at(seq, cur), test_comp));
6363

6464
flux::inc(seq, cur);
6565
std::ranges::next_permutation(test_comp);
@@ -95,7 +95,7 @@ constexpr auto compare_permutations_with_python_itertools() -> bool
9595
auto p = flux::read_at(permutations, first);
9696
auto r = flux::ref(reference.at(static_cast<size_t>(i)));
9797

98-
STATIC_CHECK(check_equal(p, r));
98+
// STATIC_CHECK(check_equal(p, r));
9999

100100
flux::inc(permutations, first);
101101
}
@@ -107,12 +107,6 @@ constexpr auto compare_permutations_with_python_itertools() -> bool
107107

108108
TEST_CASE("permutations")
109109
{
110-
bool types = test_permutations_types();
111-
REQUIRE(types);
112-
113-
bool functionality = test_permutations();
114-
REQUIRE(functionality);
115-
116-
bool comparison = compare_permutations_with_python_itertools();
117-
REQUIRE(comparison);
110+
auto implementation = false;
111+
REQUIRE(implementation);
118112
}

0 commit comments

Comments
 (0)