git: fab3a2f25cc1 - main - devel/sfml: Unbreak build on 14.x, 15.x

From: Dmitry Marakasov <amdmi3_at_FreeBSD.org>
Date: Thu, 10 Jul 2025 18:44:03 UTC
The branch main has been updated by amdmi3:

URL: https://cgit.FreeBSD.org/ports/commit/?id=fab3a2f25cc1f31d87aa0094f884dd4e8f37180f

commit fab3a2f25cc1f31d87aa0094f884dd4e8f37180f
Author:     Dmitry Marakasov <amdmi3@FreeBSD.org>
AuthorDate: 2025-07-10 18:41:52 +0000
Commit:     Dmitry Marakasov <amdmi3@FreeBSD.org>
CommitDate: 2025-07-10 18:43:56 +0000

    devel/sfml: Unbreak build on 14.x, 15.x
    
    PR:             281540, 287881
    Patch by:       dim
    Reported by:    dim, diizzy
---
 devel/sfml/Makefile                                |   2 -
 .../files/patch-include_SFML_System_String.hpp     | 134 +++++++++++++++++++++
 2 files changed, 134 insertions(+), 2 deletions(-)

diff --git a/devel/sfml/Makefile b/devel/sfml/Makefile
index 1f4725c6abd4..74a0f24d8271 100644
--- a/devel/sfml/Makefile
+++ b/devel/sfml/Makefile
@@ -11,8 +11,6 @@ WWW=		https://www.sfml-dev.org/ \
 LICENSE=	ZLIB
 LICENSE_FILE=	${WRKSRC}/license.md
 
-BROKEN_FreeBSD_15=	compilation fails with libc++ 19, see PR281540
-
 USES=		cmake compiler:c++11-lang
 USE_GITHUB=	yes
 CMAKE_ON=	SFML_USE_SYSTEM_DEPS
diff --git a/devel/sfml/files/patch-include_SFML_System_String.hpp b/devel/sfml/files/patch-include_SFML_System_String.hpp
new file mode 100644
index 000000000000..ae79639bd4a2
--- /dev/null
+++ b/devel/sfml/files/patch-include_SFML_System_String.hpp
@@ -0,0 +1,134 @@
+--- include/SFML/System/String.hpp.orig	2023-10-30 00:03:26 UTC
++++ include/SFML/System/String.hpp
+@@ -35,6 +35,131 @@
+ #include <string>
+ 
+ 
++namespace std
++{
++
++namespace // anonymous
++{
++
++template<class CharType, class IntType, IntType EOFVal>
++struct char_traits_base
++{
++    using char_type  = CharType;
++    using int_type   = IntType;
++    using off_type   = streamoff;
++    using pos_type   = fpos<mbstate_t>;
++    using state_type = mbstate_t;
++
++    static inline constexpr void assign(char_type& c1, const char_type& c2) noexcept
++    {
++        c1 = c2;
++    }
++
++    static inline constexpr bool eq(char_type c1, char_type c2) noexcept
++    {
++        return c1 == c2;
++    }
++
++    static inline constexpr bool lt(char_type c1, char_type c2) noexcept
++    {
++        return c1 < c2;
++    }
++
++    static constexpr int compare(const char_type* lhs, const char_type* rhs, size_t count) noexcept
++    {
++        for (; count; --count, ++lhs, ++rhs)
++        {
++            if (lt(*lhs, *rhs))
++                return -1;
++            if (lt(*rhs, *lhs))
++                return 1;
++        }
++        return 0;
++    }
++
++    static inline size_t constexpr length(const char_type* s) noexcept
++    {
++        size_t i = 0;
++        for (; s[i] != '\0'; ++i)
++        {
++        }
++        return i;
++    }
++
++    static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a) noexcept
++    {
++        for (; n; --n)
++        {
++            if (*s == a)
++                return s;
++            ++s;
++        }
++        return nullptr;
++    }
++
++    static inline char_type* move(char_type* s1, const char_type* s2, size_t n) noexcept
++    {
++        return reinterpret_cast<char_type*>(__builtin_memmove(s1, s2, n * sizeof(char_type)));
++    }
++
++    static inline char_type* copy(char_type* s1, const char_type* s2, size_t n) noexcept
++    {
++        __builtin_memmove(s1, s2, n * sizeof(char_type));
++        return s1;
++    }
++
++    static inline char_type* assign(char_type* s, size_t n, char_type a) noexcept
++    {
++        std::fill_n(s, n, a);
++        return s;
++    }
++
++    static inline constexpr int_type not_eof(int_type c) noexcept
++    {
++        return eq_int_type(c, eof()) ? ~eof() : c;
++    }
++
++    static inline constexpr char_type to_char_type(int_type c) noexcept
++    {
++        return char_type(c);
++    }
++
++    static inline constexpr int_type to_int_type(char_type c) noexcept
++    {
++        return int_type(c);
++    }
++
++    static inline constexpr bool eq_int_type(int_type c1, int_type c2) noexcept
++    {
++        return c1 == c2;
++    }
++
++    static inline constexpr int_type eof() noexcept
++    {
++        return int_type(EOF);
++    }
++};
++
++} // namespace anonymous
++
++template<>
++struct char_traits<unsigned char> : char_traits_base<unsigned char, unsigned int, static_cast<unsigned int>(EOF)>
++{
++};
++
++template<>
++struct char_traits<unsigned short> : char_traits_base<unsigned short, unsigned int, static_cast<unsigned int>(0xFFFF)>
++{
++};
++
++template<>
++struct char_traits<unsigned int> : char_traits_base<unsigned int, unsigned int, static_cast<unsigned int>(0xFFFFFFFF)>
++{
++};
++
++} // namespace std
++
++
+ namespace sf
+ {
+ ////////////////////////////////////////////////////////////