summaryrefslogtreecommitdiffstats
path: root/libcxx/test
diff options
context:
space:
mode:
authorHoward Hinnant <hhinnant@apple.com>2010-05-30 21:39:41 +0000
committerHoward Hinnant <hhinnant@apple.com>2010-05-30 21:39:41 +0000
commit0c17e32edda76b1745f2c2713f61fdca00ae4e07 (patch)
tree8e84289bfa528b3b3dc69c04cd52c378375ebb95 /libcxx/test
parent71eac6e114c217b1596ad1366ca20e3cdec21c77 (diff)
downloadbcm5719-llvm-0c17e32edda76b1745f2c2713f61fdca00ae4e07.tar.gz
bcm5719-llvm-0c17e32edda76b1745f2c2713f61fdca00ae4e07.zip
[locale.stdcvt]
llvm-svn: 105174
Diffstat (limited to 'libcxx/test')
-rw-r--r--libcxx/test/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/utf_sanity_check.pass.cpp34
-rw-r--r--libcxx/test/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp2
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_mode.pass.cpp29
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf16.pass.cpp56
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf16_always_noconv.pass.cpp45
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf16_encoding.pass.cpp45
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf16_in.pass.cpp739
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf16_length.pass.cpp449
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf16_max_length.pass.cpp63
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf16_out.pass.cpp331
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf16_unshift.pass.cpp56
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf8.pass.cpp56
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf8_always_noconv.pass.cpp45
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf8_encoding.pass.cpp45
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf8_in.pass.cpp360
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf8_length.pass.cpp244
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf8_max_length.pass.cpp63
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf8_out.pass.cpp456
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf8_unshift.pass.cpp56
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_always_noconv.pass.cpp45
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_encoding.pass.cpp45
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_in.pass.cpp372
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_length.pass.cpp235
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_max_length.pass.cpp63
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_out.pass.cpp415
-rw-r--r--libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_unshift.pass.cpp56
-rw-r--r--libcxx/test/localization/locale.stdcvt/version.pass.cpp20
27 files changed, 4412 insertions, 13 deletions
diff --git a/libcxx/test/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/utf_sanity_check.pass.cpp b/libcxx/test/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/utf_sanity_check.pass.cpp
index 33fd85b0263..3e98cf555a2 100644
--- a/libcxx/test/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/utf_sanity_check.pass.cpp
+++ b/libcxx/test/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/utf_sanity_check.pass.cpp
@@ -16,6 +16,7 @@
// sanity check
#include <locale>
+#include <codecvt>
#include <cassert>
#include <stdio.h>
@@ -24,11 +25,11 @@ int main()
{
typedef std::codecvt<char32_t, char, std::mbstate_t> F32_8;
typedef std::codecvt<char16_t, char, std::mbstate_t> F16_8;
- typedef std::codecvt<char32_t, char16_t, std::mbstate_t> F32_16;
+ typedef std::codecvt_utf16<char32_t> F32_16;
std::locale l = std::locale(std::locale::classic(), new F32_16);
- const F32_8& f32_8 = std::use_facet<F32_8>(l);
+ const F32_8& f32_8 = std::use_facet<F32_8>(std::locale::classic());
const F32_16& f32_16 = std::use_facet<F32_16>(l);
- const F16_8& f16_8 = std::use_facet<F16_8>(l);
+ const F16_8& f16_8 = std::use_facet<F16_8>(std::locale::classic());
std::mbstate_t mbs = {0};
F32_8::intern_type* c32p;
F16_8::intern_type* c16p;
@@ -38,23 +39,27 @@ int main()
const F32_8::extern_type* c_c8p;
F32_8::intern_type c32;
F16_8::intern_type c16[2];
+ char c16c[4];
+ char* c16cp;
F32_8::extern_type c8[4];
for (F32_8::intern_type c32x = 0; c32x < 0x110003; ++c32x)
{
if (0xD800 <= c32x && c32x < 0xE000 || c32x >= 0x110000)
{
- assert(f32_16.out(mbs, &c32x, &c32x+1, c_c32p, c16+0, c16+2, c16p) == F32_8::error);
+ assert(f32_16.out(mbs, &c32x, &c32x+1, c_c32p, c16c+0, c16c+4, c16cp) == F32_8::error);
assert(f32_8.out(mbs, &c32x, &c32x+1, c_c32p, c8, c8+4, c8p) == F32_8::error);
}
else
{
- assert(f32_16.out(mbs, &c32x, &c32x+1, c_c32p, c16, c16+2, c16p) == F32_8::ok);
+ assert(f32_16.out(mbs, &c32x, &c32x+1, c_c32p, c16c, c16c+4, c16cp) == F32_8::ok);
assert(c_c32p-&c32x == 1);
if (c32x < 0x10000)
- assert(c16p-c16 == 1);
+ assert(c16cp-c16c == 2);
else
- assert(c16p-c16 == 2);
- c_c16p = c16p;
+ assert(c16cp-c16c == 4);
+ for (int i = 0; i < (c16cp - c16c) / 2; ++i)
+ c16[i] = (unsigned char)c16c[2*i] << 8 | (unsigned char)c16c[2*i+1];
+ c_c16p = c16 + (c16cp - c16c) / 2;
assert(f16_8.out(mbs, c16, c_c16p, c_c16p, c8, c8+4, c8p) == F32_8::ok);
if (c32x < 0x10000)
assert(c_c16p-c16 == 1);
@@ -104,12 +109,17 @@ int main()
assert(c16p-c16 == 1);
else
assert(c16p-c16 == 2);
- c_c16p = c16p;
- assert(f32_16.in(mbs, c16, c_c16p, c_c16p, &c32, &c32+1, c32p) == F32_8::ok);
+ for (int i = 0; i < c16p-c16; ++i)
+ {
+ c16c[2*i] = static_cast<char>(c16[i] >> 8);
+ c16c[2*i+1] = static_cast<char>(c16[i]);
+ }
+ const char* c_c16cp = c16c + (c16p-c16)*2;
+ assert(f32_16.in(mbs, c16c, c_c16cp, c_c16cp, &c32, &c32+1, c32p) == F32_8::ok);
if (c32x < 0x10000)
- assert(c_c16p-c16 == 1);
+ assert(c_c16cp-c16c == 2);
else
- assert(c_c16p-c16 == 2);
+ assert(c_c16cp-c16c == 4);
assert(c32p-&c32 == 1);
assert(c32 == c32x);
}
diff --git a/libcxx/test/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp b/libcxx/test/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp
index 8aa99b00709..101bceb2c79 100644
--- a/libcxx/test/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp
+++ b/libcxx/test/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp
@@ -33,7 +33,7 @@ int main()
const my_facet f(1);
char str[200];
output_iterator<char*> iter;
- tm t;
+ tm t = {0};
t.tm_sec = 6;
t.tm_min = 3;
t.tm_hour = 13;
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_mode.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_mode.pass.cpp
new file mode 100644
index 00000000000..92043a8a005
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_mode.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// enum codecvt_mode
+// {
+// consume_header = 4,
+// generate_header = 2,
+// little_endian = 1
+// };
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ assert(std::consume_header == 4);
+ assert(std::generate_header == 2);
+ assert(std::little_endian == 1);
+ std::codecvt_mode e = std::consume_header;
+ assert(e == 4);
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf16.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf16.pass.cpp
new file mode 100644
index 00000000000..25998952989
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf16.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf16
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// Not a portable test
+
+#include <codecvt>
+#include <cassert>
+
+int outstanding_news = 0;
+
+void* operator new(std::size_t s) throw(std::bad_alloc)
+{
+ ++outstanding_news;
+ return std::malloc(s);
+}
+
+void operator delete(void* p) throw()
+{
+ if (p)
+ {
+ --outstanding_news;
+ std::free(p);
+ }
+}
+
+int main()
+{
+ assert(outstanding_news == 0);
+ {
+ typedef std::codecvt_utf16<wchar_t> C;
+ C c;
+ assert(outstanding_news == 0);
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t> C;
+ std::locale loc(std::locale::classic(), new C);
+ assert(outstanding_news != 0);
+ }
+ assert(outstanding_news == 0);
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf16_always_noconv.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf16_always_noconv.pass.cpp
new file mode 100644
index 00000000000..8d9c197e9df
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf16_always_noconv.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf16
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// bool always_noconv() const throw();
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf16<wchar_t> C;
+ C c;
+ bool r = c.always_noconv();
+ assert(r == false);
+ }
+ {
+ typedef std::codecvt_utf16<char16_t> C;
+ C c;
+ bool r = c.always_noconv();
+ assert(r == false);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t> C;
+ C c;
+ bool r = c.always_noconv();
+ assert(r == false);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf16_encoding.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf16_encoding.pass.cpp
new file mode 100644
index 00000000000..a95f78fe172
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf16_encoding.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf16
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// int encoding() const throw();
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf16<wchar_t> C;
+ C c;
+ int r = c.encoding();
+ assert(r == 0);
+ }
+ {
+ typedef std::codecvt_utf16<char16_t> C;
+ C c;
+ int r = c.encoding();
+ assert(r == 0);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t> C;
+ C c;
+ int r = c.encoding();
+ assert(r == 0);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf16_in.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf16_in.pass.cpp
new file mode 100644
index 00000000000..0572b80e6f6
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf16_in.pass.cpp
@@ -0,0 +1,739 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf16
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// result
+// in(stateT& state,
+// const externT* from, const externT* from_end, const externT*& from_next,
+// internT* to, internT* to_end, internT*& to_next) const;
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf16<wchar_t> C;
+ C c;
+ wchar_t w = 0;
+ char n[4] = {0xD8, 0xC0, 0xDC, 0x03};
+ wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(w == 0x40003);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x1005);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t, 0x1000> C;
+ C c;
+ wchar_t w = 0;
+ char n[4] = {0xD8, 0xC0, 0xDC, 0x03};
+ wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header> C;
+ C c;
+ wchar_t w = 0;
+ char n[6] = {0xFE, 0xFF, 0xD8, 0xC0, 0xDC, 0x03};
+ wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+6, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+6);
+ assert(w == 0x40003);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x1005);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian> C;
+ C c;
+ wchar_t w = 0;
+ char n[4] = {0xC0, 0xD8, 0x03, 0xDC};
+ wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(w == 0x40003);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x1005);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t, 0x1000, std::little_endian> C;
+ C c;
+ wchar_t w = 0;
+ char n[4] = {0xC0, 0xD8, 0x03, 0xDC};
+ wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t, 0x10ffff, std::codecvt_mode(
+ std::consume_header |
+ std::little_endian)> C;
+ C c;
+ wchar_t w = 0;
+ char n[6] = {0xFF, 0xFE, 0xC0, 0xD8, 0x03, 0xDC};
+ wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+6, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+6);
+ assert(w == 0x40003);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x1005);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t> C;
+ C c;
+ char32_t w = 0;
+ char n[4] = {0xD8, 0xC0, 0xDC, 0x03};
+ char32_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(w == 0x40003);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x1005);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t, 0x1000> C;
+ C c;
+ char32_t w = 0;
+ char n[4] = {0xD8, 0xC0, 0xDC, 0x03};
+ char32_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t, 0x10ffff, std::consume_header> C;
+ C c;
+ char32_t w = 0;
+ char n[6] = {0xFE, 0xFF, 0xD8, 0xC0, 0xDC, 0x03};
+ char32_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+6, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+6);
+ assert(w == 0x40003);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x1005);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t, 0x10ffff, std::little_endian> C;
+ C c;
+ char32_t w = 0;
+ char n[4] = {0xC0, 0xD8, 0x03, 0xDC};
+ char32_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(w == 0x40003);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x1005);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t, 0x1000, std::little_endian> C;
+ C c;
+ char32_t w = 0;
+ char n[4] = {0xC0, 0xD8, 0x03, 0xDC};
+ char32_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t, 0x10ffff, std::codecvt_mode(
+ std::consume_header |
+ std::little_endian)> C;
+ C c;
+ char32_t w = 0;
+ char n[6] = {0xFF, 0xFE, 0xC0, 0xD8, 0x03, 0xDC};
+ char32_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+6, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+6);
+ assert(w == 0x40003);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x1005);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+
+ {
+ typedef std::codecvt_utf16<char16_t> C;
+ C c;
+ char16_t w = 0;
+ char n[4] = {0xD8, 0xC0, 0xDC, 0x03};
+ char16_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x1005);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<char16_t, 0x1000> C;
+ C c;
+ char16_t w = 0;
+ char n[4] = {0xD8, 0xC0, 0xDC, 0x03};
+ char16_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<char16_t, 0x10ffff, std::consume_header> C;
+ C c;
+ char16_t w = 0;
+ char n[6] = {0xFE, 0xFF, 0xD8, 0xC0, 0xDC, 0x03};
+ char16_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+6, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n+2);
+ assert(w == 0);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x1005);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<char16_t, 0x10ffff, std::little_endian> C;
+ C c;
+ char16_t w = 0;
+ char n[4] = {0xC0, 0xD8, 0x03, 0xDC};
+ char16_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x1005);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<char16_t, 0x1000, std::little_endian> C;
+ C c;
+ char16_t w = 0;
+ char n[4] = {0xC0, 0xD8, 0x03, 0xDC};
+ char16_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf16<char16_t, 0x10ffff, std::codecvt_mode(
+ std::consume_header |
+ std::little_endian)> C;
+ C c;
+ char16_t w = 0;
+ char n[6] = {0xFF, 0xFE, 0xC0, 0xD8, 0x03, 0xDC};
+ char16_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+6, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n+2);
+ assert(w == 0);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x1005);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x56);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf16_length.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf16_length.pass.cpp
new file mode 100644
index 00000000000..0154ec717ea
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf16_length.pass.cpp
@@ -0,0 +1,449 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf16
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// int length(stateT& state, const externT* from, const externT* from_end,
+// size_t max) const;
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf16<wchar_t> C;
+ C c;
+ char n[4] = {0xD8, 0xC0, 0xDC, 0x03};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 4);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t, 0x1000> C;
+ C c;
+ char n[4] = {0xD8, 0xC0, 0xDC, 0x03};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 0);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 0);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header> C;
+ C c;
+ char n[6] = {0xFE, 0xFF, 0xD8, 0xC0, 0xDC, 0x03};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+6, 2);
+ assert(r == 6);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian> C;
+ C c;
+ char n[4] = {0xC0, 0xD8, 0x03, 0xDC};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 4);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t, 0x1000, std::little_endian> C;
+ C c;
+ char n[4] = {0xC0, 0xD8, 0x03, 0xDC};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 0);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 0);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t, 0x10ffff, std::codecvt_mode(
+ std::consume_header |
+ std::little_endian)> C;
+ C c;
+ char n[6] = {0xFF, 0xFE, 0xC0, 0xD8, 0x03, 0xDC};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+6, 2);
+ assert(r == 6);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t> C;
+ C c;
+ char n[4] = {0xD8, 0xC0, 0xDC, 0x03};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 4);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t, 0x1000> C;
+ C c;
+ char n[4] = {0xD8, 0xC0, 0xDC, 0x03};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 0);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 0);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t, 0x10ffff, std::consume_header> C;
+ C c;
+ char n[6] = {0xFE, 0xFF, 0xD8, 0xC0, 0xDC, 0x03};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+6, 2);
+ assert(r == 6);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t, 0x10ffff, std::little_endian> C;
+ C c;
+ char n[4] = {0xC0, 0xD8, 0x03, 0xDC};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 4);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t, 0x1000, std::little_endian> C;
+ C c;
+ char n[4] = {0xC0, 0xD8, 0x03, 0xDC};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 0);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 0);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t, 0x10ffff, std::codecvt_mode(
+ std::consume_header |
+ std::little_endian)> C;
+ C c;
+ char n[6] = {0xFF, 0xFE, 0xC0, 0xD8, 0x03, 0xDC};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+6, 2);
+ assert(r == 6);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+
+ {
+ typedef std::codecvt_utf16<char16_t> C;
+ C c;
+ char n[4] = {0xD8, 0xC0, 0xDC, 0x03};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 0);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<char16_t, 0x1000> C;
+ C c;
+ char n[4] = {0xD8, 0xC0, 0xDC, 0x03};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 0);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 0);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<char16_t, 0x10ffff, std::consume_header> C;
+ C c;
+ char n[6] = {0xFE, 0xFF, 0xD8, 0xC0, 0xDC, 0x03};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+6, 2);
+ assert(r == 2);
+
+ n[0] = char(0x10);
+ n[1] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x04);
+ n[1] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x00);
+ n[1] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<char16_t, 0x10ffff, std::little_endian> C;
+ C c;
+ char n[4] = {0xC0, 0xD8, 0x03, 0xDC};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 0);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<char16_t, 0x1000, std::little_endian> C;
+ C c;
+ char n[4] = {0xC0, 0xD8, 0x03, 0xDC};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 0);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 0);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<char16_t, 0x10ffff, std::codecvt_mode(
+ std::consume_header |
+ std::little_endian)> C;
+ C c;
+ char n[6] = {0xFF, 0xFE, 0xC0, 0xD8, 0x03, 0xDC};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+6, 2);
+ assert(r == 2);
+
+ n[1] = char(0x10);
+ n[0] = char(0x05);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[1] = char(0x04);
+ n[0] = char(0x53);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[1] = char(0x00);
+ n[0] = char(0x56);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf16_max_length.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf16_max_length.pass.cpp
new file mode 100644
index 00000000000..35fccc70b38
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf16_max_length.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf16
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// int max_length() const throw();
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf16<wchar_t> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 4);
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t, 0xFFFFFFFF, std::consume_header> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 6);
+ }
+ {
+ typedef std::codecvt_utf16<char16_t> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 2);
+ }
+ {
+ typedef std::codecvt_utf16<char16_t, 0xFFFFFFFF, std::consume_header> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 4);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 4);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t, 0xFFFFFFFF, std::consume_header> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 6);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf16_out.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf16_out.pass.cpp
new file mode 100644
index 00000000000..e745b5ff4f3
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf16_out.pass.cpp
@@ -0,0 +1,331 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf16
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// result
+// out(stateT& state,
+// const internT* from, const internT* from_end, const internT*& from_next,
+// externT* to, externT* to_end, externT*& to_next) const;
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf16<wchar_t> C;
+ C c;
+ wchar_t w = 0x40003;
+ char n[4] = {0};
+ const wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(n[0] == char(0xD8));
+ assert(n[1] == char(0xC0));
+ assert(n[2] == char(0xDC));
+ assert(n[3] == char(0x03));
+
+ w = 0x1005;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0x10));
+ assert(n[1] == char(0x05));
+ assert(n[2] == char(0xDC));
+ assert(n[3] == char(0x03));
+
+ w = 0x453;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0x04));
+ assert(n[1] == char(0x53));
+ assert(n[2] == char(0xDC));
+ assert(n[3] == char(0x03));
+
+ w = 0x56;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0x00));
+ assert(n[1] == char(0x56));
+ assert(n[2] == char(0xDC));
+ assert(n[3] == char(0x03));
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t, 0x1000> C;
+ C c;
+ wchar_t w = 0x40003;
+ char n[4] = {0};
+ const wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(n[0] == char(0));
+ assert(n[1] == char(0));
+ assert(n[2] == char(0));
+ assert(n[3] == char(0));
+
+ w = 0x1005;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(n[0] == char(0));
+ assert(n[1] == char(0));
+ assert(n[2] == char(0));
+ assert(n[3] == char(0));
+
+ w = 0x453;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0x04));
+ assert(n[1] == char(0x53));
+ assert(n[2] == char(0));
+ assert(n[3] == char(0));
+
+ w = 0x56;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0x00));
+ assert(n[1] == char(0x56));
+ assert(n[2] == char(0));
+ assert(n[3] == char(0));
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t, 0x10ffff, std::generate_header> C;
+ C c;
+ wchar_t w = 0x40003;
+ char n[6] = {0};
+ const wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, &w, &w+1, wp, n, n+6, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+6);
+ assert(n[0] == char(0xFE));
+ assert(n[1] == char(0xFF));
+ assert(n[2] == char(0xD8));
+ assert(n[3] == char(0xC0));
+ assert(n[4] == char(0xDC));
+ assert(n[5] == char(0x03));
+
+ w = 0x1005;
+ r = c.out(m, &w, &w+1, wp, n, n+6, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(n[0] == char(0xFE));
+ assert(n[1] == char(0xFF));
+ assert(n[2] == char(0x10));
+ assert(n[3] == char(0x05));
+ assert(n[4] == char(0xDC));
+ assert(n[5] == char(0x03));
+
+ w = 0x453;
+ r = c.out(m, &w, &w+1, wp, n, n+6, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(n[0] == char(0xFE));
+ assert(n[1] == char(0xFF));
+ assert(n[2] == char(0x04));
+ assert(n[3] == char(0x53));
+ assert(n[4] == char(0xDC));
+ assert(n[5] == char(0x03));
+
+ w = 0x56;
+ r = c.out(m, &w, &w+1, wp, n, n+6, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(n[0] == char(0xFE));
+ assert(n[1] == char(0xFF));
+ assert(n[2] == char(0x00));
+ assert(n[3] == char(0x56));
+ assert(n[4] == char(0xDC));
+ assert(n[5] == char(0x03));
+ }
+
+ {
+ typedef std::codecvt_utf16<wchar_t, 0x10FFFF, std::little_endian> C;
+ C c;
+ wchar_t w = 0x40003;
+ char n[4] = {0};
+ const wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(n[1] == char(0xD8));
+ assert(n[0] == char(0xC0));
+ assert(n[3] == char(0xDC));
+ assert(n[2] == char(0x03));
+
+ w = 0x1005;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[1] == char(0x10));
+ assert(n[0] == char(0x05));
+ assert(n[3] == char(0xDC));
+ assert(n[2] == char(0x03));
+
+ w = 0x453;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[1] == char(0x04));
+ assert(n[0] == char(0x53));
+ assert(n[3] == char(0xDC));
+ assert(n[2] == char(0x03));
+
+ w = 0x56;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[1] == char(0x00));
+ assert(n[0] == char(0x56));
+ assert(n[3] == char(0xDC));
+ assert(n[2] == char(0x03));
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t, 0x1000, std::little_endian> C;
+ C c;
+ wchar_t w = 0x40003;
+ char n[4] = {0};
+ const wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(n[1] == char(0));
+ assert(n[0] == char(0));
+ assert(n[3] == char(0));
+ assert(n[2] == char(0));
+
+ w = 0x1005;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(n[1] == char(0));
+ assert(n[0] == char(0));
+ assert(n[3] == char(0));
+ assert(n[2] == char(0));
+
+ w = 0x453;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[1] == char(0x04));
+ assert(n[0] == char(0x53));
+ assert(n[3] == char(0));
+ assert(n[2] == char(0));
+
+ w = 0x56;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[1] == char(0x00));
+ assert(n[0] == char(0x56));
+ assert(n[3] == char(0));
+ assert(n[2] == char(0));
+ }
+ {
+ typedef std::codecvt_utf16<wchar_t, 0x10ffff, std::codecvt_mode(
+ std::generate_header |
+ std::little_endian)> C;
+ C c;
+ wchar_t w = 0x40003;
+ char n[6] = {0};
+ const wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, &w, &w+1, wp, n, n+6, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+6);
+ assert(n[1] == char(0xFE));
+ assert(n[0] == char(0xFF));
+ assert(n[3] == char(0xD8));
+ assert(n[2] == char(0xC0));
+ assert(n[5] == char(0xDC));
+ assert(n[4] == char(0x03));
+
+ w = 0x1005;
+ r = c.out(m, &w, &w+1, wp, n, n+6, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(n[1] == char(0xFE));
+ assert(n[0] == char(0xFF));
+ assert(n[3] == char(0x10));
+ assert(n[2] == char(0x05));
+ assert(n[5] == char(0xDC));
+ assert(n[4] == char(0x03));
+
+ w = 0x453;
+ r = c.out(m, &w, &w+1, wp, n, n+6, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(n[1] == char(0xFE));
+ assert(n[0] == char(0xFF));
+ assert(n[3] == char(0x04));
+ assert(n[2] == char(0x53));
+ assert(n[5] == char(0xDC));
+ assert(n[4] == char(0x03));
+
+ w = 0x56;
+ r = c.out(m, &w, &w+1, wp, n, n+6, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(n[1] == char(0xFE));
+ assert(n[0] == char(0xFF));
+ assert(n[3] == char(0x00));
+ assert(n[2] == char(0x56));
+ assert(n[5] == char(0xDC));
+ assert(n[4] == char(0x03));
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf16_unshift.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf16_unshift.pass.cpp
new file mode 100644
index 00000000000..61ab4648394
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf16_unshift.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf16
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// result
+// unshift(stateT& state,
+// externT* to, externT* to_end, externT*& to_next) const;
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf16<wchar_t> C;
+ C c;
+ char n[4] = {0};
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.unshift(m, n, n+4, np);
+ assert(r == std::codecvt_base::noconv);
+ }
+ {
+ typedef std::codecvt_utf16<char16_t> C;
+ C c;
+ char n[4] = {0};
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.unshift(m, n, n+4, np);
+ assert(r == std::codecvt_base::noconv);
+ }
+ {
+ typedef std::codecvt_utf16<char32_t> C;
+ C c;
+ char n[4] = {0};
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.unshift(m, n, n+4, np);
+ assert(r == std::codecvt_base::noconv);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf8.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf8.pass.cpp
new file mode 100644
index 00000000000..d4f960aa556
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf8.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf8
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// Not a portable test
+
+#include <codecvt>
+#include <cassert>
+
+int outstanding_news = 0;
+
+void* operator new(std::size_t s) throw(std::bad_alloc)
+{
+ ++outstanding_news;
+ return std::malloc(s);
+}
+
+void operator delete(void* p) throw()
+{
+ if (p)
+ {
+ --outstanding_news;
+ std::free(p);
+ }
+}
+
+int main()
+{
+ assert(outstanding_news == 0);
+ {
+ typedef std::codecvt_utf8<wchar_t> C;
+ C c;
+ assert(outstanding_news == 0);
+ }
+ {
+ typedef std::codecvt_utf8<wchar_t> C;
+ std::locale loc(std::locale::classic(), new C);
+ assert(outstanding_news != 0);
+ }
+ assert(outstanding_news == 0);
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf8_always_noconv.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_always_noconv.pass.cpp
new file mode 100644
index 00000000000..94d2e8f3e49
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_always_noconv.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf8
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// bool always_noconv() const throw();
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf8<wchar_t> C;
+ C c;
+ bool r = c.always_noconv();
+ assert(r == false);
+ }
+ {
+ typedef std::codecvt_utf8<char16_t> C;
+ C c;
+ bool r = c.always_noconv();
+ assert(r == false);
+ }
+ {
+ typedef std::codecvt_utf8<char32_t> C;
+ C c;
+ bool r = c.always_noconv();
+ assert(r == false);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf8_encoding.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_encoding.pass.cpp
new file mode 100644
index 00000000000..5ee22e3d01a
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_encoding.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf8
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// int encoding() const throw();
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf8<wchar_t> C;
+ C c;
+ int r = c.encoding();
+ assert(r == 0);
+ }
+ {
+ typedef std::codecvt_utf8<char16_t> C;
+ C c;
+ int r = c.encoding();
+ assert(r == 0);
+ }
+ {
+ typedef std::codecvt_utf8<char32_t> C;
+ C c;
+ int r = c.encoding();
+ assert(r == 0);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf8_in.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_in.pass.cpp
new file mode 100644
index 00000000000..8dd453ac81c
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_in.pass.cpp
@@ -0,0 +1,360 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf8
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// result
+// in(stateT& state,
+// const externT* from, const externT* from_end, const externT*& from_next,
+// internT* to, internT* to_end, internT*& to_next) const;
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf8<wchar_t> C;
+ C c;
+ wchar_t w = 0;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(w == 0x40003);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.in(m, n, n+3, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+3);
+ assert(w == 0x1005);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+1);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf8<wchar_t, 0x1000> C;
+ C c;
+ wchar_t w = 0;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.in(m, n, n+3, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+1);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf8<wchar_t, 0xFFFFFFFF, std::consume_header> C;
+ C c;
+ wchar_t w = 0;
+ char n[7] = {0xEF, 0xBB, 0xBF, 0xF1, 0x80, 0x80, 0x83};
+ wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+7, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+7);
+ assert(w == 0x40003);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.in(m, n, n+3, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+3);
+ assert(w == 0x1005);
+
+ n[0] = char(0xEF);
+ n[1] = char(0xBB);
+ n[2] = char(0xBF);
+ n[3] = char(0xD1);
+ n[4] = char(0x93);
+ r = c.in(m, n, n+5, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+5);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+1);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf8<char32_t> C;
+ C c;
+ char32_t w = 0;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ char32_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(w == 0x40003);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.in(m, n, n+3, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+3);
+ assert(w == 0x1005);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+1);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf8<char32_t, 0x1000> C;
+ C c;
+ char32_t w = 0;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ char32_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.in(m, n, n+3, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+1);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf8<char32_t, 0xFFFFFFFF, std::consume_header> C;
+ C c;
+ char32_t w = 0;
+ char n[7] = {0xEF, 0xBB, 0xBF, 0xF1, 0x80, 0x80, 0x83};
+ char32_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+7, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+7);
+ assert(w == 0x40003);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.in(m, n, n+3, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+3);
+ assert(w == 0x1005);
+
+ n[0] = char(0xEF);
+ n[1] = char(0xBB);
+ n[2] = char(0xBF);
+ n[3] = char(0xD1);
+ n[4] = char(0x93);
+ r = c.in(m, n, n+5, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+5);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+1);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf8<char16_t> C;
+ C c;
+ char16_t w = 0;
+ char n[3] = {0xE1, 0x80, 0x85};
+ char16_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+3, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+3);
+ assert(w == 0x1005);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+1);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf8<char16_t, 0x1000> C;
+ C c;
+ char16_t w = 0;
+ char n[3] = {0xE1, 0x80, 0x85};
+ char16_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+3, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(w == 0);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+1);
+ assert(w == 0x56);
+ }
+ {
+ typedef std::codecvt_utf8<char16_t, 0xFFFFFFFF, std::consume_header> C;
+ C c;
+ char16_t w = 0;
+ char n[6] = {0xEF, 0xBB, 0xBF, 0xE1, 0x80, 0x85};
+ char16_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+6, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+6);
+ assert(w == 0x1005);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(w == 0x453);
+
+ w = 0x56;
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, &w, &w+1, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+1);
+ assert(w == 0x56);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf8_length.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_length.pass.cpp
new file mode 100644
index 00000000000..f06caed24af
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_length.pass.cpp
@@ -0,0 +1,244 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf8
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// int length(stateT& state, const externT* from, const externT* from_end,
+// size_t max) const;
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf8<wchar_t> C;
+ C c;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 1);
+ assert(r == 4);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 3);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.length(m, n, n+2, 3);
+ assert(r == 2);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 3);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8<wchar_t, 0x1000> C;
+ C c;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 1);
+ assert(r == 0);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 0);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.length(m, n, n+2, 3);
+ assert(r == 2);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 3);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8<wchar_t, 0xFFFFFFFF, std::consume_header> C;
+ C c;
+ char n[7] = {0xEF, 0xBB, 0xBF, 0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+7, 1);
+ assert(r == 7);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 3);
+
+ n[0] = char(0xEF);
+ n[1] = char(0xBB);
+ n[2] = char(0xBF);
+ n[3] = char(0xD1);
+ n[4] = char(0x93);
+ r = c.length(m, n, n+5, 3);
+ assert(r == 5);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 3);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8<char32_t> C;
+ C c;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 1);
+ assert(r == 4);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 3);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.length(m, n, n+2, 3);
+ assert(r == 2);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 3);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8<char32_t, 0x1000> C;
+ C c;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 1);
+ assert(r == 0);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 0);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.length(m, n, n+2, 3);
+ assert(r == 2);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 3);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8<char32_t, 0xFFFFFFFF, std::consume_header> C;
+ C c;
+ char n[7] = {0xEF, 0xBB, 0xBF, 0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+7, 1);
+ assert(r == 7);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 3);
+
+ n[0] = char(0xEF);
+ n[1] = char(0xBB);
+ n[2] = char(0xBF);
+ n[3] = char(0xD1);
+ n[4] = char(0x93);
+ r = c.length(m, n, n+5, 3);
+ assert(r == 5);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 3);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8<char16_t> C;
+ C c;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 1);
+ assert(r == 0);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 3);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.length(m, n, n+2, 3);
+ assert(r == 2);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 3);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8<char16_t, 0x1000> C;
+ C c;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 1);
+ assert(r == 0);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 0);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.length(m, n, n+2, 3);
+ assert(r == 2);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 3);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8<char16_t, 0xFFFFFFFF, std::consume_header> C;
+ C c;
+ char n[7] = {0xEF, 0xBB, 0xBF, 0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+7, 1);
+ assert(r == 3);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 3);
+
+ n[0] = char(0xEF);
+ n[1] = char(0xBB);
+ n[2] = char(0xBF);
+ n[3] = char(0xD1);
+ n[4] = char(0x93);
+ r = c.length(m, n, n+5, 3);
+ assert(r == 5);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 3);
+ assert(r == 1);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf8_max_length.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_max_length.pass.cpp
new file mode 100644
index 00000000000..a7a47d083b1
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_max_length.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf8
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// int max_length() const throw();
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf8<wchar_t> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 4);
+ }
+ {
+ typedef std::codecvt_utf8<wchar_t, 0xFFFFFFFF, std::consume_header> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 7);
+ }
+ {
+ typedef std::codecvt_utf8<char16_t> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 3);
+ }
+ {
+ typedef std::codecvt_utf8<char16_t, 0xFFFFFFFF, std::consume_header> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 6);
+ }
+ {
+ typedef std::codecvt_utf8<char32_t> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 4);
+ }
+ {
+ typedef std::codecvt_utf8<char32_t, 0xFFFFFFFF, std::consume_header> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 7);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf8_out.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_out.pass.cpp
new file mode 100644
index 00000000000..5ed05747da8
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_out.pass.cpp
@@ -0,0 +1,456 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf8
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// result
+// out(stateT& state,
+// const internT* from, const internT* from_end, const internT*& from_next,
+// externT* to, externT* to_end, externT*& to_next) const;
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf8<wchar_t> C;
+ C c;
+ wchar_t w = 0x40003;
+ char n[4] = {0};
+ const wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(n[0] == char(0xF1));
+ assert(n[1] == char(0x80));
+ assert(n[2] == char(0x80));
+ assert(n[3] == char(0x83));
+
+ w = 0x1005;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+3);
+ assert(n[0] == char(0xE1));
+ assert(n[1] == char(0x80));
+ assert(n[2] == char(0x85));
+ assert(n[3] == char(0x83));
+
+ w = 0x453;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0xD1));
+ assert(n[1] == char(0x93));
+ assert(n[2] == char(0x85));
+ assert(n[3] == char(0x83));
+
+ w = 0x56;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+1);
+ assert(n[0] == char(0x56));
+ assert(n[1] == char(0x93));
+ assert(n[2] == char(0x85));
+ assert(n[3] == char(0x83));
+ }
+ {
+ typedef std::codecvt_utf8<wchar_t, 0x1000> C;
+ C c;
+ wchar_t w = 0x40003;
+ char n[4] = {0};
+ const wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(n[0] == char(0));
+ assert(n[1] == char(0));
+ assert(n[2] == char(0));
+ assert(n[3] == char(0));
+
+ w = 0x1005;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(n[0] == char(0));
+ assert(n[1] == char(0));
+ assert(n[2] == char(0));
+ assert(n[3] == char(0));
+
+ w = 0x453;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0xD1));
+ assert(n[1] == char(0x93));
+ assert(n[2] == char(0));
+ assert(n[3] == char(0));
+
+ w = 0x56;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+1);
+ assert(n[0] == char(0x56));
+ assert(n[1] == char(0x93));
+ assert(n[2] == char(0));
+ assert(n[3] == char(0));
+ }
+ {
+ typedef std::codecvt_utf8<wchar_t, 0xFFFFFFFF, std::generate_header> C;
+ C c;
+ wchar_t w = 0x40003;
+ char n[7] = {0};
+ const wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, &w, &w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+7);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xF1));
+ assert(n[4] == char(0x80));
+ assert(n[5] == char(0x80));
+ assert(n[6] == char(0x83));
+
+ w = 0x1005;
+ r = c.out(m, &w, &w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+6);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xE1));
+ assert(n[4] == char(0x80));
+ assert(n[5] == char(0x85));
+ assert(n[6] == char(0x83));
+
+ w = 0x453;
+ r = c.out(m, &w, &w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+5);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xD1));
+ assert(n[4] == char(0x93));
+ assert(n[5] == char(0x85));
+ assert(n[6] == char(0x83));
+
+ w = 0x56;
+ r = c.out(m, &w, &w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0x56));
+ assert(n[4] == char(0x93));
+ assert(n[5] == char(0x85));
+ assert(n[6] == char(0x83));
+ }
+ {
+ typedef std::codecvt_utf8<char32_t> C;
+ C c;
+ char32_t w = 0x40003;
+ char n[4] = {0};
+ const char32_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(n[0] == char(0xF1));
+ assert(n[1] == char(0x80));
+ assert(n[2] == char(0x80));
+ assert(n[3] == char(0x83));
+
+ w = 0x1005;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+3);
+ assert(n[0] == char(0xE1));
+ assert(n[1] == char(0x80));
+ assert(n[2] == char(0x85));
+ assert(n[3] == char(0x83));
+
+ w = 0x453;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0xD1));
+ assert(n[1] == char(0x93));
+ assert(n[2] == char(0x85));
+ assert(n[3] == char(0x83));
+
+ w = 0x56;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+1);
+ assert(n[0] == char(0x56));
+ assert(n[1] == char(0x93));
+ assert(n[2] == char(0x85));
+ assert(n[3] == char(0x83));
+ }
+ {
+ typedef std::codecvt_utf8<char32_t, 0x1000> C;
+ C c;
+ char32_t w = 0x40003;
+ char n[4] = {0};
+ const char32_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(n[0] == char(0));
+ assert(n[1] == char(0));
+ assert(n[2] == char(0));
+ assert(n[3] == char(0));
+
+ w = 0x1005;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(n[0] == char(0));
+ assert(n[1] == char(0));
+ assert(n[2] == char(0));
+ assert(n[3] == char(0));
+
+ w = 0x453;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0xD1));
+ assert(n[1] == char(0x93));
+ assert(n[2] == char(0));
+ assert(n[3] == char(0));
+
+ w = 0x56;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+1);
+ assert(n[0] == char(0x56));
+ assert(n[1] == char(0x93));
+ assert(n[2] == char(0));
+ assert(n[3] == char(0));
+ }
+ {
+ typedef std::codecvt_utf8<char32_t, 0xFFFFFFFF, std::generate_header> C;
+ C c;
+ char32_t w = 0x40003;
+ char n[7] = {0};
+ const char32_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, &w, &w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+7);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xF1));
+ assert(n[4] == char(0x80));
+ assert(n[5] == char(0x80));
+ assert(n[6] == char(0x83));
+
+ w = 0x1005;
+ r = c.out(m, &w, &w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+6);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xE1));
+ assert(n[4] == char(0x80));
+ assert(n[5] == char(0x85));
+ assert(n[6] == char(0x83));
+
+ w = 0x453;
+ r = c.out(m, &w, &w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+5);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xD1));
+ assert(n[4] == char(0x93));
+ assert(n[5] == char(0x85));
+ assert(n[6] == char(0x83));
+
+ w = 0x56;
+ r = c.out(m, &w, &w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0x56));
+ assert(n[4] == char(0x93));
+ assert(n[5] == char(0x85));
+ assert(n[6] == char(0x83));
+ }
+ {
+ typedef std::codecvt_utf8<char16_t> C;
+ C c;
+ char16_t w = 0x1005;
+ char n[4] = {0};
+ const char16_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+3);
+ assert(n[0] == char(0xE1));
+ assert(n[1] == char(0x80));
+ assert(n[2] == char(0x85));
+ assert(n[3] == char(0));
+
+ w = 0x453;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0xD1));
+ assert(n[1] == char(0x93));
+ assert(n[2] == char(0x85));
+ assert(n[3] == char(0));
+
+ w = 0x56;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+1);
+ assert(n[0] == char(0x56));
+ assert(n[1] == char(0x93));
+ assert(n[2] == char(0x85));
+ assert(n[3] == char(0));
+ }
+ {
+ typedef std::codecvt_utf8<char16_t, 0x1000> C;
+ C c;
+ char16_t w = 0x1005;
+ char n[4] = {0};
+ const char16_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::error);
+ assert(wp == &w);
+ assert(np == n);
+ assert(n[0] == char(0));
+ assert(n[1] == char(0));
+ assert(n[2] == char(0));
+ assert(n[3] == char(0));
+
+ w = 0x453;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0xD1));
+ assert(n[1] == char(0x93));
+ assert(n[2] == char(0));
+ assert(n[3] == char(0));
+
+ w = 0x56;
+ r = c.out(m, &w, &w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+1);
+ assert(n[0] == char(0x56));
+ assert(n[1] == char(0x93));
+ assert(n[2] == char(0));
+ assert(n[3] == char(0));
+ }
+ {
+ typedef std::codecvt_utf8<char16_t, 0xFFFFFFFF, std::generate_header> C;
+ C c;
+ char16_t w = 0x1005;
+ char n[7] = {0};
+ const char16_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, &w, &w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+6);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xE1));
+ assert(n[4] == char(0x80));
+ assert(n[5] == char(0x85));
+ assert(n[6] == char(0));
+
+ w = 0x453;
+ r = c.out(m, &w, &w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+5);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xD1));
+ assert(n[4] == char(0x93));
+ assert(n[5] == char(0x85));
+ assert(n[6] == char(0));
+
+ w = 0x56;
+ r = c.out(m, &w, &w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == &w+1);
+ assert(np == n+4);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0x56));
+ assert(n[4] == char(0x93));
+ assert(n[5] == char(0x85));
+ assert(n[6] == char(0));
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf8_unshift.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_unshift.pass.cpp
new file mode 100644
index 00000000000..054c1a71a98
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_unshift.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf8
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// result
+// unshift(stateT& state,
+// externT* to, externT* to_end, externT*& to_next) const;
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf8<wchar_t> C;
+ C c;
+ char n[4] = {0};
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.unshift(m, n, n+4, np);
+ assert(r == std::codecvt_base::noconv);
+ }
+ {
+ typedef std::codecvt_utf8<char16_t> C;
+ C c;
+ char n[4] = {0};
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.unshift(m, n, n+4, np);
+ assert(r == std::codecvt_base::noconv);
+ }
+ {
+ typedef std::codecvt_utf8<char32_t> C;
+ C c;
+ char n[4] = {0};
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.unshift(m, n, n+4, np);
+ assert(r == std::codecvt_base::noconv);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_always_noconv.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_always_noconv.pass.cpp
new file mode 100644
index 00000000000..dfb9923f0ba
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_always_noconv.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf8_utf16
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// bool always_noconv() const throw();
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf8_utf16<wchar_t> C;
+ C c;
+ bool r = c.always_noconv();
+ assert(r == false);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char16_t> C;
+ C c;
+ bool r = c.always_noconv();
+ assert(r == false);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char32_t> C;
+ C c;
+ bool r = c.always_noconv();
+ assert(r == false);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_encoding.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_encoding.pass.cpp
new file mode 100644
index 00000000000..f16e30e5ee5
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_encoding.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf8_utf16
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// int encoding() const throw();
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf8_utf16<wchar_t> C;
+ C c;
+ int r = c.encoding();
+ assert(r == 0);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char16_t> C;
+ C c;
+ int r = c.encoding();
+ assert(r == 0);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char32_t> C;
+ C c;
+ int r = c.encoding();
+ assert(r == 0);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_in.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_in.pass.cpp
new file mode 100644
index 00000000000..4427ece2e02
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_in.pass.cpp
@@ -0,0 +1,372 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf8_utf16
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// result
+// in(stateT& state,
+// const externT* from, const externT* from_end, const externT*& from_next,
+// internT* to, internT* to_end, internT*& to_next) const;
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf8_utf16<wchar_t> C;
+ C c;
+ wchar_t w[2] = {0};
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+2);
+ assert(np == n+4);
+ assert(w[0] == 0xD8C0);
+ assert(w[1] == 0xDC03);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.in(m, n, n+3, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+3);
+ assert(w[0] == 0x1005);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+2);
+ assert(w[0] == 0x0453);
+
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+1);
+ assert(w[0] == 0x0056);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<wchar_t, 0x1000> C;
+ C c;
+ wchar_t w[2] = {0};
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, w, w+2, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == w);
+ assert(np == n);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.in(m, n, n+3, np, w, w+2, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == w);
+ assert(np == n);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+2);
+ assert(w[0] == 0x0453);
+
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+1);
+ assert(w[0] == 0x0056);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<wchar_t, 0x10ffff, std::consume_header> C;
+ C c;
+ wchar_t w[2] = {0};
+ char n[7] = {0xEF, 0xBB, 0xBF, 0xF1, 0x80, 0x80, 0x83};
+ wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+7, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+2);
+ assert(np == n+7);
+ assert(w[0] == 0xD8C0);
+ assert(w[1] == 0xDC03);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.in(m, n, n+3, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+3);
+ assert(w[0] == 0x1005);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+2);
+ assert(w[0] == 0x0453);
+
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+1);
+ assert(w[0] == 0x0056);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char32_t> C;
+ C c;
+ char32_t w[2] = {0};
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ char32_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+2);
+ assert(np == n+4);
+ assert(w[0] == 0xD8C0);
+ assert(w[1] == 0xDC03);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.in(m, n, n+3, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+3);
+ assert(w[0] == 0x1005);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+2);
+ assert(w[0] == 0x0453);
+
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+1);
+ assert(w[0] == 0x0056);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char32_t, 0x1000> C;
+ C c;
+ char32_t w[2] = {0};
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ char32_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, w, w+2, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == w);
+ assert(np == n);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.in(m, n, n+3, np, w, w+2, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == w);
+ assert(np == n);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+2);
+ assert(w[0] == 0x0453);
+
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+1);
+ assert(w[0] == 0x0056);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char32_t, 0x10ffff, std::consume_header> C;
+ C c;
+ char32_t w[2] = {0};
+ char n[7] = {0xEF, 0xBB, 0xBF, 0xF1, 0x80, 0x80, 0x83};
+ char32_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+7, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+2);
+ assert(np == n+7);
+ assert(w[0] == 0xD8C0);
+ assert(w[1] == 0xDC03);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.in(m, n, n+3, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+3);
+ assert(w[0] == 0x1005);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+2);
+ assert(w[0] == 0x0453);
+
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+1);
+ assert(w[0] == 0x0056);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char16_t> C;
+ C c;
+ char16_t w[2] = {0};
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ char16_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+2);
+ assert(np == n+4);
+ assert(w[0] == 0xD8C0);
+ assert(w[1] == 0xDC03);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.in(m, n, n+3, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+3);
+ assert(w[0] == 0x1005);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+2);
+ assert(w[0] == 0x0453);
+
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+1);
+ assert(w[0] == 0x0056);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char16_t, 0x1000> C;
+ C c;
+ char16_t w[2] = {0};
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ char16_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+4, np, w, w+2, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == w);
+ assert(np == n);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.in(m, n, n+3, np, w, w+2, wp);
+ assert(r == std::codecvt_base::error);
+ assert(wp == w);
+ assert(np == n);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+2);
+ assert(w[0] == 0x0453);
+
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+1);
+ assert(w[0] == 0x0056);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char16_t, 0x10ffff, std::consume_header> C;
+ C c;
+ char16_t w[2] = {0};
+ char n[7] = {0xEF, 0xBB, 0xBF, 0xF1, 0x80, 0x80, 0x83};
+ char16_t* wp = nullptr;
+ std::mbstate_t m;
+ const char* np = nullptr;
+ std::codecvt_base::result r = c.in(m, n, n+7, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+2);
+ assert(np == n+7);
+ assert(w[0] == 0xD8C0);
+ assert(w[1] == 0xDC03);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.in(m, n, n+3, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+3);
+ assert(w[0] == 0x1005);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.in(m, n, n+2, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+2);
+ assert(w[0] == 0x0453);
+
+ n[0] = char(0x56);
+ r = c.in(m, n, n+1, np, w, w+2, wp);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+1);
+ assert(w[0] == 0x0056);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_length.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_length.pass.cpp
new file mode 100644
index 00000000000..2d93657f848
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_length.pass.cpp
@@ -0,0 +1,235 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf8_utf16
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// int length(stateT& state, const externT* from, const externT* from_end,
+// size_t max) const;
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf8_utf16<wchar_t> C;
+ C c;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 4);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 3);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 2);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<wchar_t, 0x1000> C;
+ C c;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 0);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 0);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 2);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<wchar_t, 0x10ffff, std::consume_header> C;
+ C c;
+ char n[7] = {0xEF, 0xBB, 0xBF, 0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+7, 2);
+ assert(r == 7);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 3);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 2);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char32_t> C;
+ C c;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 4);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 3);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 2);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char32_t, 0x1000> C;
+ C c;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 0);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 0);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 2);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char32_t, 0x10ffff, std::consume_header> C;
+ C c;
+ char n[7] = {0xEF, 0xBB, 0xBF, 0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+7, 2);
+ assert(r == 7);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 3);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 2);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char16_t> C;
+ C c;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 4);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 3);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 2);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char16_t, 0x1000> C;
+ C c;
+ char n[4] = {0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+4, 2);
+ assert(r == 0);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 0);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 2);
+ assert(r == 1);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char16_t, 0x10ffff, std::consume_header> C;
+ C c;
+ char n[7] = {0xEF, 0xBB, 0xBF, 0xF1, 0x80, 0x80, 0x83};
+ std::mbstate_t m;
+ int r = c.length(m, n, n+7, 2);
+ assert(r == 7);
+
+ n[0] = char(0xE1);
+ n[1] = char(0x80);
+ n[2] = char(0x85);
+ r = c.length(m, n, n+3, 2);
+ assert(r == 3);
+
+ n[0] = char(0xD1);
+ n[1] = char(0x93);
+ r = c.length(m, n, n+2, 2);
+ assert(r == 2);
+
+ n[0] = char(0x56);
+ r = c.length(m, n, n+1, 2);
+ assert(r == 1);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_max_length.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_max_length.pass.cpp
new file mode 100644
index 00000000000..b869a285787
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_max_length.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf8_utf16
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// int max_length() const throw();
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf8_utf16<wchar_t> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 4);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<wchar_t, 0xFFFFFFFF, std::consume_header> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 7);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char16_t> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 4);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char16_t, 0xFFFFFFFF, std::consume_header> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 7);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char32_t> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 4);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char32_t, 0xFFFFFFFF, std::consume_header> C;
+ C c;
+ int r = c.max_length();
+ assert(r == 7);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_out.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_out.pass.cpp
new file mode 100644
index 00000000000..cb221410ffa
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_out.pass.cpp
@@ -0,0 +1,415 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf8_utf16
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// result
+// out(stateT& state,
+// const internT* from, const internT* from_end, const internT*& from_next,
+// externT* to, externT* to_end, externT*& to_next) const;
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf8_utf16<wchar_t> C;
+ C c;
+ wchar_t w[2] = {0xD8C0, 0xDC03};
+ char n[4] = {0};
+ const wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, w, w+2, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+2);
+ assert(np == n+4);
+ assert(n[0] == char(0xF1));
+ assert(n[1] == char(0x80));
+ assert(n[2] == char(0x80));
+ assert(n[3] == char(0x83));
+
+ w[0] = 0x1005;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+3);
+ assert(n[0] == char(0xE1));
+ assert(n[1] == char(0x80));
+ assert(n[2] == char(0x85));
+
+ w[0] = 0x453;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0xD1));
+ assert(n[1] == char(0x93));
+
+ w[0] = 0x56;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+1);
+ assert(n[0] == char(0x56));
+ }
+ {
+ typedef std::codecvt_utf8_utf16<wchar_t, 0x1000> C;
+ C c;
+ wchar_t w[2] = {0xD8C0, 0xDC03};
+ char n[4] = {0};
+ const wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, w, w+2, wp, n, n+4, np);
+ assert(r == std::codecvt_base::error);
+ assert(wp == w);
+ assert(np == n);
+
+ w[0] = 0x1005;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::error);
+ assert(wp == w);
+ assert(np == n);
+
+ w[0] = 0x453;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0xD1));
+ assert(n[1] == char(0x93));
+
+ w[0] = 0x56;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+1);
+ assert(n[0] == char(0x56));
+ }
+ {
+ typedef std::codecvt_utf8_utf16<wchar_t, 0x10ffff, std::generate_header> C;
+ C c;
+ wchar_t w[2] = {0xD8C0, 0xDC03};
+ char n[7] = {0};
+ const wchar_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, w, w+2, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+2);
+ assert(np == n+7);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xF1));
+ assert(n[4] == char(0x80));
+ assert(n[5] == char(0x80));
+ assert(n[6] == char(0x83));
+
+ w[0] = 0x1005;
+ r = c.out(m, w, w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+6);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xE1));
+ assert(n[4] == char(0x80));
+ assert(n[5] == char(0x85));
+
+ w[0] = 0x453;
+ r = c.out(m, w, w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+5);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xD1));
+ assert(n[4] == char(0x93));
+
+ w[0] = 0x56;
+ r = c.out(m, w, w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+4);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0x56));
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char32_t> C;
+ C c;
+ char32_t w[2] = {0xD8C0, 0xDC03};
+ char n[4] = {0};
+ const char32_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, w, w+2, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+2);
+ assert(np == n+4);
+ assert(n[0] == char(0xF1));
+ assert(n[1] == char(0x80));
+ assert(n[2] == char(0x80));
+ assert(n[3] == char(0x83));
+
+ w[0] = 0x1005;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+3);
+ assert(n[0] == char(0xE1));
+ assert(n[1] == char(0x80));
+ assert(n[2] == char(0x85));
+
+ w[0] = 0x453;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0xD1));
+ assert(n[1] == char(0x93));
+
+ w[0] = 0x56;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+1);
+ assert(n[0] == char(0x56));
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char32_t, 0x1000> C;
+ C c;
+ char32_t w[2] = {0xD8C0, 0xDC03};
+ char n[4] = {0};
+ const char32_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, w, w+2, wp, n, n+4, np);
+ assert(r == std::codecvt_base::error);
+ assert(wp == w);
+ assert(np == n);
+
+ w[0] = 0x1005;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::error);
+ assert(wp == w);
+ assert(np == n);
+
+ w[0] = 0x453;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0xD1));
+ assert(n[1] == char(0x93));
+
+ w[0] = 0x56;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+1);
+ assert(n[0] == char(0x56));
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char32_t, 0x10ffff, std::generate_header> C;
+ C c;
+ char32_t w[2] = {0xD8C0, 0xDC03};
+ char n[7] = {0};
+ const char32_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, w, w+2, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+2);
+ assert(np == n+7);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xF1));
+ assert(n[4] == char(0x80));
+ assert(n[5] == char(0x80));
+ assert(n[6] == char(0x83));
+
+ w[0] = 0x1005;
+ r = c.out(m, w, w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+6);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xE1));
+ assert(n[4] == char(0x80));
+ assert(n[5] == char(0x85));
+
+ w[0] = 0x453;
+ r = c.out(m, w, w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+5);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xD1));
+ assert(n[4] == char(0x93));
+
+ w[0] = 0x56;
+ r = c.out(m, w, w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+4);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0x56));
+ }
+
+ {
+ typedef std::codecvt_utf8_utf16<char16_t> C;
+ C c;
+ char16_t w[2] = {0xD8C0, 0xDC03};
+ char n[4] = {0};
+ const char16_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, w, w+2, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+2);
+ assert(np == n+4);
+ assert(n[0] == char(0xF1));
+ assert(n[1] == char(0x80));
+ assert(n[2] == char(0x80));
+ assert(n[3] == char(0x83));
+
+ w[0] = 0x1005;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+3);
+ assert(n[0] == char(0xE1));
+ assert(n[1] == char(0x80));
+ assert(n[2] == char(0x85));
+
+ w[0] = 0x453;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0xD1));
+ assert(n[1] == char(0x93));
+
+ w[0] = 0x56;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+1);
+ assert(n[0] == char(0x56));
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char16_t, 0x1000> C;
+ C c;
+ char16_t w[2] = {0xD8C0, 0xDC03};
+ char n[4] = {0};
+ const char16_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, w, w+2, wp, n, n+4, np);
+ assert(r == std::codecvt_base::error);
+ assert(wp == w);
+ assert(np == n);
+
+ w[0] = 0x1005;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::error);
+ assert(wp == w);
+ assert(np == n);
+
+ w[0] = 0x453;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+2);
+ assert(n[0] == char(0xD1));
+ assert(n[1] == char(0x93));
+
+ w[0] = 0x56;
+ r = c.out(m, w, w+1, wp, n, n+4, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+1);
+ assert(n[0] == char(0x56));
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char16_t, 0x10ffff, std::generate_header> C;
+ C c;
+ char16_t w[2] = {0xD8C0, 0xDC03};
+ char n[7] = {0};
+ const char16_t* wp = nullptr;
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.out(m, w, w+2, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+2);
+ assert(np == n+7);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xF1));
+ assert(n[4] == char(0x80));
+ assert(n[5] == char(0x80));
+ assert(n[6] == char(0x83));
+
+ w[0] = 0x1005;
+ r = c.out(m, w, w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+6);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xE1));
+ assert(n[4] == char(0x80));
+ assert(n[5] == char(0x85));
+
+ w[0] = 0x453;
+ r = c.out(m, w, w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+5);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0xD1));
+ assert(n[4] == char(0x93));
+
+ w[0] = 0x56;
+ r = c.out(m, w, w+1, wp, n, n+7, np);
+ assert(r == std::codecvt_base::ok);
+ assert(wp == w+1);
+ assert(np == n+4);
+ assert(n[0] == char(0xEF));
+ assert(n[1] == char(0xBB));
+ assert(n[2] == char(0xBF));
+ assert(n[3] == char(0x56));
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_unshift.pass.cpp b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_unshift.pass.cpp
new file mode 100644
index 00000000000..dc9e6557280
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/codecvt_utf8_utf16_unshift.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+// template <class Elem, unsigned long Maxcode = 0x10ffff,
+// codecvt_mode Mode = (codecvt_mode)0>
+// class codecvt_utf8_utf16
+// : public codecvt<Elem, char, mbstate_t>
+// {
+// // unspecified
+// };
+
+// result
+// unshift(stateT& state,
+// externT* to, externT* to_end, externT*& to_next) const;
+
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::codecvt_utf8_utf16<wchar_t> C;
+ C c;
+ char n[4] = {0};
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.unshift(m, n, n+4, np);
+ assert(r == std::codecvt_base::noconv);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char16_t> C;
+ C c;
+ char n[4] = {0};
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.unshift(m, n, n+4, np);
+ assert(r == std::codecvt_base::noconv);
+ }
+ {
+ typedef std::codecvt_utf8_utf16<char32_t> C;
+ C c;
+ char n[4] = {0};
+ std::mbstate_t m;
+ char* np = nullptr;
+ std::codecvt_base::result r = c.unshift(m, n, n+4, np);
+ assert(r == std::codecvt_base::noconv);
+ }
+}
diff --git a/libcxx/test/localization/locale.stdcvt/version.pass.cpp b/libcxx/test/localization/locale.stdcvt/version.pass.cpp
new file mode 100644
index 00000000000..916d9780476
--- /dev/null
+++ b/libcxx/test/localization/locale.stdcvt/version.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <codecvt>
+
+#include <codecvt>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
OpenPOWER on IntegriCloud