@@ -61,6 +61,24 @@ struct Storage final {
6161template <class T >
6262struct Storage <T, 0 > final {};
6363
64+ template <size_t I>
65+ constexpr bool array_cmp_impl (sus::cmp::Ordering auto & val, const auto & l,
66+ const auto & r) noexcept {
67+ auto cmp = l.get_unchecked (::sus::marker::unsafe_fn, I) <=>
68+ r.get_unchecked (::sus::marker::unsafe_fn, I);
69+ // Allow downgrading from equal to equivalent, but not the inverse.
70+ if (cmp != 0 ) val = cmp;
71+ // Short circuit by returning true when we find a difference.
72+ return val == 0 ;
73+ }
74+
75+ template <size_t ... Is>
76+ constexpr auto array_cmp (sus::cmp::Ordering auto equal, const auto & l,
77+ const auto & r, std::index_sequence<Is...>) noexcept {
78+ auto val = equal;
79+ (true && ... && (array_cmp_impl<Is>(val, l, r)));
80+ return val;
81+ }
6482} // namespace __private
6583
6684// / A collection of objects of type `T`, with a fixed size `N`.
@@ -335,10 +353,11 @@ class Array final {
335353 // / Satisfies the [`Eq<Array<T, N>, Array<U, N>>`]($sus::cmp::Eq) concept.
336354 template <class U >
337355 requires (::sus::cmp::Eq<T, U>)
338- constexpr bool operator==(const Array<U, N>& r) const & noexcept
356+ friend constexpr bool operator==(const Array& l,
357+ const Array<U, N>& r) noexcept
339358 requires(::sus::cmp::Eq<T>)
340359 {
341- return eq_impl (r, std::make_index_sequence<N>());
360+ return l. eq_impl (r, std::make_index_sequence<N>());
342361 }
343362
344363 // / Satisfies the [`Eq<Array<T, N>, Slice<U>>`]($sus::cmp::Eq) concept.
@@ -405,6 +424,115 @@ class Array final {
405424 sus::iter::IterRefCounter::empty_for_view (), storage_.data_ , N);
406425 }
407426
427+ // / Compares two Arrays.
428+ // /
429+ // / Satisfies sus::cmp::StrongOrd<Array<T, N>> if sus::cmp::StrongOrd<T>.
430+ // /
431+ // / Satisfies sus::cmp::Ord<Array<T, N>> if sus::cmp::Ord<T>.
432+ // /
433+ // / Satisfies sus::cmp::PartialOrd<Array<T, N>> if sus::cmp::PartialOrd<T>.
434+ // / #[doc.overloads=array.cmp.array]
435+ template <class U >
436+ requires (::sus::cmp::ExclusiveStrongOrd<T, U>)
437+ friend constexpr std::strong_ordering operator<=>(
438+ const Array& l, const Array<U, N>& r) noexcept {
439+ return __private::array_cmp (std::strong_ordering::equivalent, l, r,
440+ std::make_index_sequence<N>());
441+ }
442+ // / #[doc.overloads=array.cmp.array]
443+ template <class U >
444+ requires (::sus::cmp::ExclusiveOrd<T, U>)
445+ friend constexpr std::weak_ordering operator<=>(
446+ const Array& l, const Array<U, N>& r) noexcept {
447+ return __private::array_cmp (std::weak_ordering::equivalent, l, r,
448+ std::make_index_sequence<N>());
449+ }
450+ // / #[doc.overloads=array.cmp.array]
451+ template <class U >
452+ requires (::sus::cmp::ExclusivePartialOrd<T, U>)
453+ friend constexpr std::partial_ordering operator<=>(
454+ const Array& l, const Array<U, N>& r) noexcept {
455+ return __private::array_cmp (std::partial_ordering::equivalent, l, r,
456+ std::make_index_sequence<N>());
457+ }
458+
459+ // / Compares an Array and a Slice.
460+ // /
461+ // / Satisfies sus::cmp::StrongOrd<Array<T, N>, Slice<T>> if
462+ // / sus::cmp::StrongOrd<T>.
463+ // /
464+ // / Satisfies sus::cmp::Ord<Array<T, N>, Slice<T>> if sus::cmp::Ord<T>.
465+ // /
466+ // / Satisfies sus::cmp::PartialOrd<Array<T, N>, Slice<T>> if
467+ // / sus::cmp::PartialOrd<T>.
468+ // / #[doc.overloads=array.cmp.slice]
469+ template <class U >
470+ requires (::sus::cmp::ExclusiveStrongOrd<T, U>)
471+ friend constexpr std::strong_ordering operator<=>(
472+ const Array& l, const Slice<U>& r) noexcept {
473+ if (r.len () != N) return r.len () <=> N;
474+ return __private::array_cmp (std::strong_ordering::equivalent, l, r,
475+ std::make_index_sequence<N>());
476+ }
477+ // / #[doc.overloads=array.cmp.slice]
478+ template <class U >
479+ requires (::sus::cmp::ExclusiveOrd<T, U>)
480+ friend constexpr std::weak_ordering operator<=>(const Array& l,
481+ const Slice<U>& r) noexcept {
482+ if (r.len () != N) return r.len () <=> N;
483+ return __private::array_cmp (std::weak_ordering::equivalent, l, r,
484+ std::make_index_sequence<N>());
485+ }
486+ // / #[doc.overloads=array.cmp.slice]
487+ template <class U >
488+ requires (::sus::cmp::ExclusivePartialOrd<T, U>)
489+ friend constexpr std::partial_ordering operator<=>(
490+ const Array& l, const Slice<U>& r) noexcept {
491+ if (r.len () != N) return r.len () <=> N;
492+ return __private::array_cmp (std::partial_ordering::equivalent, l, r,
493+ std::make_index_sequence<N>());
494+ }
495+
496+ // / Compares an Array and a SliceMut.
497+ // /
498+ // / Satisfies sus::cmp::StrongOrd<Array<T, N>, SliceMut<T>> if
499+ // / sus::cmp::StrongOrd<T>.
500+ // /
501+ // / Satisfies sus::cmp::Ord<Array<T, N>, SliceMut<T>> if sus::cmp::Ord<T>.
502+ // /
503+ // / Satisfies sus::cmp::PartialOrd<Array<T, N>, SliceMut<T>> if
504+ // / sus::cmp::PartialOrd<T>.
505+ // / #[doc.overloads=array.cmp.slicemut]
506+ template <class U >
507+ requires (::sus::cmp::ExclusiveStrongOrd<T, U>)
508+ friend constexpr std::strong_ordering operator<=>(
509+ const Array& l, const SliceMut<U>& r) noexcept {
510+ if (r.len () != N) return r.len () <=> N;
511+ return __private::array_cmp (std::strong_ordering::equivalent, l, r,
512+ std::make_index_sequence<N>());
513+ }
514+ // / #[doc.overloads=array.cmp.slicemut]
515+ template <class U >
516+ requires (::sus::cmp::ExclusiveOrd<T, U>)
517+ friend constexpr std::weak_ordering operator<=>(
518+ const Array& l, const SliceMut<U>& r) noexcept {
519+ if (r.len () != N) return r.len () <=> N;
520+ return __private::array_cmp (std::weak_ordering::equivalent, l, r,
521+ std::make_index_sequence<N>());
522+ }
523+ // / #[doc.overloads=array.cmp.slicemut]
524+ template <class U >
525+ requires (::sus::cmp::ExclusivePartialOrd<T, U>)
526+ friend constexpr std::partial_ordering operator<=>(
527+ const Array& l, const SliceMut<U>& r) noexcept {
528+ if (r.len () != N) return r.len () <=> N;
529+ return __private::array_cmp (std::partial_ordering::equivalent, l, r,
530+ std::make_index_sequence<N>());
531+ }
532+
533+ // Stream support.
534+ _sus_format_to_stream (Array);
535+
408536 private:
409537 enum WithDefault { WITH_DEFAULT };
410538 template <size_t ... Is>
@@ -467,136 +595,6 @@ template <class T, class... Ts>
467595 std::same_as<std::remove_cvref_t <T>, std::remove_cvref_t <Ts>>))
468596Array (T&&, Ts&&...) -> Array<std::remove_cvref_t <T>, 1u + sizeof ...(Ts)>;
469597
470- namespace __private {
471-
472- template <size_t I>
473- constexpr inline bool array_cmp_impl (sus::cmp::Ordering auto & val,
474- const auto & l, const auto & r) noexcept {
475- auto cmp = l.get_unchecked (::sus::marker::unsafe_fn, I) <=>
476- r.get_unchecked (::sus::marker::unsafe_fn, I);
477- // Allow downgrading from equal to equivalent, but not the inverse.
478- if (cmp != 0 ) val = cmp;
479- // Short circuit by returning true when we find a difference.
480- return val == 0 ;
481- };
482-
483- template <size_t ... Is>
484- constexpr inline auto array_cmp (sus::cmp::Ordering auto equal, const auto & l,
485- const auto & r,
486- std::index_sequence<Is...>) noexcept {
487- auto val = equal;
488- (true && ... && (array_cmp_impl<Is>(val, l, r)));
489- return val;
490- };
491-
492- } // namespace __private
493-
494- // / Compares two Arrays.
495- // /
496- // / Satisfies sus::cmp::StrongOrd<Array<T, N>> if sus::cmp::StrongOrd<T>.
497- // /
498- // / Satisfies sus::cmp::Ord<Array<T, N>> if sus::cmp::Ord<T>.
499- // /
500- // / Satisfies sus::cmp::PartialOrd<Array<T, N>> if sus::cmp::PartialOrd<T>.
501- // / #[doc.overloads=array.cmp.array]
502- template <class T , class U , size_t N>
503- requires (::sus::cmp::ExclusiveStrongOrd<T, U>)
504- constexpr inline std::strong_ordering operator <=>(
505- const Array<T, N>& l, const Array<U, N>& r) noexcept {
506- return __private::array_cmp (std::strong_ordering::equivalent, l, r,
507- std::make_index_sequence<N>());
508- }
509- // / #[doc.overloads=array.cmp.array]
510- template <class T , class U , size_t N>
511- requires (::sus::cmp::ExclusiveOrd<T, U>)
512- constexpr inline std::weak_ordering operator <=>(const Array<T, N>& l,
513- const Array<U, N>& r) noexcept {
514- return __private::array_cmp (std::weak_ordering::equivalent, l, r,
515- std::make_index_sequence<N>());
516- }
517- // / #[doc.overloads=array.cmp.array]
518- template <class T , class U , size_t N>
519- requires (::sus::cmp::ExclusivePartialOrd<T, U>)
520- constexpr inline std::partial_ordering operator <=>(
521- const Array<T, N>& l, const Array<U, N>& r) noexcept {
522- return __private::array_cmp (std::partial_ordering::equivalent, l, r,
523- std::make_index_sequence<N>());
524- }
525-
526- // / Compares an Array and a Slice.
527- // /
528- // / Satisfies sus::cmp::StrongOrd<Array<T, N>, Slice<T>> if
529- // / sus::cmp::StrongOrd<T>.
530- // /
531- // / Satisfies sus::cmp::Ord<Array<T, N>, Slice<T>> if sus::cmp::Ord<T>.
532- // /
533- // / Satisfies sus::cmp::PartialOrd<Array<T, N>, Slice<T>> if
534- // / sus::cmp::PartialOrd<T>.
535- // / #[doc.overloads=array.cmp.slice]
536- template <class T , class U , size_t N>
537- requires (::sus::cmp::ExclusiveStrongOrd<T, U>)
538- constexpr inline std::strong_ordering operator <=>(const Array<T, N>& l,
539- const Slice<U>& r) noexcept {
540- if (r.len () != N) return r.len () <=> N;
541- return __private::array_cmp (std::strong_ordering::equivalent, l, r,
542- std::make_index_sequence<N>());
543- }
544- // / #[doc.overloads=array.cmp.slice]
545- template <class T , class U , size_t N>
546- requires (::sus::cmp::ExclusiveOrd<T, U>)
547- constexpr inline std::weak_ordering operator <=>(const Array<T, N>& l,
548- const Slice<U>& r) noexcept {
549- if (r.len () != N) return r.len () <=> N;
550- return __private::array_cmp (std::weak_ordering::equivalent, l, r,
551- std::make_index_sequence<N>());
552- }
553- // / #[doc.overloads=array.cmp.slice]
554- template <class T , class U , size_t N>
555- requires (::sus::cmp::ExclusivePartialOrd<T, U>)
556- constexpr inline std::partial_ordering operator <=>(const Array<T, N>& l,
557- const Slice<U>& r) noexcept {
558- if (r.len () != N) return r.len () <=> N;
559- return __private::array_cmp (std::partial_ordering::equivalent, l, r,
560- std::make_index_sequence<N>());
561- }
562-
563- // / Compares an Array and a SliceMut.
564- // /
565- // / Satisfies sus::cmp::StrongOrd<Array<T, N>, SliceMut<T>> if
566- // / sus::cmp::StrongOrd<T>.
567- // /
568- // / Satisfies sus::cmp::Ord<Array<T, N>, SliceMut<T>> if sus::cmp::Ord<T>.
569- // /
570- // / Satisfies sus::cmp::PartialOrd<Array<T, N>, SliceMut<T>> if
571- // / sus::cmp::PartialOrd<T>.
572- // / #[doc.overloads=array.cmp.slicemut]
573- template <class T , class U , size_t N>
574- requires (::sus::cmp::ExclusiveStrongOrd<T, U>)
575- constexpr inline std::strong_ordering operator <=>(
576- const Array<T, N>& l, const SliceMut<U>& r) noexcept {
577- if (r.len () != N) return r.len () <=> N;
578- return __private::array_cmp (std::strong_ordering::equivalent, l, r,
579- std::make_index_sequence<N>());
580- }
581- // / #[doc.overloads=array.cmp.slicemut]
582- template <class T , class U , size_t N>
583- requires (::sus::cmp::ExclusiveOrd<T, U>)
584- constexpr inline std::weak_ordering operator <=>(const Array<T, N>& l,
585- const SliceMut<U>& r) noexcept {
586- if (r.len () != N) return r.len () <=> N;
587- return __private::array_cmp (std::weak_ordering::equivalent, l, r,
588- std::make_index_sequence<N>());
589- }
590- // / #[doc.overloads=array.cmp.slicemut]
591- template <class T , class U , size_t N>
592- requires (::sus::cmp::ExclusivePartialOrd<T, U>)
593- constexpr inline std::partial_ordering operator <=>(
594- const Array<T, N>& l, const SliceMut<U>& r) noexcept {
595- if (r.len () != N) return r.len () <=> N;
596- return __private::array_cmp (std::partial_ordering::equivalent, l, r,
597- std::make_index_sequence<N>());
598- }
599-
600598// / Support for using structured bindings with `Array`.
601599// / #[doc.overloads=array.structured.bindings]
602600template <size_t I, class T , size_t N>
@@ -664,17 +662,6 @@ struct fmt::formatter<::sus::collections::Array<T, N>, Char> {
664662 ::sus::string::__private::AnyFormatter<T, Char> underlying_;
665663};
666664
667- // Stream support (written out manually due to size_t template param).
668- namespace sus ::collections {
669- template <class T , size_t N,
670- ::sus::string::__private::StreamCanReceiveString<char > StreamType>
671- inline StreamType& operator <<(StreamType& stream, const Array<T, N>& value) {
672- return ::sus::string::__private::format_to_stream (stream,
673- fmt::to_string (value));
674- }
675-
676- } // namespace sus::collections
677-
678665namespace sus ::collections {
679666// Documented in vec.h
680667using ::sus::iter::begin;
0 commit comments