#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 { /** Default constructor. */ ISentinelFor(); /** Copy constructor. */ ISentinelFor(const ISentinelFor&); /** Copy assignment operator. */ ISentinelFor* operator=(const ISentinelFor&); /** Equality operator. */ 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 */ { /** Default constructor. */ ISizedSentinelFor(); /** Copy constructor. */ ISizedSentinelFor(const ISizedSentinelFor&); /** Copy assignment operator. */ ISizedSentinelFor& operator=(const ISizedSentinelFor&); /** Equality operator. */ bool operator==(const I&) const&; /** 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