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  <antosh...@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.

Reply via email to