Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/ctor_char16_t_char8_t.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/ctor_char16_t_char8_t.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// explicit codecvt(size_t refs = 0); + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +using F = std::codecvt; + +struct my_facet : F { + static int count; + + explicit my_facet(std::size_t refs = 0) : F(refs) { ++count; } + + ~my_facet() { --count; } +}; + +int my_facet::count = 0; + +int main(int, char**) { + { + std::locale l(std::locale::classic(), new my_facet); + assert(my_facet::count == 1); + } + assert(my_facet::count == 0); + { + my_facet f(1); + assert(my_facet::count == 1); + { + std::locale l(std::locale::classic(), &f); + assert(my_facet::count == 1); + } + assert(my_facet::count == 1); + } + assert(my_facet::count == 0); + + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/ctor_char32_t_char8_t.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/ctor_char32_t_char8_t.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// explicit codecvt(size_t refs = 0); + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +using F = std::codecvt; + +struct my_facet : F { + static int count; + + explicit my_facet(std::size_t refs = 0) : F(refs) { ++count; } + + ~my_facet() { --count; } +}; + +int my_facet::count = 0; + +int main(int, char**) { + { + std::locale l(std::locale::classic(), new my_facet); + assert(my_facet::count == 1); + } + assert(my_facet::count == 0); + { + my_facet f(1); + assert(my_facet::count == 1); + { + std::locale l(std::locale::classic(), &f); + assert(my_facet::count == 1); + } + assert(my_facet::count == 1); + } + assert(my_facet::count == 0); + + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_always_noconv.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_always_noconv.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// bool always_noconv() const noexcept; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +int main(int, char**) { + using F = std::codecvt; + const F& f = std::use_facet(std::locale::classic()); + assert(!f.always_noconv()); + static_assert(noexcept(f.always_noconv())); + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_encoding.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_encoding.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// int encoding() const noexcept; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +int main(int, char**) { + using F = std::codecvt; + const F& f = std::use_facet(std::locale::classic()); + assert(f.encoding() == 0); + static_assert(noexcept(f.encoding())); + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_in.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_in.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// result in(stateT& state, +// const externT* from, const externT* from_end, const externT*& from_next, +// internT* to, internT* to_end, internT*& to_next) const; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +int main(int, char**) { + using F = std::codecvt; + const F::extern_type from[] = u8"some text"; + F::intern_type to[9]; + const F& f = std::use_facet(std::locale::classic()); + std::mbstate_t mbs = {}; + const F::extern_type* from_next = nullptr; + F::intern_type* to_next = nullptr; + assert(f.in(mbs, from, from + 9, from_next, to, to + 9, to_next) == F::ok); + assert(from_next - from == 9); + assert(to_next - to == 9); + for (unsigned i = 0; i < 9; ++i) + assert(to[i] == from[i]); + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_length.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_length.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// int length(stateT& state, const externT* from, const externT* from_end, size_t max) const; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +int main(int, char**) { + using F = std::codecvt; + const F& f = std::use_facet(std::locale::classic()); + std::mbstate_t mbs = {}; + const char8_t from[] = u8"some text"; + assert(f.length(mbs, from, from + 10, 0) == 0); + assert(f.length(mbs, from, from + 10, 8) == 8); + assert(f.length(mbs, from, from + 10, 9) == 9); + assert(f.length(mbs, from, from + 10, 10) == 10); + assert(f.length(mbs, from, from + 10, 100) == 10); + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_max_length.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_max_length.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// int max_length() const noexcept; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +int main(int, char**) { + using F = std::codecvt; + const F& f = std::use_facet(std::locale::classic()); + assert(f.max_length() == 4); + static_assert(noexcept(f.max_length())); + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_out.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_out.pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// result out(stateT& state, +// const internT* from, const internT* from_end, const internT*& from_next, +// externT* to, externT* to_end, externT*& to_next) const; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +int main(int, char**) { + using F = std::codecvt; + const F& f = std::use_facet(std::locale::classic()); + F::intern_type from[9] = {'s', 'o', 'm', 'e', ' ', 't', 'e', 'x', 't'}; + F::extern_type to[9] = {0}; + std::mbstate_t mbs = {}; + const F::intern_type* from_next = nullptr; + F::extern_type* to_next = nullptr; + F::result r = f.out(mbs, from, from + 9, from_next, to, to + 9, to_next); + assert(r == F::ok); + assert(from_next - from == 9); + assert(to_next - to == 9); + for (unsigned i = 0; i < 9; ++i) + assert(to[i] == from[i]); + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_unshift.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_unshift.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// result unshift(stateT& state, +// externT* to, externT* to_end, externT*& to_next) const; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +int main(int, char**) { + using F = std::codecvt; + const F& f = std::use_facet(std::locale::classic()); + std::mbstate_t mbs = {}; + char8_t to[3]; + char8_t* to_next = nullptr; + assert(f.unshift(mbs, to, to + 3, to_next) == F::noconv); + assert(to_next == to); + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_always_noconv.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_always_noconv.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// bool always_noconv() const noexcept; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +int main(int, char**) { + using F = std::codecvt; + const F& f = std::use_facet(std::locale::classic()); + assert(!f.always_noconv()); + static_assert(noexcept(f.always_noconv())); + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_encoding.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_encoding.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// int encoding() const noexcept; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +int main(int, char**) { + using F = std::codecvt; + const F& f = std::use_facet(std::locale::classic()); + assert(f.encoding() == 0); + static_assert(noexcept(f.encoding())); + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_in.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_in.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// result in(stateT& state, +// const externT* from, const externT* from_end, const externT*& from_next, +// internT* to, internT* to_end, internT*& to_next) const; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +int main(int, char**) { + using F = std::codecvt; + const F::extern_type from[] = u8"some text"; + F::intern_type to[9]; + const F& f = std::use_facet(std::locale::classic()); + std::mbstate_t mbs = {}; + const F::extern_type* from_next = nullptr; + F::intern_type* to_next = nullptr; + assert(f.in(mbs, from, from + 9, from_next, to, to + 9, to_next) == F::ok); + assert(from_next - from == 9); + assert(to_next - to == 9); + for (unsigned i = 0; i < 9; ++i) + assert(to[i] == from[i]); + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_length.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_length.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// int length(stateT& state, const externT* from, const externT* from_end, size_t max) const; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +int main(int, char**) { + using F = std::codecvt; + const F& f = std::use_facet(std::locale::classic()); + std::mbstate_t mbs = {}; + const char8_t from[] = u8"some text"; + assert(f.length(mbs, from, from + 10, 0) == 0); + assert(f.length(mbs, from, from + 10, 8) == 8); + assert(f.length(mbs, from, from + 10, 9) == 9); + assert(f.length(mbs, from, from + 10, 10) == 10); + assert(f.length(mbs, from, from + 10, 100) == 10); + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_max_length.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_max_length.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// int max_length() const noexcept; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +int main(int, char**) { + using F = std::codecvt; + const F& f = std::use_facet(std::locale::classic()); + assert(f.max_length() == 4); + static_assert(noexcept(f.max_length())); + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_out.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_out.pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// result out(stateT& state, +// const internT* from, const internT* from_end, const internT*& from_next, +// externT* to, externT* to_end, externT*& to_next) const; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +int main(int, char**) { + using F = std::codecvt; + const F& f = std::use_facet(std::locale::classic()); + F::intern_type from[9] = {'s', 'o', 'm', 'e', ' ', 't', 'e', 'x', 't'}; + F::extern_type to[9] = {0}; + std::mbstate_t mbs = {}; + const F::intern_type* from_next = nullptr; + F::extern_type* to_next = nullptr; + F::result r = f.out(mbs, from, from + 9, from_next, to, to + 9, to_next); + assert(r == F::ok); + assert(from_next - from == 9); + assert(to_next - to == 9); + for (unsigned i = 0; i < 9; ++i) + assert(to[i] == from[i]); + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_unshift.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_unshift.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> class codecvt + +// result unshift(stateT& state, +// externT* to, externT* to_end, externT*& to_next) const; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include + +int main(int, char**) { + using F = std::codecvt; + const F& f = std::use_facet(std::locale::classic()); + std::mbstate_t mbs = {}; + char8_t to[3]; + char8_t* to_next = nullptr; + assert(f.unshift(mbs, to, to + 3, to_next) == F::noconv); + assert(to_next == to); + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/utf_sanity_check.pass.cpp =================================================================== --- libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/utf_sanity_check.pass.cpp +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/utf_sanity_check.pass.cpp @@ -10,6 +10,8 @@ // template <> class codecvt // template <> class codecvt +// template <> class codecvt // C++20 +// template <> class codecvt // C++20 // template <> class codecvt // extension // sanity check @@ -22,109 +24,194 @@ #include "test_macros.h" -int main(int, char**) -{ - typedef std::codecvt F32_8; - typedef std::codecvt F16_8; - typedef std::codecvt_utf16 F32_16; - std::locale l = std::locale(std::locale::classic(), new F32_16); - const F32_8& f32_8 = std::use_facet(std::locale::classic()); - const F32_16& f32_16 = std::use_facet(l); - const F16_8& f16_8 = std::use_facet(std::locale::classic()); - std::mbstate_t mbs = {}; - F32_8::intern_type* c32p; - F16_8::intern_type* c16p; - F32_8::extern_type* c8p; - const F32_8::intern_type* c_c32p; - const F16_8::intern_type* c_c16p; - 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, 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, c16c, c16c+4, c16cp) == F32_8::ok); - assert(c_c32p-&c32x == 1); - if (c32x < 0x10000) - assert(c16cp-c16c == 2); - else - 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); - else - assert(c_c16p-c16 == 2); - if (c32x < 0x80) - assert(c8p-c8 == 1); - else if (c32x < 0x800) - assert(c8p-c8 == 2); - else if (c32x < 0x10000) - assert(c8p-c8 == 3); - else - assert(c8p-c8 == 4); - c_c8p = c8p; - assert(f32_8.in(mbs, c8, c_c8p, c_c8p, &c32, &c32+1, c32p) == F32_8::ok); - if (c32x < 0x80) - assert(c_c8p-c8 == 1); - else if (c32x < 0x800) - assert(c_c8p-c8 == 2); - else if (c32x < 0x10000) - assert(c_c8p-c8 == 3); - else - assert(c_c8p-c8 == 4); - assert(c32p-&c32 == 1); - assert(c32 == c32x); - assert(f32_8.out(mbs, &c32x, &c32x+1, c_c32p, c8, c8+4, c8p) == F32_8::ok); - assert(c_c32p-&c32x == 1); - if (c32x < 0x80) - assert(c8p-c8 == 1); - else if (c32x < 0x800) - assert(c8p-c8 == 2); - else if (c32x < 0x10000) - assert(c8p-c8 == 3); - else - assert(c8p-c8 == 4); - c_c8p = c8p; - assert(f16_8.in(mbs, c8, c_c8p, c_c8p, c16, c16+2, c16p) == F32_8::ok); - if (c32x < 0x80) - assert(c_c8p-c8 == 1); - else if (c32x < 0x800) - assert(c_c8p-c8 == 2); - else if (c32x < 0x10000) - assert(c_c8p-c8 == 3); - else - assert(c_c8p-c8 == 4); - if (c32x < 0x10000) - assert(c16p-c16 == 1); - else - assert(c16p-c16 == 2); - for (int i = 0; i < c16p-c16; ++i) - { - c16c[2*i] = static_cast(c16[i] >> 8); - c16c[2*i+1] = static_cast(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_c16cp-c16c == 2); - else - assert(c_c16cp-c16c == 4); - assert(c32p-&c32 == 1); - assert(c32 == c32x); - } +int main(int, char**) { + typedef std::codecvt F32_8; + typedef std::codecvt F16_8; + typedef std::codecvt_utf16 F32_16; + std::locale l = std::locale(std::locale::classic(), new F32_16); + const F32_8& f32_8 = std::use_facet(std::locale::classic()); + const F32_16& f32_16 = std::use_facet(l); + const F16_8& f16_8 = std::use_facet(std::locale::classic()); + std::mbstate_t mbs32_8 = {}; + std::mbstate_t mbs16_8 = {}; + std::mbstate_t mbs32_16 = {}; + F32_8::intern_type* c32p; + F16_8::intern_type* c16p; + F32_8::extern_type* c8p; + const F32_8::intern_type* c_c32p; + const F16_8::intern_type* c_c16p; + 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]; + +// C++20 codecvt specializations for char8_t are not yet implemented +#if TEST_STD_VER > 17 && !defined(_LIBCPP_VERSION) + typedef std::codecvt F32_8T; + typedef std::codecvt F16_8T; + const F32_8T& f32_8t = std::use_facet(std::locale::classic()); + const F16_8T& f16_8t = std::use_facet(std::locale::classic()); + std::mbstate_t mbs32_8t = {}; + std::mbstate_t mbs16_8t = {}; + F32_8T::extern_type* c8tp; + const F32_8T::extern_type* c_c8tp; + F32_8T::extern_type c8t[4]; +#endif + + for (F32_8::intern_type c32x = 0; c32x < 0x110003; ++c32x) { + if ((0xD800 <= c32x && c32x < 0xE000) || c32x >= 0x110000) { +#ifndef _MSVC_STL_VERSION // Don't ask; eldritch horrors. + assert(f32_16.out(mbs32_16, &c32x, &c32x + 1, c_c32p, c16c + 0, c16c + 4, + c16cp) == F32_8::error); + assert(f32_8.out(mbs32_8, &c32x, &c32x + 1, c_c32p, c8, c8 + 4, c8p) == + F32_8::error); +#endif + +// C++20 codecvt specializations for char8_t are not yet implemented +#if TEST_STD_VER > 17 && !defined(_LIBCPP_VERSION) + assert(f32_8t.out(mbs32_8t, &c32x, &c32x + 1, c_c32p, c8t, c8t + 4, + c8tp) == F32_8T::error); +#endif + } else { + assert(f32_16.out(mbs32_16, &c32x, &c32x + 1, c_c32p, c16c, c16c + 4, + c16cp) == F32_8::ok); + assert(c_c32p - &c32x == 1); + if (c32x < 0x10000) + assert(c16cp - c16c == 2); + else + assert(c16cp - c16c == 4); + for (int i = 0; i < (c16cp - c16c) / 2; ++i) + c16[i] = (char16_t)((unsigned char)c16c[2 * i] << 8 | + (unsigned char)c16c[2 * i + 1]); + c_c16p = c16 + (c16cp - c16c) / 2; + assert(f16_8.out(mbs16_8, c16, c_c16p, c_c16p, c8, c8 + 4, c8p) == + F32_8::ok); + if (c32x < 0x10000) + assert(c_c16p - c16 == 1); + else + assert(c_c16p - c16 == 2); + if (c32x < 0x80) + assert(c8p - c8 == 1); + else if (c32x < 0x800) + assert(c8p - c8 == 2); + else if (c32x < 0x10000) + assert(c8p - c8 == 3); + else + assert(c8p - c8 == 4); + c_c8p = c8p; + assert(f32_8.in(mbs32_8, c8, c_c8p, c_c8p, &c32, &c32 + 1, c32p) == + F32_8::ok); + if (c32x < 0x80) + assert(c_c8p - c8 == 1); + else if (c32x < 0x800) + assert(c_c8p - c8 == 2); + else if (c32x < 0x10000) + assert(c_c8p - c8 == 3); + else + assert(c_c8p - c8 == 4); + assert(c32p - &c32 == 1); + assert(c32 == c32x); + assert(f32_8.out(mbs32_8, &c32x, &c32x + 1, c_c32p, c8, c8 + 4, c8p) == + F32_8::ok); + assert(c_c32p - &c32x == 1); + if (c32x < 0x80) + assert(c8p - c8 == 1); + else if (c32x < 0x800) + assert(c8p - c8 == 2); + else if (c32x < 0x10000) + assert(c8p - c8 == 3); + else + assert(c8p - c8 == 4); + c_c8p = c8p; + assert(f16_8.in(mbs16_8, c8, c_c8p, c_c8p, c16, c16 + 2, c16p) == + F32_8::ok); + if (c32x < 0x80) + assert(c_c8p - c8 == 1); + else if (c32x < 0x800) + assert(c_c8p - c8 == 2); + else if (c32x < 0x10000) + assert(c_c8p - c8 == 3); + else + assert(c_c8p - c8 == 4); + if (c32x < 0x10000) + assert(c16p - c16 == 1); + else + assert(c16p - c16 == 2); + for (int i = 0; i < c16p - c16; ++i) { + c16c[2 * i] = static_cast(c16[i] >> 8); + c16c[2 * i + 1] = static_cast(c16[i]); + } + const char* c_c16cp = c16c + (c16p - c16) * 2; + assert(f32_16.in(mbs32_16, c16c, c_c16cp, c_c16cp, &c32, &c32 + 1, + c32p) == F32_8::ok); + if (c32x < 0x10000) + assert(c_c16cp - c16c == 2); + else + assert(c_c16cp - c16c == 4); + assert(c32p - &c32 == 1); + assert(c32 == c32x); + +// C++20 codecvt specializations for char8_t are not yet implemented +#if TEST_STD_VER > 17 && !defined(_LIBCPP_VERSION) + assert(f32_8t.out(mbs32_8t, &c32x, &c32x + 1, c_c32p, c8t, c8t + 4, + c8tp) == F32_8T::ok); + assert(c_c32p - &c32x == 1); + if (c32x < 0x80) + assert(c8tp - c8t == 1); + else if (c32x < 0x800) + assert(c8tp - c8t == 2); + else if (c32x < 0x10000) + assert(c8tp - c8t == 3); + else + assert(c8tp - c8t == 4); + c_c8tp = c8tp; + assert(f16_8t.in(mbs16_8t, c8t, c_c8tp, c_c8tp, c16, c16 + 2, c16p) == + F16_8T::ok); + if (c32x < 0x80) + assert(c_c8tp - c8t == 1); + else if (c32x < 0x800) + assert(c_c8tp - c8t == 2); + else if (c32x < 0x10000) + assert(c_c8tp - c8t == 3); + else + assert(c_c8tp - c8t == 4); + if (c32x < 0x10000) + assert(c16p - c16 == 1); + else + assert(c16p - c16 == 2); + c_c16p = c16p; + assert(f16_8t.out(mbs16_8t, c16, c_c16p, c_c16p, c8t, c8t + 4, c8tp) == + F16_8T::ok); + if (c32x < 0x10000) + assert(c_c16p - c16 == 1); + else + assert(c_c16p - c16 == 2); + if (c32x < 0x80) + assert(c8tp - c8t == 1); + else if (c32x < 0x800) + assert(c8tp - c8t == 2); + else if (c32x < 0x10000) + assert(c8tp - c8t == 3); + else + assert(c8tp - c8t == 4); + c_c8tp = c8tp; + assert(f32_8t.in(mbs32_8t, c8t, c_c8tp, c_c8tp, &c32, &c32 + 1, c32p) == + F32_8T::ok); + if (c32x < 0x80) + assert(c_c8tp - c8t == 1); + else if (c32x < 0x800) + assert(c_c8tp - c8t == 2); + else if (c32x < 0x10000) + assert(c_c8tp - c8t == 3); + else + assert(c_c8tp - c8t == 4); + assert(c32p - &c32 == 1); + assert(c32 == c32x); +#endif } + } return 0; } Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/types_char16_t_char8_t.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/types_char16_t_char8_t.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> +// class codecvt +// : public locale::facet, +// public codecvt_base +// { +// public: +// typedef char16_t intern_type; +// typedef char8_t extern_type; +// typedef mbstate_t state_type; +// ... +// }; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include +#include + +int main(int, char**) { + using F = std::codecvt; + static_assert(std::is_base_of_v); + static_assert(std::is_base_of_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + std::locale l = std::locale::classic(); + assert(std::has_facet(l)); + const F& f = std::use_facet(l); + (void)F::id; + (void)f; + return 0; +} Index: libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/types_char32_t_char8_t.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/localization/locale.categories/category.ctype/locale.codecvt/types_char32_t_char8_t.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template <> +// class codecvt +// : public locale::facet, +// public codecvt_base +// { +// public: +// typedef char32_t intern_type; +// typedef char8_t extern_type; +// typedef mbstate_t state_type; +// ... +// }; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// C++20 codecvt specializations for char8_t are not yet implemented: +// UNSUPPORTED: libc++ + +#include +#include +#include + +int main(int, char**) { + using F = std::codecvt; + static_assert(std::is_base_of_v); + static_assert(std::is_base_of_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + std::locale l = std::locale::classic(); + assert(std::has_facet(l)); + const F& f = std::use_facet(l); + (void)F::id; + (void)f; + return 0; +}