Skip to content

Commit

Permalink
General cleanup; attempted ICE fix for MSVC
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickroberts committed Jan 13, 2025
1 parent 6ae9b50 commit a4bdb6a
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 17 deletions.
6 changes: 6 additions & 0 deletions include/pr/any_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class any_iterator : public detail::iterator_concept_trait<KindV> {
static constexpr any_kind kind = KindV;

template <class IteratorT, class SentinelT>
requires detail::convertible_to_any_iterator<IteratorT, SentinelT,
any_iterator>
constexpr any_iterator(IteratorT iterator, SentinelT sentinel)
: iterator_ptr_(in_place_iterator_type_<IteratorT, SentinelT>,
static_cast<IteratorT &&>(iterator),
Expand Down Expand Up @@ -105,8 +107,12 @@ class any_iterator : public detail::iterator_concept_trait<KindV> {
operator==(const any_iterator &other) const -> bool
requires forward_
{
#if defined __GNUG__
// explicit method call to prevent ambiguity
return iterator_ptr_->operator==(*other.iterator_ptr_);
#else
return *iterator_ptr_ == *other.iterator_ptr_;
#endif
}

constexpr auto operator--() -> any_iterator &
Expand Down
3 changes: 3 additions & 0 deletions include/pr/any_kind.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ enum class any_kind : unsigned char {
copyable = 0b01000000,
sized = 0b10000000,
common = random_access | sized,
// TODO: Is simple a better name to use than constant? any_view<T, simple>
// satisfies the exposition-only "simple-view", but does not (necessarily)
// satisfy constant_range
simple = constant,
// clang-format on
};
Expand Down
37 changes: 24 additions & 13 deletions include/pr/detail/concepts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@ template <class From, class To>
concept common_reference_same_as =
std::same_as<std::common_reference_t<From, To>, To>;

template <class IteratorT, any_kind KindV, class ReferenceT, class SentinelT>
template <class IteratorT, class SentinelT, any_kind KindV, class ReferenceT,
class DifferenceT>
concept models_iterator_of =
disables_or_models_contiguous_iterator<IteratorT, KindV> and
common_reference_same_as<std::iter_reference_t<IteratorT>, ReferenceT> and
std::convertible_to<std::iter_difference_t<IteratorT>, DifferenceT> and
std::sentinel_for<SentinelT, IteratorT>;

template <class RangeT, any_kind KindV>
Expand All @@ -59,12 +61,13 @@ template <class RangeT, any_kind KindV>
concept disables_or_models_sized_range =
disables_kind<KindV, any_kind::sized> or std::ranges::sized_range<RangeT>;

template <class MaybeConstantRangeT, any_kind KindV, class ReferenceT>
template <class MaybeConstantRangeT, any_kind KindV, class ReferenceT,
class DifferenceT>
concept models_range_of =
std::ranges::range<MaybeConstantRangeT> and
models_iterator_of<std::ranges::iterator_t<MaybeConstantRangeT>, KindV,
ReferenceT,
std::ranges::sentinel_t<MaybeConstantRangeT>> and
models_iterator_of<std::ranges::iterator_t<MaybeConstantRangeT>,
std::ranges::sentinel_t<MaybeConstantRangeT>, KindV,
ReferenceT, DifferenceT> and
disables_or_models_borrowed_range<MaybeConstantRangeT, KindV> and
disables_or_models_sized_range<MaybeConstantRangeT, KindV>;

Expand All @@ -77,16 +80,16 @@ using const_if_enabled_t =
std::conditional_t<detail::enables_kind(KindV, any_kind::constant),
const ViewT, ViewT>;

template <class ViewT, any_kind KindV, class ReferenceT>
concept models_view_of =
std::ranges::view<ViewT> and
models_range_of<const_if_enabled_t<ViewT, KindV>, KindV, ReferenceT> and
disables_or_models_copyable_range<ViewT, KindV>;
template <class ViewT, any_kind KindV, class ReferenceT, class DifferenceT>
concept models_view_of = std::ranges::view<ViewT> and
models_range_of<const_if_enabled_t<ViewT, KindV>,
KindV, ReferenceT, DifferenceT> and
disables_or_models_copyable_range<ViewT, KindV>;

template <class RangeT, any_kind KindV, class ReferenceT>
template <class RangeT, any_kind KindV, class ReferenceT, class DifferenceT>
concept models_viewable_range_of =
std::ranges::viewable_range<RangeT> and
models_view_of<std::views::all_t<RangeT>, KindV, ReferenceT>;
models_view_of<std::views::all_t<RangeT>, KindV, ReferenceT, DifferenceT>;

template <class T1, class T2>
inline constexpr bool is_instantiation_of_v = false;
Expand All @@ -98,11 +101,19 @@ inline constexpr bool is_instantiation_of_v<
AnyViewT<ElementT1, KindV1, ReferenceT1, DifferenceT1>,
AnyViewT<ElementT2, KindV2, ReferenceT2, DifferenceT2>> = true;

template <class IteratorT, class SentinelT, class AnyIteratorT>
concept convertible_to_any_iterator =
not is_instantiation_of_v<IteratorT, AnyIteratorT> and
models_iterator_of<IteratorT, SentinelT, AnyIteratorT::kind,
std::iter_reference_t<AnyIteratorT>,
std::iter_difference_t<AnyIteratorT>>;

template <class RangeT, class AnyViewT>
concept convertible_to_any_view =
not is_instantiation_of_v<std::decay_t<RangeT>, AnyViewT> and
models_viewable_range_of<RangeT, AnyViewT::kind,
std::ranges::range_reference_t<AnyViewT>>;
std::ranges::range_reference_t<AnyViewT>,
std::ranges::range_difference_t<AnyViewT>>;

template <class InterfaceT>
concept interface_copyable =
Expand Down
13 changes: 9 additions & 4 deletions include/pr/detail/view_adaptor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ class constant_view_adaptor
: view_(static_cast<ViewT &&>(view)) {}

[[nodiscard]] constexpr auto begin() const -> iterator_ override {
if constexpr (disables_kind<KindV, any_kind::common>) {
return iterator_(std::ranges::begin(view_), std::ranges::end(view_));
} else {
if constexpr (detail::enables_kind(KindV, any_kind::common)) {
// optimization: don't store end when any_view is common_range
return iterator_(std::ranges::begin(view_), std::unreachable_sentinel);
} else {
return iterator_(std::ranges::begin(view_), std::ranges::end(view_));
}
}
};
Expand All @@ -44,7 +44,12 @@ class constant_view_adaptor<ElementT, KindV, ReferenceT, DifferenceT, ViewT>
: view_(static_cast<ViewT &&>(view)) {}

[[nodiscard]] constexpr auto begin() -> iterator_ override {
return iterator_(std::ranges::begin(view_), std::ranges::end(view_));
if constexpr (detail::enables_kind(KindV, any_kind::common)) {
// optimization: don't store end when any_view is common_range
return iterator_(std::ranges::begin(view_), std::unreachable_sentinel);
} else {
return iterator_(std::ranges::begin(view_), std::ranges::end(view_));
}
}
};

Expand Down

0 comments on commit a4bdb6a

Please sign in to comment.