diff --git a/Convention/[Runtime]/Config.hpp b/Convention/[Runtime]/Config.hpp index b99c891..57bc2f6 100644 --- a/Convention/[Runtime]/Config.hpp +++ b/Convention/[Runtime]/Config.hpp @@ -272,14 +272,18 @@ constexpr int ConstexprStrCompare( #endif // PLATFORM_EXTENSION struct PlatformIndicator + : public +#ifdef _DEBUG + std::false_type +#else + std::true_type +#endif { - using tag = void; #ifdef _DEBUG constexpr static bool IsRelease = false; #else constexpr static bool IsRelease = true; #endif - constexpr static bool value = IsRelease; #if defined(_WIN64)||defined(_WIN32) constexpr static bool IsPlatformWindows = true; #else diff --git a/Convention/[Runtime]/Generics/Sequence.hpp b/Convention/[Runtime]/Generics/Sequence.hpp index 37fbfed..6bc4928 100644 --- a/Convention/[Runtime]/Generics/Sequence.hpp +++ b/Convention/[Runtime]/Generics/Sequence.hpp @@ -1,3 +1,12 @@ +/** +* @brief 序列 +* @contains SequenceTrait 序列性状 +* @contains SequenceIndicator 指示序列动作 +* @contains Array 数组 +* @contains BoolArray bool数组 +* @contains Vector 可变数组 +*/ + #pragma once #ifndef Convention_Runtime_Generics_Sequence_hpp #define Convention_Runtime_Generics_Sequence_hpp @@ -9,6 +18,71 @@ namespace Convention namespace Generics { + /** + * @brief 序列性状, 用于静态判断 + * @tparam Sequence 序列类型 + */ + template + struct SequenceTrait + { + constexpr static bool _IsSequence() + { + if_exists(Sequence::begin) + { + if_exists(Sequence::end) + { + if_exists(Sequence::cbegin) + { + if_exists(Sequence::cend) + { + if_exists(Sequence::operator[]) + { + return true; + } + } + } + } + } + return false; + }; + constexpr static bool IsSequence = _IsSequence(); + }; + + /** + * @brief 序列指示器, 序列动作的适配器 + * @tparam Sequence 序列类型 + */ + template + struct SequenceIndicator + { + static_assert(SequenceTrait::IsSequence, + "Current template type is not a Sequence"); + using iterator = decltype(std::declval().begin()); + using const_iterator = decltype(std::declval().cbegin()); + using element = std::decay_t()[0])>; + + static iterator begin(Sequence& self) + { + return self.begin(); + } + static iterator end(Sequence& self) + { + return self.end(); + } + static const_iterator begin(const Sequence& self) + { + return self.cbegin(); + } + static const_iterator end(const Sequence& self) + { + return self.cend(); + } + static element& at(Sequence& self, int index) + { + return self[index]; + } + }; + /** * @brief 栈上静态数组 * @tparam Element 内容物类型 @@ -18,6 +92,263 @@ namespace Convention template using Array = std::array; + namespace internal + { + template + class _BoolArray_const_iterator +#if _ITERATOR_DEBUG_LEVEL != 0 + : private _Iterator_base12_compatible +#endif // _ITERATOR_DEBUG_LEVEL != 0 + { + public: + using _Ty = bool; +#if _HAS_CXX20 + using iterator_concept = contiguous_iterator_tag; +#endif // _HAS_CXX20 + using iterator_category = random_access_iterator_tag; + using value_type = _Ty; + using difference_type = ptrdiff_t; + using pointer = const _Ty*; + using reference = const _Ty&; + + enum { _EEN_SIZE = _Size }; // helper for expression evaluator + +#if _ITERATOR_DEBUG_LEVEL == 0 + _CONSTEXPR17 _Array_const_iterator() noexcept : _Ptr() {} + + _CONSTEXPR17 explicit _Array_const_iterator(pointer _Parg, size_t _Off = 0) noexcept : _Ptr(_Parg + _Off) {} + + _NODISCARD _CONSTEXPR17 reference operator*() const noexcept { + return *_Ptr; + } + + _NODISCARD _CONSTEXPR17 pointer operator->() const noexcept { + return _Ptr; + } + + _CONSTEXPR17 _Array_const_iterator& operator++() noexcept { + ++_Ptr; + return *this; + } + + _CONSTEXPR17 _Array_const_iterator operator++(int) noexcept { + _Array_const_iterator _Tmp = *this; + ++_Ptr; + return _Tmp; + } + + _CONSTEXPR17 _Array_const_iterator& operator--() noexcept { + --_Ptr; + return *this; + } + + _CONSTEXPR17 _Array_const_iterator operator--(int) noexcept { + _Array_const_iterator _Tmp = *this; + --_Ptr; + return _Tmp; + } + + _CONSTEXPR17 _Array_const_iterator& operator+=(const ptrdiff_t _Off) noexcept { + _Ptr += _Off; + return *this; + } + + _CONSTEXPR17 _Array_const_iterator& operator-=(const ptrdiff_t _Off) noexcept { + _Ptr -= _Off; + return *this; + } + + _NODISCARD _CONSTEXPR17 ptrdiff_t operator-(const _Array_const_iterator& _Right) const noexcept { + return _Ptr - _Right._Ptr; + } + + _NODISCARD _CONSTEXPR17 reference operator[](const ptrdiff_t _Off) const noexcept { + return _Ptr[_Off]; + } + + _NODISCARD _CONSTEXPR17 bool operator==(const _Array_const_iterator& _Right) const noexcept { + return _Ptr == _Right._Ptr; + } + +#if _HAS_CXX20 + _NODISCARD constexpr strong_ordering operator<=>(const _Array_const_iterator& _Right) const noexcept { + return _Ptr <=> _Right._Ptr; + } +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv + _NODISCARD _CONSTEXPR17 bool operator<(const _Array_const_iterator& _Right) const noexcept { + return _Ptr < _Right._Ptr; + } +#endif // ^^^ !_HAS_CXX20 ^^^ + + using _Prevent_inheriting_unwrap = _Array_const_iterator; + + _NODISCARD constexpr pointer _Unwrapped() const noexcept { + return _Ptr; + } + + static constexpr bool _Unwrap_when_unverified = true; + + constexpr void _Seek_to(pointer _It) noexcept { + _Ptr = _It; + } + + private: + pointer _Ptr; // beginning of array + +#else // ^^^ _ITERATOR_DEBUG_LEVEL == 0 / _ITERATOR_DEBUG_LEVEL != 0 vvv + _CONSTEXPR17 _Array_const_iterator() noexcept : _Ptr(), _Idx(0) {} + + _CONSTEXPR17 explicit _Array_const_iterator(pointer _Parg, size_t _Off = 0) noexcept : _Ptr(_Parg), _Idx(_Off) {} + + _NODISCARD _CONSTEXPR17 reference operator*() const noexcept { + return *operator->(); + } + + _NODISCARD _CONSTEXPR17 pointer operator->() const noexcept { + _STL_VERIFY(_Ptr, "cannot dereference value-initialized array iterator"); + _STL_VERIFY(_Idx < _Size, "cannot dereference out of range array iterator"); + return _Ptr + _Idx; + } + + _CONSTEXPR17 _Array_const_iterator& operator++() noexcept { + _STL_VERIFY(_Ptr, "cannot increment value-initialized array iterator"); + _STL_VERIFY(_Idx < _Size, "cannot increment array iterator past end"); + ++_Idx; + return *this; + } + + _CONSTEXPR17 _Array_const_iterator operator++(int) noexcept { + _Array_const_iterator _Tmp = *this; + ++*this; + return _Tmp; + } + + _CONSTEXPR17 _Array_const_iterator& operator--() noexcept { + _STL_VERIFY(_Ptr, "cannot decrement value-initialized array iterator"); + _STL_VERIFY(_Idx != 0, "cannot decrement array iterator before begin"); + --_Idx; + return *this; + } + + _CONSTEXPR17 _Array_const_iterator operator--(int) noexcept { + _Array_const_iterator _Tmp = *this; + --*this; + return _Tmp; + } + + constexpr void _Verify_offset(const ptrdiff_t _Off) const noexcept { + if (_Off != 0) { + _STL_VERIFY(_Ptr, "cannot seek value-initialized array iterator"); + } + + if (_Off < 0) { + _STL_VERIFY(_Idx >= size_t{ 0 } - static_cast(_Off), "cannot seek array iterator before begin"); + } + + if (_Off > 0) { + _STL_VERIFY(_Size - _Idx >= static_cast(_Off), "cannot seek array iterator after end"); + } + } + + _CONSTEXPR17 _Array_const_iterator& operator+=(const ptrdiff_t _Off) noexcept { + _Verify_offset(_Off); + _Idx += static_cast(_Off); + return *this; + } + + _CONSTEXPR17 _Array_const_iterator& operator-=(const ptrdiff_t _Off) noexcept { + return *this += -_Off; + } + + _NODISCARD _CONSTEXPR17 ptrdiff_t operator-(const _Array_const_iterator& _Right) const noexcept { + _Compat(_Right); + return static_cast(_Idx - _Right._Idx); + } + + _NODISCARD _CONSTEXPR17 reference operator[](const ptrdiff_t _Off) const noexcept { + return *(*this + _Off); + } + + _NODISCARD _CONSTEXPR17 bool operator==(const _Array_const_iterator& _Right) const noexcept { + _Compat(_Right); + return _Idx == _Right._Idx; + } + +#if _HAS_CXX20 + _NODISCARD constexpr strong_ordering operator<=>(const _Array_const_iterator& _Right) const noexcept { + _Compat(_Right); + return _Idx <=> _Right._Idx; + } +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv + _NODISCARD _CONSTEXPR17 bool operator<(const _Array_const_iterator& _Right) const noexcept { + _Compat(_Right); + return _Idx < _Right._Idx; + } +#endif // ^^^ !_HAS_CXX20 ^^^ + + _CONSTEXPR17 void _Compat(const _Array_const_iterator& _Right) const noexcept { // test for compatible iterator pair + _STL_VERIFY(_Ptr == _Right._Ptr, "array iterators incompatible"); + } + + using _Prevent_inheriting_unwrap = _Array_const_iterator; + + _NODISCARD constexpr pointer _Unwrapped() const noexcept { + return _Ptr + _Idx; + } + + constexpr void _Verify_with(const _Array_const_iterator& _Last) const noexcept { + // note _Compat check inside operator<= + _STL_VERIFY(*this <= _Last, "array iterator range transposed"); + } + + constexpr void _Seek_to(pointer _It) noexcept { + _Idx = static_cast(_It - _Ptr); + } + + private: + pointer _Ptr; // beginning of array + size_t _Idx; // offset into array +#endif // ^^^ _ITERATOR_DEBUG_LEVEL != 0 ^^^ + + public: + _NODISCARD _CONSTEXPR17 _Array_const_iterator operator+(const ptrdiff_t _Off) const noexcept { + _Array_const_iterator _Tmp = *this; + _Tmp += _Off; + return _Tmp; + } + + _NODISCARD _CONSTEXPR17 _Array_const_iterator operator-(const ptrdiff_t _Off) const noexcept { + _Array_const_iterator _Tmp = *this; + _Tmp -= _Off; + return _Tmp; + } + + _NODISCARD friend _CONSTEXPR17 _Array_const_iterator operator+( + const ptrdiff_t _Off, _Array_const_iterator _Next) noexcept { + _Next += _Off; + return _Next; + } + +#if !_HAS_CXX20 + _NODISCARD _CONSTEXPR17 bool operator!=(const _Array_const_iterator& _Right) const noexcept { + return !(*this == _Right); + } + + _NODISCARD _CONSTEXPR17 bool operator>(const _Array_const_iterator& _Right) const noexcept { + return _Right < *this; + } + + _NODISCARD _CONSTEXPR17 bool operator<=(const _Array_const_iterator& _Right) const noexcept { + return !(_Right < *this); + } + + _NODISCARD _CONSTEXPR17 bool operator>=(const _Array_const_iterator& _Right) const noexcept { + return !(*this < _Right); + } +#endif // !_HAS_CXX20 + }; + } + /** * @brief 栈上静态Bool数组 * @tparam size 元素大小