diff --git a/third_party/sfml/README.vbam b/third_party/sfml/README.vbam index 1cf0cf13..d41f758d 100644 --- a/third_party/sfml/README.vbam +++ b/third_party/sfml/README.vbam @@ -4,5 +4,7 @@ emulator. The original SFML library can be found at http://www.sfml-dev.org/ This uses SFML 2.6.2 as a basis, with the following modifications: * Upstream commit [9022d956](https://github.com/SFML/SFML/commit/9022d956) was partially backported to fix a compilation failure with modern Clang. +* Added `U32StringCharTraits` in `include\SFML\System\String.hpp` to work around + a compilation failure on macOS. * `` was added as an include in `src\SFML\System\Win32\SleepImpl.cpp` to fix a compilation failure with MSVC. diff --git a/third_party/sfml/include/SFML/System/String.hpp b/third_party/sfml/include/SFML/System/String.hpp index 420ab88e..82d7e52b 100644 --- a/third_party/sfml/include/SFML/System/String.hpp +++ b/third_party/sfml/include/SFML/System/String.hpp @@ -76,6 +76,44 @@ struct SFML_SYSTEM_API U8StringCharTraits //////////////////////////////////////////////////////////// using U8String = std::basic_string; +//////////////////////////////////////////////////////////// +/// \brief Character traits for std::uint32_t +/// +//////////////////////////////////////////////////////////// +struct SFML_SYSTEM_API U32StringCharTraits +{ + // NOLINTBEGIN(readability-identifier-naming) + using char_type = std::uint32_t; + using int_type = std::char_traits::int_type; + using off_type = std::char_traits::off_type; + using pos_type = std::char_traits::pos_type; + using state_type = std::char_traits::state_type; + static void assign(char_type& c1, char_type c2) noexcept; + static char_type* assign(char_type* s, std::size_t n, char_type c); + static bool eq(char_type c1, char_type c2) noexcept; + static bool lt(char_type c1, char_type c2) noexcept; + static char_type* move(char_type* s1, const char_type* s2, std::size_t n); + static char_type* copy(char_type* s1, const char_type* s2, std::size_t n); + static int compare(const char_type* s1, const char_type* s2, std::size_t n); + static std::size_t length(const char_type* s); + static const char_type* find(const char_type* s, std::size_t n, const char_type& c); + static char_type to_char_type(int_type i) noexcept; + static int_type to_int_type(char_type c) noexcept; + static bool eq_int_type(int_type i1, int_type i2) noexcept; + static int_type eof() noexcept; + static int_type not_eof(int_type i) noexcept; + // NOLINTEND(readability-identifier-naming) +}; +//////////////////////////////////////////////////////////// +/// \brief Portable replacement for std::basic_string +/// +/// While all major C++ implementations happen to define this +/// as of early 2024, this specialization is not strictly speaking +/// standard C++. Thus we can't depend on its continued existence. +/// +//////////////////////////////////////////////////////////// +using U32String = std::basic_string; + //////////////////////////////////////////////////////////// /// \brief Utility string class that automatically handles /// conversions between types and encodings @@ -88,8 +126,8 @@ public: //////////////////////////////////////////////////////////// // Types //////////////////////////////////////////////////////////// - typedef std::basic_string::iterator Iterator; //!< Iterator type - typedef std::basic_string::const_iterator ConstIterator; //!< Read-only iterator type + typedef sf::U32String::iterator Iterator; //!< Iterator type + typedef sf::U32String::const_iterator ConstIterator; //!< Read-only iterator type //////////////////////////////////////////////////////////// // Static member data @@ -186,7 +224,7 @@ public: /// \param utf32String UTF-32 string to assign /// //////////////////////////////////////////////////////////// - String(const std::basic_string& utf32String); + String(const sf::U32String& utf32String); //////////////////////////////////////////////////////////// /// \brief Copy constructor @@ -335,7 +373,7 @@ public: /// \see toUtf8, toUtf16 /// //////////////////////////////////////////////////////////// - std::basic_string toUtf32() const; + sf::U32String toUtf32() const; //////////////////////////////////////////////////////////// /// \brief Overload of assignment operator @@ -563,7 +601,7 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - std::basic_string m_string; //!< Internal string of UTF-32 characters + sf::U32String m_string; //!< Internal string of UTF-32 characters }; //////////////////////////////////////////////////////////// diff --git a/third_party/sfml/src/SFML/System/String.cpp b/third_party/sfml/src/SFML/System/String.cpp index 5270e212..ca301f71 100644 --- a/third_party/sfml/src/SFML/System/String.cpp +++ b/third_party/sfml/src/SFML/System/String.cpp @@ -108,9 +108,84 @@ U8StringCharTraits::int_type U8StringCharTraits::not_eof(int_type i) noexcept return std::char_traits::not_eof(i); } +//////////////////////////////////////////////////////////// +void U32StringCharTraits::assign(char_type& c1, char_type c2) noexcept +{ + c1 = c2; +} +//////////////////////////////////////////////////////////// +U32StringCharTraits::char_type* U32StringCharTraits::assign(char_type* s, std::size_t n, char_type c) +{ + return reinterpret_cast( + std::char_traits::assign(reinterpret_cast(s), n, static_cast(c))); +} +//////////////////////////////////////////////////////////// +bool U32StringCharTraits::eq(char_type c1, char_type c2) noexcept +{ + return c1 == c2; +} +//////////////////////////////////////////////////////////// +bool U32StringCharTraits::lt(char_type c1, char_type c2) noexcept +{ + return c1 < c2; +} +//////////////////////////////////////////////////////////// +U32StringCharTraits::char_type* U32StringCharTraits::move(char_type* s1, const char_type* s2, std::size_t n) +{ + std::memmove(s1, s2, n); + return s1; +} +//////////////////////////////////////////////////////////// +U32StringCharTraits::char_type* U32StringCharTraits::copy(char_type* s1, const char_type* s2, std::size_t n) +{ + std::memcpy(s1, s2, n); + return s1; +} +//////////////////////////////////////////////////////////// +int U32StringCharTraits::compare(const char_type* s1, const char_type* s2, std::size_t n) +{ + return std::memcmp(s1, s2, n); +} +//////////////////////////////////////////////////////////// +std::size_t U32StringCharTraits::length(const char_type* s) +{ + return std::strlen(reinterpret_cast(s)); +} +//////////////////////////////////////////////////////////// +const U32StringCharTraits::char_type* U32StringCharTraits::find(const char_type* s, std::size_t n, const char_type& c) +{ + return reinterpret_cast( + std::char_traits::find(reinterpret_cast(s), n, static_cast(c))); +} +//////////////////////////////////////////////////////////// +U32StringCharTraits::char_type U32StringCharTraits::to_char_type(int_type i) noexcept +{ + return static_cast(std::char_traits::to_char_type(i)); +} +//////////////////////////////////////////////////////////// +U32StringCharTraits::int_type U32StringCharTraits::to_int_type(char_type c) noexcept +{ + return std::char_traits::to_int_type(static_cast(c)); +} +//////////////////////////////////////////////////////////// +bool U32StringCharTraits::eq_int_type(int_type i1, int_type i2) noexcept +{ + return i1 == i2; +} +//////////////////////////////////////////////////////////// +U32StringCharTraits::int_type U32StringCharTraits::eof() noexcept +{ + return std::char_traits::eof(); +} +//////////////////////////////////////////////////////////// +U32StringCharTraits::int_type U32StringCharTraits::not_eof(int_type i) noexcept +{ + return std::char_traits::not_eof(i); +} + //////////////////////////////////////////////////////////// -const std::size_t String::InvalidPos = std::basic_string::npos; +const std::size_t String::InvalidPos = sf::U32String::npos; //////////////////////////////////////////////////////////// @@ -195,7 +270,7 @@ String::String(const Uint32* utf32String) //////////////////////////////////////////////////////////// -String::String(const std::basic_string& utf32String) : +String::String(const sf::U32String& utf32String) : m_string(utf32String) { } @@ -279,7 +354,7 @@ std::basic_string String::toUtf16() const //////////////////////////////////////////////////////////// -std::basic_string String::toUtf32() const +sf::U32String String::toUtf32() const { return m_string; }