From 50896fa491cf15bcf21418259ae4d978c0bac38c Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 9 Feb 2025 09:03:53 +0100 Subject: [PATCH] mbsstr, mbscasestr, mbspcasecmp: Use const-improved C++ templates. * lib/string.in.h (mbsstr, mbspcasecmp, mbscasestr): In C++, define through a template that supports both 'char *' and 'const char *'. --- ChangeLog | 4 +++ lib/string.in.h | 90 ++++++++++++++++++++++++++++++++++--------------- 2 files changed, 67 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index be4e2425d3..f958f3632f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2025-02-09 Bruno Haible + mbsstr, mbscasestr, mbspcasecmp: Use const-improved C++ templates. + * lib/string.in.h (mbsstr, mbspcasecmp, mbscasestr): In C++, define + through a template that supports both 'char *' and 'const char *'. + mbsstr, mbscasestr, mbspcasecmp: Use const-improved function macros. * lib/string.in.h (mbsstr, mbspcasecmp, mbscasestr): Define as macros that cast the result to 'const char *' when the first argument is a diff --git a/lib/string.in.h b/lib/string.in.h index 6705967c59..bfe949cf84 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -1178,17 +1178,29 @@ _GL_CXXALIASWARN (mbsrchr); _GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle) _GL_ATTRIBUTE_PURE _GL_ARG_NONNULL ((1, 2)); +# ifndef _GL_NO_CONST_GENERICS /* Don't silently convert a 'const char *' to a 'char *'. Programmers want compiler warnings for 'const' related mistakes. */ -# if !(defined _GL_NO_CONST_GENERICS || defined __cplusplus) -# if __STDC_VERSION__ >= 202311 -# define mbsstr(h,n) (typeof(h)) mbsstr ((h), (n)) -# elif ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \ - || defined __ICC || defined __TINYC__) -# define mbsstr(h,n) \ - _Generic ((h), \ - char const *: (char const *) mbsstr ((h), (n)), \ - default : mbsstr ((h), (n))) +# ifdef __cplusplus +template + T * mbsstr_template (T* haystack, const char *needle); +template <> + inline char * mbsstr_template (char *haystack, const char *needle) + { return mbsstr (haystack, needle); } +template <> + inline const char * mbsstr_template (const char *haystack, const char *needle) + { return mbsstr (haystack, needle); } +# define mbsstr mbsstr_template +# else +# if __STDC_VERSION__ >= 202311 +# define mbsstr(h,n) (typeof(h)) mbsstr ((h), (n)) +# elif ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \ + || defined __ICC || defined __TINYC__) +# define mbsstr(h,n) \ + _Generic ((h), \ + char const *: (char const *) mbsstr ((h), (n)), \ + default : mbsstr ((h), (n))) +# endif # endif # endif #endif @@ -1232,17 +1244,29 @@ _GL_EXTERN_C int mbsncasecmp (const char *s1, const char *s2, size_t n) _GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix) _GL_ATTRIBUTE_PURE _GL_ARG_NONNULL ((1, 2)); +# ifndef _GL_NO_CONST_GENERICS /* Don't silently convert a 'const char *' to a 'char *'. Programmers want compiler warnings for 'const' related mistakes. */ -# if !(defined _GL_NO_CONST_GENERICS || defined __cplusplus) -# if __STDC_VERSION__ >= 202311 -# define mbspcasecmp(s,p) (typeof(s)) mbspcasecmp ((s), (p)) -# elif ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \ - || defined __ICC || defined __TINYC__) -# define mbspcasecmp(s,p) \ - _Generic ((s), \ - char const *: (char const *) mbspcasecmp ((s), (p)), \ - default : mbspcasecmp ((s), (p))) +# ifdef __cplusplus +template + T * mbspcasecmp_template (T* string, const char *prefix); +template <> + inline char * mbspcasecmp_template (char *string, const char *prefix) + { return mbspcasecmp (string, prefix); } +template <> + inline const char * mbspcasecmp_template (const char *string, const char *prefix) + { return mbspcasecmp (string, prefix); } +# define mbspcasecmp mbspcasecmp_template +# else +# if __STDC_VERSION__ >= 202311 +# define mbspcasecmp(s,p) (typeof(s)) mbspcasecmp ((s), (p)) +# elif ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \ + || defined __ICC || defined __TINYC__) +# define mbspcasecmp(s,p) \ + _Generic ((s), \ + char const *: (char const *) mbspcasecmp ((s), (p)), \ + default : mbspcasecmp ((s), (p))) +# endif # endif # endif #endif @@ -1256,17 +1280,29 @@ _GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix) _GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle) _GL_ATTRIBUTE_PURE _GL_ARG_NONNULL ((1, 2)); +# ifndef _GL_NO_CONST_GENERICS /* Don't silently convert a 'const char *' to a 'char *'. Programmers want compiler warnings for 'const' related mistakes. */ -# if !(defined _GL_NO_CONST_GENERICS || defined __cplusplus) -# if __STDC_VERSION__ >= 202311 -# define mbscasestr(h,n) (typeof(h)) mbscasestr ((h), (n)) -# elif ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \ - || defined __ICC || defined __TINYC__) -# define mbscasestr(h,n) \ - _Generic ((h), \ - char const *: (char const *) mbscasestr ((h), (n)), \ - default : mbscasestr ((h), (n))) +# ifdef __cplusplus +template + T * mbscasestr_template (T* haystack, const char *needle); +template <> + inline char * mbscasestr_template (char *haystack, const char *needle) + { return mbscasestr (haystack, needle); } +template <> + inline const char * mbscasestr_template (const char *haystack, const char *needle) + { return mbscasestr (haystack, needle); } +# define mbscasestr mbscasestr_template +# else +# if __STDC_VERSION__ >= 202311 +# define mbscasestr(h,n) (typeof(h)) mbscasestr ((h), (n)) +# elif ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \ + || defined __ICC || defined __TINYC__) +# define mbscasestr(h,n) \ + _Generic ((h), \ + char const *: (char const *) mbscasestr ((h), (n)), \ + default : mbscasestr ((h), (n))) +# endif # endif # endif #endif -- 2.39.5