#pragma once #include template class ImmutableStringBase { public: constexpr ImmutableStringBase(const Tchar* Value); // Returns a null-terminated string constexpr const Tchar* ToCString() const; // Returns the length of the string in characters constexpr uint32_t Length() const; // Standard logical casts constexpr operator Tchar*(void) const; constexpr operator const Tchar*(void) const; // Iterator definitions, for for(& :) loop constexpr Tchar* begin() const noexcept; constexpr Tchar* end() const noexcept; // Array index operator constexpr const Tchar& operator[](uint32_t Index) const; private: uint32_t _StoreSize; const Tchar* _Buffer; // Calculates the length of the string, including the null-terminator constexpr uint32_t ExpressionLength(const Tchar* Value); }; template inline constexpr ImmutableStringBase::ImmutableStringBase(const Tchar* Value) : _StoreSize(ExpressionLength(Value)), _Buffer(Value) { } template inline constexpr const Tchar* ImmutableStringBase::ToCString() const { return (const Tchar*)&this->_Buffer[0]; } template inline constexpr uint32_t ImmutableStringBase::Length() const { return this->_StoreSize; } template inline constexpr ImmutableStringBase::operator Tchar*(void) const { return (Tchar*)&this->_Buffer[0]; } template inline constexpr ImmutableStringBase::operator const Tchar*(void) const { return (const Tchar*)&this->_Buffer[0]; } template inline constexpr Tchar* ImmutableStringBase::begin() const noexcept { return (Tchar*)&this->_Buffer[0]; } template inline constexpr Tchar* ImmutableStringBase::end() const noexcept { return (Tchar*)&this->_Buffer[this->_StoreSize]; } template inline constexpr const Tchar& ImmutableStringBase::operator[](uint32_t Index) const { return this->_Buffer[Index]; } template inline constexpr uint32_t ImmutableStringBase::ExpressionLength(const Tchar* Value) { if constexpr (sizeof(Tchar) == sizeof(char)) return (uint32_t)strlen(Value); else return (uint32_t)wcslen(Value); } // // Predefined immutable string types // // An immutable string using imstring = ImmutableStringBase; // An immutable string using ImString = ImmutableStringBase; // An immutable wide string using wimstring = ImmutableStringBase; // An immutable wide string using WImString = ImmutableStringBase;