-
Notifications
You must be signed in to change notification settings - Fork 13
makes most operators hidden friends #471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e660b9d
2a0342c
ea92860
13c863d
438c023
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -63,6 +63,27 @@ struct Storage<T, 0> final {}; | |||||
|
||||||
} // namespace __private | ||||||
|
||||||
namespace __private { | ||||||
Comment on lines
64
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can avoid closing and opening the namespace here |
||||||
template <size_t I> | ||||||
constexpr bool array_cmp_impl(sus::cmp::Ordering auto& val, const auto& l, | ||||||
const auto& r) noexcept { | ||||||
auto cmp = l.get_unchecked(::sus::marker::unsafe_fn, I) <=> | ||||||
r.get_unchecked(::sus::marker::unsafe_fn, I); | ||||||
// Allow downgrading from equal to equivalent, but not the inverse. | ||||||
if (cmp != 0) val = cmp; | ||||||
// Short circuit by returning true when we find a difference. | ||||||
return val == 0; | ||||||
} | ||||||
|
||||||
template <size_t... Is> | ||||||
constexpr auto array_cmp(sus::cmp::Ordering auto equal, const auto& l, | ||||||
const auto& r, std::index_sequence<Is...>) noexcept { | ||||||
auto val = equal; | ||||||
(true && ... && (array_cmp_impl<Is>(val, l, r))); | ||||||
return val; | ||||||
} | ||||||
} // namespace __private | ||||||
|
||||||
/// A collection of objects of type `T`, with a fixed size `N`. | ||||||
/// | ||||||
/// An Array can not be larger than [`isize::MAX`]($sus::num::isize::MAX), as | ||||||
|
@@ -335,10 +356,11 @@ class Array final { | |||||
/// Satisfies the [`Eq<Array<T, N>, Array<U, N>>`]($sus::cmp::Eq) concept. | ||||||
template <class U> | ||||||
requires(::sus::cmp::Eq<T, U>) | ||||||
constexpr bool operator==(const Array<U, N>& r) const& noexcept | ||||||
friend constexpr bool operator==(const Array& l, | ||||||
const Array<U, N>& r) noexcept | ||||||
requires(::sus::cmp::Eq<T>) | ||||||
{ | ||||||
return eq_impl(r, std::make_index_sequence<N>()); | ||||||
return l.eq_impl(r, std::make_index_sequence<N>()); | ||||||
} | ||||||
|
||||||
/// Satisfies the [`Eq<Array<T, N>, Slice<U>>`]($sus::cmp::Eq) concept. | ||||||
|
@@ -405,6 +427,115 @@ class Array final { | |||||
sus::iter::IterRefCounter::empty_for_view(), storage_.data_, N); | ||||||
} | ||||||
|
||||||
/// Compares two Arrays. | ||||||
/// | ||||||
/// Satisfies sus::cmp::StrongOrd<Array<T, N>> if sus::cmp::StrongOrd<T>. | ||||||
/// | ||||||
/// Satisfies sus::cmp::Ord<Array<T, N>> if sus::cmp::Ord<T>. | ||||||
/// | ||||||
/// Satisfies sus::cmp::PartialOrd<Array<T, N>> if sus::cmp::PartialOrd<T>. | ||||||
/// #[doc.overloads=array.cmp.array] | ||||||
template <class U> | ||||||
requires(::sus::cmp::ExclusiveStrongOrd<T, U>) | ||||||
constexpr friend std::strong_ordering operator<=>( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we write |
||||||
const Array& l, const Array<U, N>& r) noexcept { | ||||||
return __private::array_cmp(std::strong_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
/// #[doc.overloads=array.cmp.array] | ||||||
template <class U> | ||||||
requires(::sus::cmp::ExclusiveOrd<T, U>) | ||||||
constexpr friend std::weak_ordering operator<=>( | ||||||
const Array& l, const Array<U, N>& r) noexcept { | ||||||
return __private::array_cmp(std::weak_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
/// #[doc.overloads=array.cmp.array] | ||||||
template <class U> | ||||||
requires(::sus::cmp::ExclusivePartialOrd<T, U>) | ||||||
constexpr friend std::partial_ordering operator<=>( | ||||||
const Array& l, const Array<U, N>& r) noexcept { | ||||||
return __private::array_cmp(std::partial_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
|
||||||
/// Compares an Array and a Slice. | ||||||
/// | ||||||
/// Satisfies sus::cmp::StrongOrd<Array<T, N>, Slice<T>> if | ||||||
/// sus::cmp::StrongOrd<T>. | ||||||
/// | ||||||
/// Satisfies sus::cmp::Ord<Array<T, N>, Slice<T>> if sus::cmp::Ord<T>. | ||||||
/// | ||||||
/// Satisfies sus::cmp::PartialOrd<Array<T, N>, Slice<T>> if | ||||||
/// sus::cmp::PartialOrd<T>. | ||||||
/// #[doc.overloads=array.cmp.slice] | ||||||
template <class U> | ||||||
requires(::sus::cmp::ExclusiveStrongOrd<T, U>) | ||||||
constexpr friend std::strong_ordering operator<=>( | ||||||
const Array& l, const Slice<U>& r) noexcept { | ||||||
if (r.len() != N) return r.len() <=> N; | ||||||
return __private::array_cmp(std::strong_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
/// #[doc.overloads=array.cmp.slice] | ||||||
template <class U> | ||||||
requires(::sus::cmp::ExclusiveOrd<T, U>) | ||||||
constexpr friend std::weak_ordering operator<=>(const Array& l, | ||||||
const Slice<U>& r) noexcept { | ||||||
if (r.len() != N) return r.len() <=> N; | ||||||
return __private::array_cmp(std::weak_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
/// #[doc.overloads=array.cmp.slice] | ||||||
template <class U> | ||||||
requires(::sus::cmp::ExclusivePartialOrd<T, U>) | ||||||
constexpr friend std::partial_ordering operator<=>( | ||||||
const Array& l, const Slice<U>& r) noexcept { | ||||||
if (r.len() != N) return r.len() <=> N; | ||||||
return __private::array_cmp(std::partial_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
|
||||||
/// Compares an Array and a SliceMut. | ||||||
/// | ||||||
/// Satisfies sus::cmp::StrongOrd<Array<T, N>, SliceMut<T>> if | ||||||
/// sus::cmp::StrongOrd<T>. | ||||||
/// | ||||||
/// Satisfies sus::cmp::Ord<Array<T, N>, SliceMut<T>> if sus::cmp::Ord<T>. | ||||||
/// | ||||||
/// Satisfies sus::cmp::PartialOrd<Array<T, N>, SliceMut<T>> if | ||||||
/// sus::cmp::PartialOrd<T>. | ||||||
/// #[doc.overloads=array.cmp.slicemut] | ||||||
template <class U> | ||||||
requires(::sus::cmp::ExclusiveStrongOrd<T, U>) | ||||||
constexpr friend std::strong_ordering operator<=>( | ||||||
const Array& l, const SliceMut<U>& r) noexcept { | ||||||
if (r.len() != N) return r.len() <=> N; | ||||||
return __private::array_cmp(std::strong_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
/// #[doc.overloads=array.cmp.slicemut] | ||||||
template <class U> | ||||||
requires(::sus::cmp::ExclusiveOrd<T, U>) | ||||||
constexpr friend std::weak_ordering operator<=>( | ||||||
const Array& l, const SliceMut<U>& r) noexcept { | ||||||
if (r.len() != N) return r.len() <=> N; | ||||||
return __private::array_cmp(std::weak_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
/// #[doc.overloads=array.cmp.slicemut] | ||||||
template <class U> | ||||||
requires(::sus::cmp::ExclusivePartialOrd<T, U>) | ||||||
constexpr friend std::partial_ordering operator<=>( | ||||||
const Array& l, const SliceMut<U>& r) noexcept { | ||||||
if (r.len() != N) return r.len() <=> N; | ||||||
return __private::array_cmp(std::partial_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
|
||||||
// Stream support | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
_sus_format_to_stream(Array); | ||||||
|
||||||
private: | ||||||
enum WithDefault { WITH_DEFAULT }; | ||||||
template <size_t... Is> | ||||||
|
@@ -467,136 +598,6 @@ template <class T, class... Ts> | |||||
std::same_as<std::remove_cvref_t<T>, std::remove_cvref_t<Ts>>)) | ||||||
Array(T&&, Ts&&...) -> Array<std::remove_cvref_t<T>, 1u + sizeof...(Ts)>; | ||||||
|
||||||
namespace __private { | ||||||
|
||||||
template <size_t I> | ||||||
constexpr inline bool array_cmp_impl(sus::cmp::Ordering auto& val, | ||||||
const auto& l, const auto& r) noexcept { | ||||||
auto cmp = l.get_unchecked(::sus::marker::unsafe_fn, I) <=> | ||||||
r.get_unchecked(::sus::marker::unsafe_fn, I); | ||||||
// Allow downgrading from equal to equivalent, but not the inverse. | ||||||
if (cmp != 0) val = cmp; | ||||||
// Short circuit by returning true when we find a difference. | ||||||
return val == 0; | ||||||
}; | ||||||
|
||||||
template <size_t... Is> | ||||||
constexpr inline auto array_cmp(sus::cmp::Ordering auto equal, const auto& l, | ||||||
const auto& r, | ||||||
std::index_sequence<Is...>) noexcept { | ||||||
auto val = equal; | ||||||
(true && ... && (array_cmp_impl<Is>(val, l, r))); | ||||||
return val; | ||||||
}; | ||||||
|
||||||
} // namespace __private | ||||||
|
||||||
/// Compares two Arrays. | ||||||
/// | ||||||
/// Satisfies sus::cmp::StrongOrd<Array<T, N>> if sus::cmp::StrongOrd<T>. | ||||||
/// | ||||||
/// Satisfies sus::cmp::Ord<Array<T, N>> if sus::cmp::Ord<T>. | ||||||
/// | ||||||
/// Satisfies sus::cmp::PartialOrd<Array<T, N>> if sus::cmp::PartialOrd<T>. | ||||||
/// #[doc.overloads=array.cmp.array] | ||||||
template <class T, class U, size_t N> | ||||||
requires(::sus::cmp::ExclusiveStrongOrd<T, U>) | ||||||
constexpr inline std::strong_ordering operator<=>( | ||||||
const Array<T, N>& l, const Array<U, N>& r) noexcept { | ||||||
return __private::array_cmp(std::strong_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
/// #[doc.overloads=array.cmp.array] | ||||||
template <class T, class U, size_t N> | ||||||
requires(::sus::cmp::ExclusiveOrd<T, U>) | ||||||
constexpr inline std::weak_ordering operator<=>(const Array<T, N>& l, | ||||||
const Array<U, N>& r) noexcept { | ||||||
return __private::array_cmp(std::weak_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
/// #[doc.overloads=array.cmp.array] | ||||||
template <class T, class U, size_t N> | ||||||
requires(::sus::cmp::ExclusivePartialOrd<T, U>) | ||||||
constexpr inline std::partial_ordering operator<=>( | ||||||
const Array<T, N>& l, const Array<U, N>& r) noexcept { | ||||||
return __private::array_cmp(std::partial_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
|
||||||
/// Compares an Array and a Slice. | ||||||
/// | ||||||
/// Satisfies sus::cmp::StrongOrd<Array<T, N>, Slice<T>> if | ||||||
/// sus::cmp::StrongOrd<T>. | ||||||
/// | ||||||
/// Satisfies sus::cmp::Ord<Array<T, N>, Slice<T>> if sus::cmp::Ord<T>. | ||||||
/// | ||||||
/// Satisfies sus::cmp::PartialOrd<Array<T, N>, Slice<T>> if | ||||||
/// sus::cmp::PartialOrd<T>. | ||||||
/// #[doc.overloads=array.cmp.slice] | ||||||
template <class T, class U, size_t N> | ||||||
requires(::sus::cmp::ExclusiveStrongOrd<T, U>) | ||||||
constexpr inline std::strong_ordering operator<=>(const Array<T, N>& l, | ||||||
const Slice<U>& r) noexcept { | ||||||
if (r.len() != N) return r.len() <=> N; | ||||||
return __private::array_cmp(std::strong_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
/// #[doc.overloads=array.cmp.slice] | ||||||
template <class T, class U, size_t N> | ||||||
requires(::sus::cmp::ExclusiveOrd<T, U>) | ||||||
constexpr inline std::weak_ordering operator<=>(const Array<T, N>& l, | ||||||
const Slice<U>& r) noexcept { | ||||||
if (r.len() != N) return r.len() <=> N; | ||||||
return __private::array_cmp(std::weak_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
/// #[doc.overloads=array.cmp.slice] | ||||||
template <class T, class U, size_t N> | ||||||
requires(::sus::cmp::ExclusivePartialOrd<T, U>) | ||||||
constexpr inline std::partial_ordering operator<=>(const Array<T, N>& l, | ||||||
const Slice<U>& r) noexcept { | ||||||
if (r.len() != N) return r.len() <=> N; | ||||||
return __private::array_cmp(std::partial_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
|
||||||
/// Compares an Array and a SliceMut. | ||||||
/// | ||||||
/// Satisfies sus::cmp::StrongOrd<Array<T, N>, SliceMut<T>> if | ||||||
/// sus::cmp::StrongOrd<T>. | ||||||
/// | ||||||
/// Satisfies sus::cmp::Ord<Array<T, N>, SliceMut<T>> if sus::cmp::Ord<T>. | ||||||
/// | ||||||
/// Satisfies sus::cmp::PartialOrd<Array<T, N>, SliceMut<T>> if | ||||||
/// sus::cmp::PartialOrd<T>. | ||||||
/// #[doc.overloads=array.cmp.slicemut] | ||||||
template <class T, class U, size_t N> | ||||||
requires(::sus::cmp::ExclusiveStrongOrd<T, U>) | ||||||
constexpr inline std::strong_ordering operator<=>( | ||||||
const Array<T, N>& l, const SliceMut<U>& r) noexcept { | ||||||
if (r.len() != N) return r.len() <=> N; | ||||||
return __private::array_cmp(std::strong_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
/// #[doc.overloads=array.cmp.slicemut] | ||||||
template <class T, class U, size_t N> | ||||||
requires(::sus::cmp::ExclusiveOrd<T, U>) | ||||||
constexpr inline std::weak_ordering operator<=>(const Array<T, N>& l, | ||||||
const SliceMut<U>& r) noexcept { | ||||||
if (r.len() != N) return r.len() <=> N; | ||||||
return __private::array_cmp(std::weak_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
/// #[doc.overloads=array.cmp.slicemut] | ||||||
template <class T, class U, size_t N> | ||||||
requires(::sus::cmp::ExclusivePartialOrd<T, U>) | ||||||
constexpr inline std::partial_ordering operator<=>( | ||||||
const Array<T, N>& l, const SliceMut<U>& r) noexcept { | ||||||
if (r.len() != N) return r.len() <=> N; | ||||||
return __private::array_cmp(std::partial_ordering::equivalent, l, r, | ||||||
std::make_index_sequence<N>()); | ||||||
} | ||||||
|
||||||
/// Support for using structured bindings with `Array`. | ||||||
/// #[doc.overloads=array.structured.bindings] | ||||||
template <size_t I, class T, size_t N> | ||||||
|
@@ -664,17 +665,6 @@ struct fmt::formatter<::sus::collections::Array<T, N>, Char> { | |||||
::sus::string::__private::AnyFormatter<T, Char> underlying_; | ||||||
}; | ||||||
|
||||||
// Stream support (written out manually due to size_t template param). | ||||||
namespace sus::collections { | ||||||
template <class T, size_t N, | ||||||
::sus::string::__private::StreamCanReceiveString<char> StreamType> | ||||||
inline StreamType& operator<<(StreamType& stream, const Array<T, N>& value) { | ||||||
return ::sus::string::__private::format_to_stream(stream, | ||||||
fmt::to_string(value)); | ||||||
} | ||||||
|
||||||
} // namespace sus::collections | ||||||
|
||||||
namespace sus::collections { | ||||||
// Documented in vec.h | ||||||
using ::sus::iter::begin; | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.