[PATCH] PR libstdc++/89728 diagnose some missuses of [locale.convenience] functions

Jonathan Wakely jwakely@redhat.com
Tue May 11 20:00:31 GMT 2021


On 11/05/21 21:27 +0300, Antony Polukhin via Libstdc++ wrote:
>This patch provides compile time diagnostics for common misuse of
>[locale.convenience] functions with std::string as a character type.
>
>
>2021-05-11  Antony Polukhin  <antoshkka@gmail.com>
>
>PR libstdc++/89728
>  * include/bits/locale_facets.h (ctype) Add static assert.
>  * testsuite/22_locale/ctype/is/string/89728_neg.cc New test.
>
>-- 
>Best regards,
>Antony Polukhin

>diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h
>index 03724cf..012857f 100644
>--- a/libstdc++-v3/include/bits/locale_facets.h
>+++ b/libstdc++-v3/include/bits/locale_facets.h
>@@ -136,6 +136,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>       return __s;
>     }
>
>+  template<typename>
>+    struct __is_string
>+    {
>+	enum _Value { _value = 0 };

The _value member needs to use double underscores.

But since this is only used in a static_assert, which is only
available in C++11, I think it can just derive from std::false_type
instead.

>+    };
>+
>+  template<typename _CharT, typename _Traits, typename _Alloc>
>+    struct __is_string<basic_string<_CharT, _Traits, _Alloc> >
>+    {
>+	enum _Value { _value = 1 };
>+    };
>
>   // 22.2.1.1  Template class ctype
>   // Include host and configuration specific ctype enums for ctype_base.
>@@ -614,6 +625,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   template<typename _CharT>
>     class ctype : public __ctype_abstract_base<_CharT>
>     {
>+#if __cplusplus >= 201103L
>+      static_assert(!__is_string<_CharT>::_value,
>+		    "std::basic_string used as a character type");
>+#endif
>     public:
>       // Types:
>       typedef _CharT			char_type;

Alternatively, would it be even simpler to just define a partial
specialization of ctype?

template<typename _CharT, typename _Traits, typename _Alloc>
   class ctype<basic_string<_CharT, _Traits, _Alloc> >
   {
#if __cplusplus >= 201103L
       static_assert(something dependent,
		    "std::basic_string used as a character type");
#endif
   private:
     ctype();
     ~ctype();
   };

This will work in C++98 too.



More information about the Gcc-patches mailing list