Skip to content

Commit

Permalink
Correctly constrain inline_iter_base member fns
Browse files Browse the repository at this point in the history
  • Loading branch information
tcbrindle committed Dec 14, 2024
1 parent 588ef04 commit a3f7a4e
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 37 deletions.
1 change: 1 addition & 0 deletions include/flux/adaptor/chunk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ FLUX_EXPORT inline constexpr auto chunk = detail::chunk_fn{};

template <typename D>
constexpr auto inline_iter_base<D>::chunk(num::integral auto chunk_sz) &&
requires sequence<D>
{
return flux::chunk(std::move(derived()), chunk_sz);
}
Expand Down
5 changes: 3 additions & 2 deletions include/flux/adaptor/flatten_with.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <flux/core.hpp>

#include <flux/adaptor/map.hpp>
#include <flux/sequence/single.hpp>

namespace flux {
Expand Down Expand Up @@ -409,7 +410,7 @@ FLUX_EXPORT inline constexpr auto flatten_with = detail::flatten_with_fn{};

template <typename Derived>
template <adaptable_sequence Pattern>
requires sequence<element_t<Derived>> &&
requires iterable<element_t<Derived>> &&
multipass_sequence<Pattern> &&
detail::flatten_with_compatible<element_t<Derived>, Pattern>
constexpr auto inline_iter_base<Derived>::flatten_with(Pattern&& pattern) &&
Expand All @@ -419,7 +420,7 @@ constexpr auto inline_iter_base<Derived>::flatten_with(Pattern&& pattern) &&

template <typename Derived>
template <typename Value>
requires sequence<element_t<Derived>> &&
requires iterable<element_t<Derived>> &&
std::constructible_from<value_t<element_t<Derived>>, Value&&>
constexpr auto inline_iter_base<Derived>::flatten_with(Value value) &&
{
Expand Down
2 changes: 2 additions & 0 deletions include/flux/adaptor/split_string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#ifndef FLUX_ADAPTOR_STRING_SPLIT_HPP_INCLUDED
#define FLUX_ADAPTOR_STRING_SPLIT_HPP_INCLUDED

#include "flux/core/concepts.hpp"
#include <flux/adaptor/split.hpp>
#include <flux/core/utils.hpp>

Expand Down Expand Up @@ -62,6 +63,7 @@ FLUX_EXPORT inline constexpr auto split_string = detail::split_string_fn{};

template <typename D>
constexpr auto inline_iter_base<D>::split_string(auto&& pattern) &&
requires multipass_sequence<D>
{
return flux::split_string(std::move(derived()), FLUX_FWD(pattern));
}
Expand Down
4 changes: 3 additions & 1 deletion include/flux/algorithm/ends_with.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#ifndef FLUX_ALGORITHM_ENDS_WITH_HPP_INCLUDED
#define FLUX_ALGORITHM_ENDS_WITH_HPP_INCLUDED

#include <flux/adaptor/stride.hpp>
#include <flux/algorithm/count.hpp>
#include <flux/algorithm/equal.hpp>

Expand Down Expand Up @@ -88,7 +89,8 @@ FLUX_EXPORT inline constexpr auto ends_with = detail::ends_with_fn{};

template <typename Derived>
template <sequence Needle, typename Cmp>
requires std::predicate<Cmp&, element_t<Derived>, element_t<Needle>> &&
requires sequence<Derived> &&
std::predicate<Cmp&, element_t<Derived>, element_t<Needle>> &&
(multipass_sequence<Derived> || sized_iterable<Derived>) &&
(multipass_sequence<Needle> || sized_iterable<Needle>)
constexpr auto inline_iter_base<Derived>::ends_with(Needle&& needle, Cmp cmp) -> bool
Expand Down
11 changes: 7 additions & 4 deletions include/flux/algorithm/find.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct find_fn {
requires std::equality_comparable_with<element_t<Seq>, Value const&>
constexpr auto operator()(Seq&& seq, Value const& value) const -> cursor_t<Seq>
{
constexpr auto can_memchr =
constexpr auto can_memchr =
contiguous_sequence<Seq> && sized_iterable<Seq> &&
std::same_as<Value, value_t<Seq>> &&
flux::detail::any_of<value_t<Seq>, char, signed char, unsigned char, char8_t, std::byte>;
Expand Down Expand Up @@ -91,23 +91,26 @@ FLUX_EXPORT inline constexpr auto find_if_not = detail::find_if_not_fn{};

template <typename D>
template <typename Value>
requires std::equality_comparable_with<element_t<D>, Value const&>
requires sequence<D> &&
std::equality_comparable_with<element_t<D>, Value const&>
constexpr auto inline_iter_base<D>::find(Value const& val)
{
return flux::find(derived(), val);
}

template <typename D>
template <typename Pred>
requires std::predicate<Pred&, element_t<D>>
requires sequence<D> &&
std::predicate<Pred&, element_t<D>>
constexpr auto inline_iter_base<D>::find_if(Pred pred)
{
return flux::find_if(derived(), std::ref(pred));
}

template <typename D>
template <typename Pred>
requires std::predicate<Pred&, element_t<D>>
requires sequence<D> &&
std::predicate<Pred&, element_t<D>>
constexpr auto inline_iter_base<D>::find_if_not(Pred pred)
{
return flux::find_if_not(derived(), std::ref(pred));
Expand Down
6 changes: 3 additions & 3 deletions include/flux/algorithm/find_min_max.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,23 @@ FLUX_EXPORT inline constexpr auto find_minmax = detail::find_minmax_fn{};

template <typename D>
template <typename Cmp>
requires weak_ordering_for<Cmp, D>
requires sequence<D> && weak_ordering_for<Cmp, D>
constexpr auto inline_iter_base<D>::find_min(Cmp cmp)
{
return flux::find_min(derived(), std::move(cmp));
}

template <typename D>
template <typename Cmp>
requires weak_ordering_for<Cmp, D>
requires sequence<D> && weak_ordering_for<Cmp, D>
constexpr auto inline_iter_base<D>::find_max(Cmp cmp)
{
return flux::find_max(derived(), std::move(cmp));
}

template <typename D>
template <typename Cmp>
requires weak_ordering_for<Cmp, D>
requires sequence<D> && weak_ordering_for<Cmp, D>
constexpr auto inline_iter_base<D>::find_minmax(Cmp cmp)
{
return flux::find_minmax(derived(), std::move(cmp));
Expand Down
2 changes: 1 addition & 1 deletion include/flux/algorithm/starts_with.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace flux {
namespace detail {

struct starts_with_fn {
template <sequence Haystack, sequence Needle, typename Cmp = std::ranges::equal_to>
template <iterable Haystack, sequence Needle, typename Cmp = std::ranges::equal_to>
requires std::predicate<Cmp&, element_t<Haystack>, element_t<Needle>>
constexpr auto operator()(Haystack&& haystack, Needle&& needle, Cmp cmp = Cmp{}) const -> bool
{
Expand Down
83 changes: 57 additions & 26 deletions include/flux/core/inline_iter_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,35 +40,59 @@ struct inline_iter_base {

/// Returns a cursor pointing to the first element of the sequence
[[nodiscard]]
constexpr auto first() { return flux::first(derived()); }
constexpr auto first()
requires sequence<Derived>
{
return flux::first(derived());
}

/// Returns true if `cur` points to the end of the sequence
///
/// @param cur The cursor to test
template <std::same_as<Derived> D = Derived>
requires sequence<Derived>
[[nodiscard]]
constexpr bool is_last(cursor_t<D> const& cur) { return flux::is_last(derived(), cur); }
constexpr bool is_last(cursor_t<D> const& cur)
{
return flux::is_last(derived(), cur);
}

/// Increments the given cursor
///
/// @param cur the cursor to increment
template <std::same_as<Derived> D = Derived>
constexpr auto& inc(cursor_t<D>& cur) { return flux::inc(derived(), cur); }
requires sequence<Derived>
constexpr auto& inc(cursor_t<D>& cur)
{
return flux::inc(derived(), cur);
}

/// Returns the element at the given cursor
template <std::same_as<Derived> D = Derived>
requires sequence<Derived>
[[nodiscard]]
constexpr decltype(auto) read_at(cursor_t<D> const& cur) { return flux::read_at(derived(), cur); }
constexpr decltype(auto) read_at(cursor_t<D> const& cur)
{
return flux::read_at(derived(), cur);
}

/// Returns an rvalue version of the element at the given cursor
template <std::same_as<Derived> D = Derived>
requires sequence<Derived>
[[nodiscard]]
constexpr decltype(auto) move_at(cursor_t<D> const& cur) { return flux::move_at(derived(), cur); }
constexpr decltype(auto) move_at(cursor_t<D> const& cur)
{
return flux::move_at(derived(), cur);
}

/// Returns the element at the given cursor
template <std::same_as<Derived> D = Derived>
requires sequence<Derived>
[[nodiscard]]
constexpr decltype(auto) operator[](cursor_t<D> const& cur) { return flux::read_at(derived(), cur); }
constexpr decltype(auto) operator[](cursor_t<D> const& cur)
{
return flux::read_at(derived(), cur);
}

/// Returns an cursor pointing to one past the last element of the sequence
[[nodiscard]]
Expand Down Expand Up @@ -138,8 +162,12 @@ struct inline_iter_base {
}

template <std::same_as<Derived> D = Derived>
requires sequence<Derived>
[[nodiscard]]
constexpr auto next(cursor_t<D> cur) { return flux::next(derived(), cur); }
constexpr auto next(cursor_t<D> cur)
{
return flux::next(derived(), cur);
}

template <std::same_as<Derived> D = Derived>
requires bidirectional_sequence<Derived>
Expand Down Expand Up @@ -209,11 +237,13 @@ struct inline_iter_base {
/*
* Iterator support
*/
constexpr auto begin() &;
constexpr auto begin() &
requires sequence<Derived>;

constexpr auto begin() const& requires sequence<Derived const>;

constexpr auto end() &;
constexpr auto end() &
requires sequence<Derived>;

constexpr auto end() const& requires sequence<Derived const>;

Expand Down Expand Up @@ -242,7 +272,8 @@ struct inline_iter_base {
(multipass_sequence<Derived> && not infinite_sequence<Derived>);

[[nodiscard]]
constexpr auto chunk(num::integral auto chunk_sz) &&;
constexpr auto chunk(num::integral auto chunk_sz) &&
requires sequence<Derived>;

template <typename Pred>
requires multipass_sequence<Derived> &&
Expand Down Expand Up @@ -291,16 +322,14 @@ struct inline_iter_base {
constexpr auto flatten() && requires iterable<element_t<Derived>>;

template <adaptable_sequence Pattern>
requires sequence<element_t<Derived>> &&
multipass_sequence<Pattern> &&
detail::flatten_with_compatible<element_t<Derived>, Pattern>
requires iterable<element_t<Derived>> && multipass_sequence<Pattern>
&& detail::flatten_with_compatible<element_t<Derived>, Pattern>
[[nodiscard]]
constexpr auto flatten_with(Pattern&& pattern) &&;


template <typename Value>
requires sequence<element_t<Derived>> &&
std::constructible_from<value_t<element_t<Derived>>, Value&&>
requires iterable<element_t<Derived>>
&& std::constructible_from<value_t<element_t<Derived>>, Value&&>
[[nodiscard]]
constexpr auto flatten_with(Value value) &&;

Expand Down Expand Up @@ -368,7 +397,8 @@ struct inline_iter_base {

template <typename Pattern>
[[nodiscard]]
constexpr auto split_string(Pattern&& pattern) &&;
constexpr auto split_string(Pattern&& pattern) &&
requires multipass_sequence<Derived>;

[[nodiscard]]
constexpr auto stride(num::integral auto by) &&;
Expand Down Expand Up @@ -411,9 +441,9 @@ struct inline_iter_base {
constexpr auto count_if(Pred pred);

template <sequence Needle, typename Cmp = std::ranges::equal_to>
requires std::predicate<Cmp&, element_t<Derived>, element_t<Needle>> &&
(multipass_sequence<Derived> || sized_iterable<Derived>) &&
(multipass_sequence<Needle> || sized_iterable<Needle>)
requires sequence<Derived> && std::predicate<Cmp&, element_t<Derived>, element_t<Needle>>
&& (multipass_sequence<Derived> || sized_iterable<Derived>)
&& (multipass_sequence<Needle> || sized_iterable<Needle>)
constexpr auto ends_with(Needle&& needle, Cmp cmp = {}) -> bool;

template <typename Value>
Expand All @@ -422,32 +452,33 @@ struct inline_iter_base {

/// Returns a cursor pointing to the first occurrence of `value` in the sequence
template <typename Value>
requires std::equality_comparable_with<element_t<Derived>, Value const&>
requires sequence<Derived>
&& std::equality_comparable_with<element_t<Derived>, Value const&>
[[nodiscard]]
constexpr auto find(Value const&);

template <typename Pred>
requires std::predicate<Pred&, element_t<Derived>>
requires sequence<Derived> && std::predicate<Pred&, element_t<Derived>>
[[nodiscard]]
constexpr auto find_if(Pred pred);

template <typename Pred>
requires std::predicate<Pred&, element_t<Derived>>
requires sequence<Derived> && std::predicate<Pred&, element_t<Derived>>
[[nodiscard]]
constexpr auto find_if_not(Pred pred);

template <typename Cmp = std::compare_three_way>
requires weak_ordering_for<Cmp, Derived>
requires sequence<Derived> && weak_ordering_for<Cmp, Derived>
[[nodiscard]]
constexpr auto find_max(Cmp cmp = Cmp{});

template <typename Cmp = std::compare_three_way>
requires weak_ordering_for<Cmp, Derived>
requires sequence<Derived> && weak_ordering_for<Cmp, Derived>
[[nodiscard]]
constexpr auto find_min(Cmp cmp = Cmp{});

template <typename Cmp = std::compare_three_way>
requires weak_ordering_for<Cmp, Derived>
requires sequence<Derived> && weak_ordering_for<Cmp, Derived>
[[nodiscard]]
constexpr auto find_minmax(Cmp cmp = Cmp{});

Expand Down
2 changes: 2 additions & 0 deletions include/flux/core/sequence_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ FLUX_EXPORT inline constexpr auto end = detail::end_fn{};

template <typename D>
constexpr auto inline_iter_base<D>::begin() &
requires sequence<D>
{
return flux::begin(derived());
}
Expand All @@ -220,6 +221,7 @@ constexpr auto inline_iter_base<D>::begin() const&

template <typename D>
constexpr auto inline_iter_base<D>::end() &
requires sequence<D>
{
return flux::end(derived());
}
Expand Down

0 comments on commit a3f7a4e

Please sign in to comment.