#pragma once #include "CoreTypes.h" #include "Iterator/Utility.h" #include "Iterator/Sentinel.h" #include "Iterator/BidirectionalIterator.h" #include "Miscellaneous/Compare.h" #include "TypeTraits/TypeTraits.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) #if PLATFORM_COMPILER_GCC # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wnon-template-friend" #endif /** * A concept specifies a type is a random access iterator. * Add the three-way comparison, addition, subtraction and subscript operators to the bidirectional iterator. */ template <typename I> concept CRandomAccessIterator = CBidirectionalIterator<I> && CTotallyOrdered<I> && CSizedSentinelFor<I, I> && requires(I Iter, const I Jter, const ptrdiff N) { { Iter += N } -> CSameAs<I&>; { Jter + N } -> CSameAs<I >; { N + Jter } -> CSameAs<I >; { Iter -= N } -> CSameAs<I&>; { Jter - N } -> CSameAs<I >; { Jter[N] } -> CSameAs<TIteratorReference<I>>; }; /** This is an example of a random access iterator, indicate the traits that define a random access iterator. */ template <CReferenceable T> struct IRandomAccessIterator /* : IBidirectionalIterator<T>, ISizedSentinelFor<IRandomAccessIterator> */ { // ~Begin CBidirectionalIterator. using ElementType = TRemoveCVRef<T>; // ~End CBidirectionalIterator. // ~Begin CBidirectionalIterator and CSizedSentinelFor<IRandomAccessIterator>. IRandomAccessIterator(); IRandomAccessIterator(const IRandomAccessIterator&); IRandomAccessIterator(IRandomAccessIterator&&); IRandomAccessIterator* operator=(const IRandomAccessIterator&); IRandomAccessIterator* operator=(IRandomAccessIterator&&); friend bool operator==(const IRandomAccessIterator&, const IRandomAccessIterator&); // ~End CBidirectionalIterator and CSizedSentinelFor<IRandomAccessIterator>. friend strong_ordering operator<=>(const IRandomAccessIterator&, const IRandomAccessIterator&); T operator*() const; // Also satisfies CBidirectionalIterator. T operator[](ptrdiff) const; // ~Begin CBidirectionalIterator. IRandomAccessIterator& operator++(); IRandomAccessIterator& operator--(); IRandomAccessIterator operator++(int); IRandomAccessIterator operator--(int); // ~End CBidirectionalIterator. IRandomAccessIterator& operator+=(ptrdiff); IRandomAccessIterator& operator-=(ptrdiff); IRandomAccessIterator operator+(ptrdiff) const; IRandomAccessIterator operator-(ptrdiff) const; friend IRandomAccessIterator operator+(ptrdiff, const IRandomAccessIterator&); friend ptrdiff operator-(const IRandomAccessIterator&, const IRandomAccessIterator&); // Also satisfies CSizedSentinelFor<IRandomAccessIterator>. }; // Use IRandomAccessIterator<int> represents a random access iterator static_assert(CRandomAccessIterator<IRandomAccessIterator<int&>>); static_assert( COutputIterator<IRandomAccessIterator<int&>, int>); #if PLATFORM_COMPILER_GCC # pragma GCC diagnostic pop #endif NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END