Redcraft/Redcraft.Utility/Source/Public/Iterator/RandomAccessIterator.h

94 lines
3.0 KiB
C++

#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