#pragma once #include "CoreTypes.h" #include "Iterator/Utility.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 sentinel for an iterator and expression 'Iter == Sentinel' is valid. * In addition, the type must be default constructible and copyable. */ template concept CSentinelFor = CSemiregular && CInputOrOutputIterator && CWeaklyEqualityComparable; /** This is an example of a sentinel for an iterator, indicate the traits that define a sentinel for an iterator. */ template struct ISentinelFor { ISentinelFor(); ISentinelFor(const ISentinelFor&); ISentinelFor* operator=(const ISentinelFor&); bool operator==(const I&) const&; }; // Use ISentinelFor represents a sentinel for an iterator. static_assert(CSentinelFor>, IInputOrOutputIterator>); // The CSentinelFor requires this code is valid. static_assert( requires(ISentinelFor> Sentinel, IInputOrOutputIterator Iter) { { Iter == Sentinel } -> CBooleanTestable; { Sentinel == Iter } -> CBooleanTestable; } ); /** Disable the CSizedSentinelFor concept for specific types. */ template inline constexpr bool bDisableSizedSentinelFor = false; /** * A concept specifies a type is a sized sentinel for an iterator and expressions 'Sentinel - Iter' and 'Iter - Sentinel' are valid, * and the 'Sentinel - Iter' is equal to negative 'Iter - Sentinel'. * In addition, the type must be default constructible and copyable. */ template concept CSizedSentinelFor = CSentinelFor && !bDisableSizedSentinelFor, TRemoveCVRef> && requires(const I& Iter, const S& Sentinel) { { Sentinel - Iter } -> CSameAs; { Iter - Sentinel } -> CSameAs; }; /** This is an example of a sized sentinel for an iterator, indicate the traits that define a sized sentinel for an iterator. */ template struct ISizedSentinelFor /* : ISentinelFor */ { ISizedSentinelFor(); // Also satisfies ISentinelFor. ISizedSentinelFor(const ISizedSentinelFor&); ISizedSentinelFor(ISizedSentinelFor&&); // Also satisfies ISentinelFor. ISizedSentinelFor& operator=(const ISizedSentinelFor&); ISizedSentinelFor& operator=(ISizedSentinelFor&&); // Also satisfies ISentinelFor. bool operator==(const I&) const&; // Also satisfies ISentinelFor. /** Subtraction operator. The 'Sentinel - Iter' is equal to negative 'Iter - Sentinel'. */ friend ptrdiff operator-(const I&, const ISizedSentinelFor&); friend ptrdiff operator-(const ISizedSentinelFor&, const I&); }; // Use ISizedSentinelFor represents a sized sentinel for an iterator. static_assert(CSizedSentinelFor>, IInputOrOutputIterator>); // The CSentinelFor requires this code is valid. static_assert( requires(ISizedSentinelFor> Sentinel, IInputOrOutputIterator Iter) { { Iter == Sentinel } -> CBooleanTestable; { Sentinel == Iter } -> CBooleanTestable; { Iter - Sentinel } -> CSameAs; { Sentinel - Iter } -> CSameAs; } ); #if PLATFORM_COMPILER_GCC # pragma GCC diagnostic pop #endif NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END