Skip to content

Commit

Permalink
Fix
Browse files Browse the repository at this point in the history
  • Loading branch information
lackhole committed Jun 22, 2024
1 parent 83ee08f commit 12466ae
Show file tree
Hide file tree
Showing 12 changed files with 617 additions and 148 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ Description
| `ranges::range_const_reference_t` | ![][c20ok] | |
| `ranges::range_rvalue_reference_t` | ![][c20ok] | |
| `ranges::range_common_reference_t` | ![][c20ok] | |
| `ranges::view_interface` | ![][c20ok] | |
| `ranges::view_interface` | ![][c20ok] | ![][c23ok] |
| `ranges::subrange` | ![][c20ok] | |
| `ranges::dangling` | ![][c20ok] | |
| `ranges::borrowed_iterator_t` | ![][c20ok] | |
Expand Down
12 changes: 11 additions & 1 deletion include/preview/__ranges/range_adaptor_closure.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ struct basic_range {
unsigned char data_;
};

struct ubiq_range {
ubiq_range() = default;

template<typename T, std::enable_if_t<range<remove_cvref_t<T>>::value, int> = 0>
operator T() const noexcept;
};

template<typename C, typename D>
class range_adaptor_closure_object
: protected compressed_pair<C, D>
Expand Down Expand Up @@ -75,7 +82,10 @@ template<typename T>
struct is_range_adaptor_closure
: conjunction<
derived_from_single_crtp<T, range_adaptor_closure>,
is_invocable<T, detail::basic_range>,
disjunction<
is_invocable<T, detail::basic_range>,
is_invocable<T, detail::ubiq_range>
>,
negation< range<T> >
> {};

Expand Down
39 changes: 28 additions & 11 deletions include/preview/__ranges/subrange.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,9 @@ class subrange

template<typename R, std::enable_if_t<conjunction<
different_from<subrange, R>,
detail::subrange_ctor_range<I, S, R>,
borrowed_range<R>,
detail::convertible_to_non_slicing<iterator_t<R>, I>,
convertible_to<sentinel_t<R>, S>,
disjunction<
negation<store_size>,
sized_range<R>
Expand All @@ -180,7 +182,9 @@ class subrange
: subrange(r, static_cast<detail::make_unsigned_like_t<iter_difference_t<I>>>(ranges::size(r))) {}

template<typename R, std::enable_if_t<conjunction<
detail::subrange_ctor_range<I, S, R>,
borrowed_range<R>,
detail::convertible_to_non_slicing<iterator_t<R>, I>,
convertible_to<sentinel_t<R>, S>,
bool_constant< K == subrange_kind::sized >
>::value, int> = 0>
constexpr subrange(R&& r, detail::make_unsigned_like_t<iter_difference_t<I>> n)
Expand Down Expand Up @@ -297,16 +301,29 @@ make_subrange(R&& r, detail::make_unsigned_like_t<range_difference_t<R>> n) {
}


#if __cplusplus >= 201703L

// template<typename R>
// subrange(R&&, detail::make_unsigned_like_t<range_difference_t<R>>) ->
// subrange<ranges::iterator_t<R>, ranges::sentinel_t<R>, ranges::subrange_kind::sized>;
//
// template<typename I, typename S> subrange(I, S) -> subrange<I, S>;
//
// ^^^^^^^^^^ These two are ambiguous without constraints
#if PREVIEW_CXX_VERSION >= 17
// These two are ambiguous without constraints
// vvvvvvvvvvvvvvvvvvvv
template<typename R>
subrange(R&&, detail::make_unsigned_like_t<range_difference_t<R>>) ->
subrange<
std::enable_if_t<borrowed_range<R>::value,
ranges::iterator_t<R>>,
ranges::sentinel_t<R>,
ranges::subrange_kind::sized
>;

template<typename I, typename S>
subrange(I, S)
-> subrange<
std::enable_if_t<conjunction<
input_or_output_iterator<I>,
sentinel_for<S, I>
>::value,
I>,
S
>;
// ^^^^^^^^^^^^^^^^^^^^

template<typename I, typename S>
subrange(I, S, detail::make_unsigned_like_t<iter_difference_t<I>>) ->
Expand Down
23 changes: 11 additions & 12 deletions include/preview/__ranges/views/all.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "preview/__ranges/ref_view.h"
#include "preview/__ranges/view.h"
#include "preview/__ranges/viewable_range.h"
#include "preview/__type_traits/conditional.h"
#include "preview/__type_traits/detail/return_category.h"
#include "preview/__type_traits/conjunction.h"

Expand All @@ -28,17 +29,17 @@ using preview::detail::return_category;
class all_adaptor_closure : public range_adaptor_closure<all_adaptor_closure> {
template<typename T>
using return_category_type =
std::conditional_t<
view<std::decay_t<T>>::value, return_category<1, std::decay_t<T>>,
std::conditional_t<
conjunction<
conditional_t<
view<std::decay_t<T>>, return_category<1, std::decay_t<T>>,
conjunction< // ref_view{T}
std::is_lvalue_reference<T>,
std::is_convertible<T, std::add_lvalue_reference_t<std::remove_reference_t<T>>>,
range<std::remove_reference_t<T>>,
std::is_object<std::remove_reference_t<T>>,
std::is_lvalue_reference<T>
>::value,
return_category<2, ref_view<std::remove_reference_t<T>>>,
return_category<3, owning_view<std::remove_reference_t<T>>>
>>;
std::is_object<std::remove_reference_t<T>>
>,
return_category<2, ref_view<std::remove_reference_t<T>>>,
return_category<3, owning_view<std::remove_reference_t<T>>>
>;

template<typename R, typename T>
constexpr T operator()(R&& r, return_category<1, T>) const {
Expand All @@ -56,8 +57,6 @@ class all_adaptor_closure : public range_adaptor_closure<all_adaptor_closure> {
}

public:
all_adaptor_closure() = default;

template<typename R>
constexpr typename return_category_type<R&&>::return_type
operator()(R&& r) const {
Expand Down
7 changes: 7 additions & 0 deletions include/preview/__ranges/views/cartesian_product_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,13 @@ class cartesian_product_view : public view_interface<cartesian_product_view<Firs

constexpr cartesian_product_view() = default;

// TODO: Add constraints to the class to block illegal deduction
template<typename Dummy = void, std::enable_if_t<conjunction<std::is_void<Dummy>,
input_range<First>,
forward_range<Vs>...,
view<First>,
view<Vs>...
>::value, int> = 0>
constexpr cartesian_product_view(First first, Vs... bases)
: bases_(std::move(first), std::move(bases)...) {}

Expand Down
15 changes: 15 additions & 0 deletions include/preview/__ranges/views/iota_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,21 @@ class iota_view : public view_interface<iota_view<W, Bound>> {
Bound bound_ = Bound();
};

#if PREVIEW_CXX_VERSION >= 17

template<typename W, typename Bound>
iota_view(W, Bound)
-> iota_view<
std::enable_if_t<
disjunction<
negation<is_integer_like<W>>,
negation<is_integer_like<Bound>>,
bool_constant<is_signed_integer_like<W>::value == is_signed_integer_like<Bound>::value>
>::value, W>,
Bound>;

#endif

namespace views {
namespace detail {

Expand Down
49 changes: 41 additions & 8 deletions include/preview/__utility/compressed_pair.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#
# include "preview/__core/inline_variable.h"
# include "preview/__tuple/specialize_tuple.h"
# include "preview/__type_traits/common_type.h"
# include "preview/__type_traits/conjunction.h"
# include "preview/__type_traits/is_swappable.h"

Expand Down Expand Up @@ -53,7 +54,7 @@ struct compressed_pair_empty_t {};
PREVIEW_INLINE_VARIABLE constexpr compressed_pair_empty_t compressed_pair_empty;


// An size-optimized pair using empty base optimization
// A size-optimized pair using empty base optimization
template<typename T, typename U>
class compressed_pair : public detail::compressed_slot<T, 0>, public detail::compressed_slot<U, 1> {
private:
Expand Down Expand Up @@ -90,21 +91,53 @@ class compressed_pair : public detail::compressed_slot<T, 0>, public detail::com
constexpr const U& second() const & noexcept { return second_base::template get<1>(); }
constexpr const U&& second() const && noexcept { return std::move(second_base::template get<1>()); }

constexpr std::enable_if_t<conjunction<is_swappable<T>, is_swappable<U>>::value>
swap(compressed_pair& other)
noexcept(conjunction<is_nothrow_swappable<T>, is_nothrow_swappable<U>>::value)
template<typename Dummy = void, std::enable_if_t<conjunction<std::is_void<Dummy>,
is_swappable<T>,
is_swappable<U>
>::value, int> = 0>
constexpr void swap(compressed_pair& other)
noexcept(conjunction<
is_nothrow_swappable<T>,
is_nothrow_swappable<U>
>::value)
{
using std::swap;
swap(first(), other.first());
swap(second(), other.second());
}

template<typename Dummy = void, std::enable_if_t<conjunction<std::is_void<Dummy>,
is_swappable<const T>,
is_swappable<const U>
>::value, int> = 0>
constexpr void swap(const compressed_pair& other) const
noexcept(conjunction<
is_nothrow_swappable<const T>,
is_nothrow_swappable<const U>
>::value)
{
using std::swap;
swap(first(), other.first());
swap(second(), other.second());
}
};

template<typename T, typename U, std::enable_if_t<conjunction<
is_swappable<T>,
is_swappable<U>
>::value, int> = 0>
constexpr void swap(compressed_pair<T, U>& lhs, compressed_pair<T, U>& rhs)
noexcept(noexcept(lhs.swap(rhs)))
{
lhs.swap(rhs);
}

template<typename T, typename U>
constexpr std::enable_if_t<conjunction<is_swappable<T>, is_swappable<U>>::value>
swap(compressed_pair<T, U>& lhs, compressed_pair<T, U>& rhs)
noexcept(conjunction<is_nothrow_swappable<T>, is_nothrow_swappable<U>>::value)
template<typename T, typename U, std::enable_if_t<conjunction<
is_swappable<const T>,
is_swappable<const U>
>::value, int> = 0>
constexpr void swap(const compressed_pair<T, U>& lhs, const compressed_pair<T, U>& rhs)
noexcept(noexcept(lhs.swap(rhs)))
{
lhs.swap(rhs);
}
Expand Down
18 changes: 8 additions & 10 deletions include/preview/__utility/cxx20_rel_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,16 @@ namespace rel_ops {
namespace detail {

template<typename T, typename U, typename = void>
struct has_operator_equal_2 : std::false_type {};
struct equality_comparable_precxx20 : std::false_type {};

template<typename T, typename U>
struct has_operator_equal_2<
T, U,
void_t<decltype( std::declval<T>() == std::declval<U>() )>
> : std::is_convertible<decltype( std::declval<T>() == std::declval<U>() ), bool> {};
struct equality_comparable_precxx20<T, U, void_t<decltype( std::declval<T>() == std::declval<U>() )>>
: std::is_convertible<decltype( std::declval<T>() == std::declval<U>() ), bool> {};

template<typename T, typename U, typename = void>
struct has_operator_less_2 : std::false_type {};
struct less_than_comparable_precxx20 : std::false_type {};
template<typename T, typename U>
struct has_operator_less_2<
struct less_than_comparable_precxx20<
T, U,
void_t<decltype( std::declval<T>() < std::declval<U>() )>
> : std::is_convertible<decltype( std::declval<T>() < std::declval<U>() ), bool> {};
Expand All @@ -43,7 +42,7 @@ struct has_operator_less_2<
// synthesized from `U == T`
template<typename T, typename U, std::enable_if_t<conjunction<
negation<std::is_same<T, U>>,
detail::has_operator_equal_2<const U&, const T&>
detail::equality_comparable_precxx20<const U&, const T&>
>::value, int> = 0>
constexpr bool operator==(const T& a, const U& b) noexcept(noexcept(b == a)) {
return b == a;
Expand Down Expand Up @@ -74,8 +73,7 @@ struct is_equality_comparable : detail::is_equality_comparable_impl::type<T, U>
template<typename T, typename U, std::enable_if_t<conjunction<
negation<std::is_same<T, U>>,
is_equality_comparable<T, U>,
negation< detail::has_operator_less_2<const T&, const U&> >,
detail::has_operator_less_2<const U&, const T&>
detail::less_than_comparable_precxx20<const U&, const T&>
>::value, int> = 0>
constexpr bool operator<(const T& a, const U& b) noexcept(noexcept(!( (b < a) || (a == b)))) {
// (a < b) -> !(a >= b) -> !( a > b || a == b) -> !( b < a || a == b)
Expand Down
67 changes: 21 additions & 46 deletions include/preview/string_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
#include <string>
#include <ostream>

#if __cplusplus >= 201703L
#include "preview/core.h"

#if PREVIEW_CXX_VERSION >= 17
#include <string_view>
#endif

Expand All @@ -40,54 +42,14 @@
#include "preview/__type_traits/remove_cvref.h"

namespace preview {

namespace detail {

template<
typename It,
typename End,
typename CharT,
typename SizeType,
bool = conjunction<
contiguous_iterator<It>,
sized_sentinel_for<End, It>,
has_typename_type<iter_value<It>>,
negation<std::is_convertible<It, SizeType>>
>::value /* true */
>
struct string_view_iter_ctor : std::is_same<iter_value_t<It>, CharT> {};

template<typename It, typename End, typename CharT, typename SizeType>
struct string_view_iter_ctor<It, End, CharT, SizeType, false> : std::false_type {};

template<typename D, typename SV, typename = void>
struct has_operator_string_view
#if __cplusplus < 202002L
: std::is_same<D, std::string> {};
#else
: std::false_type {};
#endif
template<typename D, typename SV>
struct has_operator_string_view<D, SV, void_t<decltype( std::declval<D&>().operator SV() )>> : std::true_type {};

template<
typename R,
typename SV,
bool = conjunction<
negation< std::is_same<remove_cvref_t<R>, SV> >,
ranges::contiguous_range<R>,
ranges::sized_range<R>,
has_typename_type<ranges::range_value<R>>
>::value /* true */
>
struct string_view_range_ctor
: conjunction<
std::is_same<ranges::range_value_t<R>, typename SV::value_type>,
negation< std::is_convertible<R, typename SV::const_pointer> >,
negation< has_operator_string_view<remove_cvref_t<R>, SV> >
>{};
template<typename R, typename SV>
struct string_view_range_ctor<R, SV, false> : std::false_type {};
struct has_operator_string_view<D, SV, void_t<decltype( std::declval<D&>().operator SV() )>>
: std::is_same<SV, decltype( std::declval<D&>().operator SV() )> {};

} // namespace detail

Expand Down Expand Up @@ -122,12 +84,25 @@ class basic_string_view {
constexpr basic_string_view( const CharT* s )
: data_(s), size_(traits_type::length(s)) {}

template<typename It, typename End, std::enable_if_t<
detail::string_view_iter_ctor<It, End, CharT, size_type>::value, int> =0>
template<typename It, typename End, std::enable_if_t<conjunction<
contiguous_iterator<It>,
sized_sentinel_for<End, It>,
same_as<iter_value_t<It>, CharT>,
negation<convertible_to<End, std::size_t>>
>::value, int> =0>
constexpr basic_string_view(It first, End last)
: data_(preview::to_address(first)), size_(last - first) {}

template<typename R, std::enable_if_t<detail::string_view_range_ctor<R, basic_string_view>::value, int> = 0>
template<typename R, std::enable_if_t<conjunction<
negation<same_as<remove_cvref_t<R>, basic_string_view>>,
ranges::contiguous_range<R>,
ranges::sized_range<R>,
negation<convertible_to<R, const CharT*>>,
negation<detail::has_operator_string_view<remove_cvref_t<R>, basic_string_view>>
#if PREVIEW_CXX_VERSION >= 17
, negation<detail::has_operator_string_view<remove_cvref_t<R>, std::basic_string_view<CharT, Traits>>>
#endif
>::value, int> = 0>
constexpr explicit basic_string_view(R&& r)
: data_(ranges::data(r)), size_(ranges::size(r)) {}

Expand Down
Loading

0 comments on commit 12466ae

Please sign in to comment.