]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/testsuite/20_util/from_chars/2.cc
C++17 P0067R5 std::to_chars and std::from_chars (partial)
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / from_chars / 2.cc
diff --git a/libstdc++-v3/testsuite/20_util/from_chars/2.cc b/libstdc++-v3/testsuite/20_util/from_chars/2.cc
new file mode 100644 (file)
index 0000000..117cf74
--- /dev/null
@@ -0,0 +1,205 @@
+// Copyright (C) 2017 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 } }
+
+#include <charconv>
+#include <string_view>
+#include <testsuite_hooks.h>
+
+// Test std::from_chars error handling.
+
+void
+test01()
+{
+  std::from_chars_result r;
+  int i = 999;
+  std::string_view s;
+
+  s = "";
+  r = std::from_chars(s.begin(), s.end(), i);
+  VERIFY( r.ec == std::errc::invalid_argument );
+  VERIFY( r.ptr == s.begin() );
+  VERIFY( i == 999 );
+
+  s = "*";
+  r = std::from_chars(s.begin(), s.end(), i);
+  VERIFY( r.ec == std::errc::invalid_argument );
+  VERIFY( r.ptr == s.begin() );
+  VERIFY( i == 999 );
+
+  s = "-";
+  r = std::from_chars(s.begin(), s.end(), i);
+  VERIFY( r.ec == std::errc::invalid_argument );
+  VERIFY( r.ptr == s.begin() );
+  VERIFY( i == 999 );
+
+  s = "-*";
+  r = std::from_chars(s.begin(), s.end(), i);
+  VERIFY( r.ec == std::errc::invalid_argument );
+  VERIFY( r.ptr == s.begin() );
+  VERIFY( i == 999 );
+
+  unsigned u = 888;
+  s = "-1";
+  r = std::from_chars(s.begin(), s.end(), u);
+  VERIFY( r.ec == std::errc::invalid_argument );
+  VERIFY( r.ptr == s.begin() );
+  s = "-a";
+  r = std::from_chars(s.begin(), s.end(), u);
+  VERIFY( r.ec == std::errc::invalid_argument );
+  VERIFY( r.ptr == s.begin() );
+  s = "-";
+  r = std::from_chars(s.begin(), s.end(), u);
+  VERIFY( r.ec == std::errc::invalid_argument );
+  VERIFY( r.ptr == s.begin() );
+  VERIFY( u == 888 );
+
+  for (int base = 2; base <= 36; ++base)
+  {
+    const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz*";
+    const char buf[2] = { '-', digits[base] };
+    r = std::from_chars(buf, buf + 1, i, base);
+    VERIFY( r.ec == std::errc::invalid_argument );
+    VERIFY( r.ptr == buf );
+    VERIFY( i == 999 );
+    r = std::from_chars(buf + 1, buf + 2, i, base);
+    VERIFY( r.ec == std::errc::invalid_argument );
+    VERIFY( r.ptr == buf + 1 );
+    VERIFY( i == 999 );
+    r = std::from_chars(buf, buf + 2, i, base);
+    VERIFY( r.ec == std::errc::invalid_argument );
+    VERIFY( r.ptr == buf );
+    VERIFY( i == 999 );
+  }
+}
+
+void
+test02()
+{
+  std::from_chars_result r;
+  std::string_view s;
+
+  signed char c = -5;
+  s = "-10000001";
+  r = std::from_chars(s.begin(), s.end(), c, 2);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.end() );
+  s = "-10000001*";
+  r = std::from_chars(s.begin(), s.end(), c, 2);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.begin() + 9 );
+  s = "-10000001000*";
+  r = std::from_chars(s.begin(), s.end(), c, 2);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.begin() + 12 );
+  s = "-129";
+  r = std::from_chars(s.begin(), s.end(), c, 10);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.end() );
+  s = "-129*";
+  r = std::from_chars(s.begin(), s.end(), c, 10);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.begin() + 4 );
+  s = "-100";
+  r = std::from_chars(s.begin(), s.end(), c, 16);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.end() );
+  s = "-100*";
+  r = std::from_chars(s.begin(), s.end(), c, 16);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.begin() + 4 );
+  s = "-81";
+  r = std::from_chars(s.begin(), s.end(), c, 16);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.end() );
+  s = "-81*";
+  r = std::from_chars(s.begin(), s.end(), c, 16);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.begin() + 3 );
+  s = "128";
+  r = std::from_chars(s.begin(), s.end(), c, 10);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.end() );
+  s = "128*";
+  r = std::from_chars(s.begin(), s.end(), c, 10);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.begin() + 3 );
+  s = "80";
+  r = std::from_chars(s.begin(), s.end(), c, 16);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.end() );
+  s = "80*";
+  r = std::from_chars(s.begin(), s.end(), c, 16);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.begin() + 2 );
+  VERIFY( c == -5 );
+
+  unsigned char uc = 9;
+  s = "100000000";
+  r = std::from_chars(s.begin(), s.end(), uc, 2);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.end() );
+  s = "100000000*";
+  r = std::from_chars(s.begin(), s.end(), uc, 2);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.begin() + 9 );
+  s = "100000000000*";
+  r = std::from_chars(s.begin(), s.end(), uc, 2);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.begin() + 12 );
+  s = "256";
+  r = std::from_chars(s.begin(), s.end(), uc, 10);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.end() );
+  s = "256**";
+  r = std::from_chars(s.begin(), s.end(), uc, 10);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.begin() + 3 );
+  s = "256000**";
+  r = std::from_chars(s.begin(), s.end(), uc, 10);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.begin() + 6 );
+  s = "100";
+  r = std::from_chars(s.begin(), s.end(), uc, 16);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.end() );
+  s = "100**";
+  r = std::from_chars(s.begin(), s.end(), uc, 16);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.begin() + 3 );
+  s = "100000**";
+  r = std::from_chars(s.begin(), s.end(), uc, 16);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.begin() + 6 );
+  VERIFY( uc == 9 );
+
+  unsigned long long ull = 123;
+  s = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz****";
+  r = std::from_chars(s.begin(), s.end(), ull, 36);
+  VERIFY( r.ec == std::errc::result_out_of_range );
+  VERIFY( r.ptr == s.begin() + 42 );
+  VERIFY( ull == 123 );
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}