LWG 3266. to_chars(bool) should be deleted
authorJonathan Wakely <jwakely@redhat.com>
Tue, 10 Sep 2019 09:08:20 +0000 (10:08 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Tue, 10 Sep 2019 09:08:20 +0000 (10:08 +0100)
The standard requires overloads of std::to_chars for char and (un)signed
integer types. This means that our constrained function template is
non-conforming, because the difference is observable when using types
that convert to an integer (e.g. wchar_t, which promotes).

As well as defining the deleted bool overload for LWG 3266, replace the
constrained function template with overloads for each type.

* include/std/charconv (to_chars): Rename to __to_chars_i. Define
non-template overloads for each signed and unsigned integer type and
char. Define deleted overload for bool (LWG 3266).
* testsuite/20_util/to_chars/1_neg.cc: Remove.
* testsuite/20_util/to_chars/3.cc: New test.
* testsuite/20_util/to_chars/lwg3266.cc: New test.

From-SVN: r275588

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/charconv
libstdc++-v3/testsuite/20_util/to_chars/1_neg.cc [deleted file]
libstdc++-v3/testsuite/20_util/to_chars/3.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/to_chars/lwg3266.cc [new file with mode: 0644]

index f5d2146cdd0098721e5880f3ce43a37c74d35b63..b7f823e4a825c66e39e5ee850287a20a9b5b4fc8 100644 (file)
@@ -1,3 +1,12 @@
+2019-09-10  Jonathan Wakely  <jwakely@redhat.com>
+
+       * include/std/charconv (to_chars): Rename to __to_chars_i. Define
+       non-template overloads for each signed and unsigned integer type and
+       char. Define deleted overload for bool (LWG 3266).
+       * testsuite/20_util/to_chars/1_neg.cc: Remove.
+       * testsuite/20_util/to_chars/3.cc: New test.
+       * testsuite/20_util/to_chars/lwg3266.cc: New test.
+
 2019-09-10  Christophe Lyon  <christophe.lyon@st.com>
 
        * acinclude.m4: Handle uclinux*.
index ceefa3b6778124768abe082dce18328a7f678945..65f183f61f40fc2f3f65563984281eb1c0ab7697 100644 (file)
@@ -305,7 +305,7 @@ namespace __detail
 
   template<typename _Tp>
     __detail::__integer_to_chars_result_type<_Tp>
-    to_chars(char* __first, char* __last, _Tp __value, int __base = 10)
+    __to_chars_i(char* __first, char* __last, _Tp __value, int __base = 10)
     {
       __glibcxx_assert(2 <= __base && __base <= 36);
 
@@ -341,6 +341,43 @@ namespace __detail
       }
     }
 
+#define _GLIBCXX_TO_CHARS(T) \
+  inline to_chars_result \
+  to_chars(char* __first, char* __last, T __value, int __base = 10) \
+  { return std::__to_chars_i<T>(__first, __last, __value, __base); }
+_GLIBCXX_TO_CHARS(char)
+_GLIBCXX_TO_CHARS(signed char)
+_GLIBCXX_TO_CHARS(unsigned char)
+_GLIBCXX_TO_CHARS(signed short)
+_GLIBCXX_TO_CHARS(unsigned short)
+_GLIBCXX_TO_CHARS(signed int)
+_GLIBCXX_TO_CHARS(unsigned int)
+_GLIBCXX_TO_CHARS(signed long)
+_GLIBCXX_TO_CHARS(unsigned long)
+_GLIBCXX_TO_CHARS(signed long long)
+_GLIBCXX_TO_CHARS(unsigned long long)
+#if defined(__GLIBCXX_TYPE_INT_N_0)
+_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_0)
+_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_0)
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_1)
+_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_1)
+_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_1)
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_2)
+_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_2)
+_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_2)
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_3)
+_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_3)
+_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_3)
+#endif
+#undef _GLIBCXX_TO_CHARS
+
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 3266. to_chars(bool) should be deleted
+  to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
+
 namespace __detail
 {
   template<typename _Tp>
diff --git a/libstdc++-v3/testsuite/20_util/to_chars/1_neg.cc b/libstdc++-v3/testsuite/20_util/to_chars/1_neg.cc
deleted file mode 100644 (file)
index d125eda..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (C) 2017-2019 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// { dg-options "-std=gnu++17" }
-// { dg-do compile { target c++17 } }
-
-#include <charconv>
-
-void
-test01(char* first, char* last)
-{
-#if _GLIBCXX_USE_WCHAR_T
-  std::to_chars(first, last, L'\x1'); // { dg-error "no matching" }
-  std::to_chars(first, last, L'\x1', 10); // { dg-error "no matching" }
-#endif
-
-  std::to_chars(first, last, u'\x1'); // { dg-error "no matching" }
-  std::to_chars(first, last, u'\x1', 10); // { dg-error "no matching" }
-  std::to_chars(first, last, U'\x1'); // { dg-error "no matching" }
-  std::to_chars(first, last, U'\x1', 10); // { dg-error "no matching" }
-}
-
-// { dg-prune-output "enable_if" }
diff --git a/libstdc++-v3/testsuite/20_util/to_chars/3.cc b/libstdc++-v3/testsuite/20_util/to_chars/3.cc
new file mode 100644 (file)
index 0000000..f8372fd
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++17 } }
+// { dg-require-string-conversions "" }
+
+#include <charconv>
+#include <string_view>
+#include <testsuite_hooks.h>
+
+template<typename C>
+bool
+check_to_chars(C val)
+{
+  using std::string_view;
+
+  char buf1[32], buf2[32], buf3[32];
+  std::to_chars_result r1 = std::to_chars(buf1, buf1+sizeof(buf1), val);
+  if (r1.ec != std::errc{})
+    return false;
+  std::to_chars_result r2 = std::to_chars(buf2, buf2+sizeof(buf2), val, 10);
+  if (r2.ec != std::errc{})
+    return false;
+  if (string_view(buf1, r1.ptr - buf1) != string_view(buf2, r2.ptr - buf2))
+    return false;
+  std::to_chars_result r3 = std::to_chars(buf3, buf3+sizeof(buf3), (long)val);
+  if (string_view(buf1, r1.ptr - buf1) != string_view(buf3, r3.ptr - buf3))
+    return false;
+  return true;
+}
+
+void
+test01()
+{
+  VERIFY( check_to_chars(u'\x21') );
+  VERIFY( check_to_chars(U'\x21') );
+#if _GLIBCXX_USE_WCHAR_T
+  VERIFY( check_to_chars(L'\x21') );
+#endif
+}
+
+int main()
+{
+  test01();
+}
diff --git a/libstdc++-v3/testsuite/20_util/to_chars/lwg3266.cc b/libstdc++-v3/testsuite/20_util/to_chars/lwg3266.cc
new file mode 100644 (file)
index 0000000..01c2c6c
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++17 } }
+
+#include <charconv>
+
+void
+test01(char* first, char* last)
+{
+  // LWG 3266. to_chars(bool) should be deleted
+  char buf;
+  std::to_chars(&buf, &buf + 1, true);     // { dg-error "deleted function" }
+  std::to_chars(&buf, &buf + 1, false, 10); // { dg-error "deleted function" }
+}