From caae3ec6759f5745dedf6222eb8362dad1256a5c Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Thu, 6 Dec 2018 00:24:58 +0000 Subject: [PATCH 01/94] [libcxx] Don't depend on availability markup to provide the streams in the dylib Whether an explicit instantiation declaration should be provided is not a matter of availability markup. This problem is exemplified by the fact that some tests were incorrectly marked as XFAIL when they should instead have been using the definition of streams from the headers, and hence passing, and that, regardless of whether visibility annotations are enabled. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348436 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/__config | 15 +++++++++------ include/istream | 2 +- include/ostream | 2 +- include/streambuf | 2 +- .../istream.unformatted/get.pass.cpp | 2 -- .../istream.unformatted/get_chart.pass.cpp | 2 -- .../istream.unformatted/get_pointer_size.pass.cpp | 4 ++-- .../get_pointer_size_chart.pass.cpp | 4 ++-- .../getline_pointer_size.pass.cpp | 4 ++-- .../getline_pointer_size_chart.pass.cpp | 4 ++-- .../istream.unformatted/ignore_0xff.pass.cpp | 3 --- .../istream.unformatted/read.pass.cpp | 2 -- .../istream.unformatted/readsome.pass.cpp | 3 --- .../istream.unformatted/seekg.pass.cpp | 3 --- .../istream.unformatted/seekg_off.pass.cpp | 2 -- .../complex.ops/stream_input.pass.cpp | 2 -- 16 files changed, 20 insertions(+), 36 deletions(-) diff --git a/include/__config b/include/__config index ef69bf495..a99fd16b9 100644 --- a/include/__config +++ b/include/__config @@ -1359,16 +1359,19 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( # define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS #endif -// Availability of stream API in the dylib got dropped and re-added. The -// extern template should effectively be available at: -// availability(macosx,introduced=10.9) -// availability(ios,introduced=7.0) -#if defined(_LIBCPP_USE_AVAILABILITY_APPLE) && \ +// The stream API was dropped and re-added in the dylib shipped on macOS +// and iOS. We can only assume the dylib to provide these definitions for +// macosx >= 10.9 and ios >= 7.0. Otherwise, the definitions are available +// from the headers, but not from the dylib. Explicit instantiation +// declarations for streams exist conditionally to this; if we provide +// an explicit instantiation declaration and we try to deploy to a dylib +// that does not provide those symbols, we'll get a load-time error. +#if !defined(_LIBCPP_BUILDING_LIBRARY) && \ ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1090) || \ (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \ __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000)) -#define _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE +# define _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB #endif #if defined(_LIBCPP_COMPILER_IBM) diff --git a/include/istream b/include/istream index 8487dbeba..efbbae800 100644 --- a/include/istream +++ b/include/istream @@ -1504,7 +1504,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x) return __is; } -#ifndef _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE +#ifndef _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream) _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream) _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_iostream) diff --git a/include/ostream b/include/ostream index ef34f71c1..d7a5d5289 100644 --- a/include/ostream +++ b/include/ostream @@ -1092,7 +1092,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x) use_facet >(__os.getloc()).widen('1')); } -#ifndef _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE +#ifndef _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream) _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream) #endif diff --git a/include/streambuf b/include/streambuf index 1739d58a1..dd293dc63 100644 --- a/include/streambuf +++ b/include/streambuf @@ -486,7 +486,7 @@ basic_streambuf<_CharT, _Traits>::overflow(int_type) return traits_type::eof(); } -#ifndef _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE +#ifndef _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf) _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf) diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp index c7f16ca7e..0f356e26d 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: with_system_cxx_lib=macosx10.7 - // // int_type get(); diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp index b3d3c69b4..cf06e343b 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: with_system_cxx_lib=macosx10.7 - // // basic_istream& get(char_type& c); diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp index a45802c57..bee448371 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp @@ -7,13 +7,13 @@ // //===----------------------------------------------------------------------===// +// In macosx10.9 to macosx10.14, streams are provided in the dylib AND they +// have a bug in how they handle null-termination in case of errors (see D40677). // XFAIL: with_system_cxx_lib=macosx10.13 // XFAIL: with_system_cxx_lib=macosx10.12 // XFAIL: with_system_cxx_lib=macosx10.11 // XFAIL: with_system_cxx_lib=macosx10.10 // XFAIL: with_system_cxx_lib=macosx10.9 -// XFAIL: with_system_cxx_lib=macosx10.8 -// XFAIL: with_system_cxx_lib=macosx10.7 // diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp index 437af84f9..c998680de 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp @@ -7,13 +7,13 @@ // //===----------------------------------------------------------------------===// +// In macosx10.9 to macosx10.14, streams are provided in the dylib AND they +// have a bug in how they handle null-termination in case of errors (see D40677). // XFAIL: with_system_cxx_lib=macosx10.13 // XFAIL: with_system_cxx_lib=macosx10.12 // XFAIL: with_system_cxx_lib=macosx10.11 // XFAIL: with_system_cxx_lib=macosx10.10 // XFAIL: with_system_cxx_lib=macosx10.9 -// XFAIL: with_system_cxx_lib=macosx10.8 -// XFAIL: with_system_cxx_lib=macosx10.7 // diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp index 7ee2c2956..7ac350f9c 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp @@ -7,13 +7,13 @@ // //===----------------------------------------------------------------------===// +// In macosx10.9 to macosx10.14, streams are provided in the dylib AND they +// have a bug in how they handle null-termination in case of errors (see D40677). // XFAIL: with_system_cxx_lib=macosx10.13 // XFAIL: with_system_cxx_lib=macosx10.12 // XFAIL: with_system_cxx_lib=macosx10.11 // XFAIL: with_system_cxx_lib=macosx10.10 // XFAIL: with_system_cxx_lib=macosx10.9 -// XFAIL: with_system_cxx_lib=macosx10.8 -// XFAIL: with_system_cxx_lib=macosx10.7 // diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp index 1bce3fa5d..f4da497b2 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp @@ -7,13 +7,13 @@ // //===----------------------------------------------------------------------===// +// In macosx10.9 to macosx10.14, streams are provided in the dylib AND they +// have a bug in how they handle null-termination in case of errors (see D40677). // XFAIL: with_system_cxx_lib=macosx10.13 // XFAIL: with_system_cxx_lib=macosx10.12 // XFAIL: with_system_cxx_lib=macosx10.11 // XFAIL: with_system_cxx_lib=macosx10.10 // XFAIL: with_system_cxx_lib=macosx10.9 -// XFAIL: with_system_cxx_lib=macosx10.8 -// XFAIL: with_system_cxx_lib=macosx10.7 // diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore_0xff.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore_0xff.pass.cpp index 3a37cffce..3095712b9 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore_0xff.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore_0xff.pass.cpp @@ -7,9 +7,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: with_system_cxx_lib=macosx10.7 -// XFAIL: with_system_cxx_lib=macosx10.8 - // // basic_istream& diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp index ceef0d28f..20e70cfbd 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: with_system_cxx_lib=macosx10.7 - // // basic_istream& read(char_type* s, streamsize n); diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp index a0a8e2f1b..01eecb5d8 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp @@ -7,9 +7,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: with_system_cxx_lib=macosx10.7 -// XFAIL: with_system_cxx_lib=macosx10.8 - // // streamsize readsome(char_type* s, streamsize n); diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp index e370b4bfb..dc4e0ba0d 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp @@ -7,9 +7,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: with_system_cxx_lib=macosx10.7 -// XFAIL: with_system_cxx_lib=macosx10.8 - // // basic_istream& seekg(pos_type pos); diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp index d41302e68..3b7417ab2 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp @@ -10,8 +10,6 @@ // XFAIL: with_system_cxx_lib=macosx10.11 // XFAIL: with_system_cxx_lib=macosx10.10 // XFAIL: with_system_cxx_lib=macosx10.9 -// XFAIL: with_system_cxx_lib=macosx10.7 -// XFAIL: with_system_cxx_lib=macosx10.8 // diff --git a/test/std/numerics/complex.number/complex.ops/stream_input.pass.cpp b/test/std/numerics/complex.number/complex.ops/stream_input.pass.cpp index 4d866acb8..24644e307 100644 --- a/test/std/numerics/complex.number/complex.ops/stream_input.pass.cpp +++ b/test/std/numerics/complex.number/complex.ops/stream_input.pass.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: with_system_cxx_lib=macosx10.7 - // // template From 8bcb9cabcd045b57f3fde41b7df532a331915bd3 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Thu, 6 Dec 2018 00:25:15 +0000 Subject: [PATCH 02/94] [libcxx] Mark some tests as failing on macosx 10.14 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348437 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../input.streams/istream.unformatted/get_pointer_size.pass.cpp | 1 + .../istream.unformatted/get_pointer_size_chart.pass.cpp | 1 + .../istream.unformatted/getline_pointer_size.pass.cpp | 1 + .../istream.unformatted/getline_pointer_size_chart.pass.cpp | 1 + 4 files changed, 4 insertions(+) diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp index bee448371..83fd40bef 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp @@ -9,6 +9,7 @@ // In macosx10.9 to macosx10.14, streams are provided in the dylib AND they // have a bug in how they handle null-termination in case of errors (see D40677). +// XFAIL: with_system_cxx_lib=macosx10.14 // XFAIL: with_system_cxx_lib=macosx10.13 // XFAIL: with_system_cxx_lib=macosx10.12 // XFAIL: with_system_cxx_lib=macosx10.11 diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp index c998680de..8b42bae55 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp @@ -9,6 +9,7 @@ // In macosx10.9 to macosx10.14, streams are provided in the dylib AND they // have a bug in how they handle null-termination in case of errors (see D40677). +// XFAIL: with_system_cxx_lib=macosx10.14 // XFAIL: with_system_cxx_lib=macosx10.13 // XFAIL: with_system_cxx_lib=macosx10.12 // XFAIL: with_system_cxx_lib=macosx10.11 diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp index 7ac350f9c..f17aa1623 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp @@ -9,6 +9,7 @@ // In macosx10.9 to macosx10.14, streams are provided in the dylib AND they // have a bug in how they handle null-termination in case of errors (see D40677). +// XFAIL: with_system_cxx_lib=macosx10.14 // XFAIL: with_system_cxx_lib=macosx10.13 // XFAIL: with_system_cxx_lib=macosx10.12 // XFAIL: with_system_cxx_lib=macosx10.11 diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp index f4da497b2..5c6a3c59f 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp @@ -9,6 +9,7 @@ // In macosx10.9 to macosx10.14, streams are provided in the dylib AND they // have a bug in how they handle null-termination in case of errors (see D40677). +// XFAIL: with_system_cxx_lib=macosx10.14 // XFAIL: with_system_cxx_lib=macosx10.13 // XFAIL: with_system_cxx_lib=macosx10.12 // XFAIL: with_system_cxx_lib=macosx10.11 From edfdc498b8c3b60a548118051c8af96bcf97e731 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Thu, 6 Dec 2018 13:52:20 +0000 Subject: [PATCH 03/94] [libcxx] Make return value of array.data() checked only for libc++ The section array.zero says: "The return value of data() is unspecified". This patch marks all checks of the array.data() return value as libc++ specific. Reviewed as https://reviews.llvm.org/D55364. Thanks to Andrey Maksimov for the patch. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348485 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../containers/sequences/array/array.data/data.pass.cpp | 8 ++++---- .../sequences/array/array.data/data_const.pass.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/std/containers/sequences/array/array.data/data.pass.cpp b/test/std/containers/sequences/array/array.data/data.pass.cpp index 436cea431..ba2c571eb 100644 --- a/test/std/containers/sequences/array/array.data/data.pass.cpp +++ b/test/std/containers/sequences/array/array.data/data.pass.cpp @@ -42,7 +42,7 @@ int main() typedef std::array C; C c = {}; T* p = c.data(); - assert(p != nullptr); + LIBCPP_ASSERT(p != nullptr); } { typedef double T; @@ -50,14 +50,14 @@ int main() C c = {{}}; const T* p = c.data(); static_assert((std::is_same::value), ""); - assert(p != nullptr); + LIBCPP_ASSERT(p != nullptr); } { typedef std::max_align_t T; typedef std::array C; const C c = {}; const T* p = c.data(); - assert(p != nullptr); + LIBCPP_ASSERT(p != nullptr); std::uintptr_t pint = reinterpret_cast(p); assert(pint % TEST_ALIGNOF(std::max_align_t) == 0); } @@ -66,6 +66,6 @@ int main() typedef std::array C; C c = {}; T* p = c.data(); - assert(p != nullptr); + LIBCPP_ASSERT(p != nullptr); } } diff --git a/test/std/containers/sequences/array/array.data/data_const.pass.cpp b/test/std/containers/sequences/array/array.data/data_const.pass.cpp index 0b6c0c48d..f46352564 100644 --- a/test/std/containers/sequences/array/array.data/data_const.pass.cpp +++ b/test/std/containers/sequences/array/array.data/data_const.pass.cpp @@ -48,14 +48,14 @@ int main() typedef std::array C; const C c = {}; const T* p = c.data(); - assert(p != nullptr); + LIBCPP_ASSERT(p != nullptr); } { typedef std::max_align_t T; typedef std::array C; const C c = {}; const T* p = c.data(); - assert(p != nullptr); + LIBCPP_ASSERT(p != nullptr); std::uintptr_t pint = reinterpret_cast(p); assert(pint % TEST_ALIGNOF(std::max_align_t) == 0); } From 7ea279fbed3f749dab88a2cde9c9bb301f5a5f07 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Thu, 6 Dec 2018 18:06:47 +0000 Subject: [PATCH 04/94] [libcxx] Add XFAILs for aligned allocation tests on AppleClang 9 Some people are still running the test suite using AppleClang 9. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348507 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../delete_align_val_t_replace.pass.cpp | 24 +++++++++---------- .../new.delete.array/new_align_val_t.pass.cpp | 24 +++++++++---------- .../new_align_val_t_nothrow.pass.cpp | 24 +++++++++---------- .../new_align_val_t_nothrow_replace.pass.cpp | 24 +++++++++---------- .../delete_align_val_t_replace.pass.cpp | 24 +++++++++---------- .../new_align_val_t.pass.cpp | 24 +++++++++---------- .../new_align_val_t_nothrow.pass.cpp | 24 +++++++++---------- .../new_align_val_t_nothrow_replace.pass.cpp | 24 +++++++++---------- 8 files changed, 96 insertions(+), 96 deletions(-) diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp index 87c0cf35f..4dd9390c4 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp @@ -20,22 +20,22 @@ // Aligned allocation was not provided before macosx10.12 and as a result we // get availability errors when the deployment target is older than macosx10.13. // However, AppleClang 10 (and older) don't trigger availability errors. -// XFAIL: !apple-clang-10 && availability=macosx10.12 -// XFAIL: !apple-clang-10 && availability=macosx10.11 -// XFAIL: !apple-clang-10 && availability=macosx10.10 -// XFAIL: !apple-clang-10 && availability=macosx10.9 -// XFAIL: !apple-clang-10 && availability=macosx10.8 -// XFAIL: !apple-clang-10 && availability=macosx10.7 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7 // On AppleClang 10 (and older), instead of getting an availability failure // like above, we get a link error when we link against a dylib that does // not export the aligned allocation functions. -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.12 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.11 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.10 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.9 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.8 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.7 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7 // On Windows libc++ doesn't provide its own definitions for new/delete // but instead depends on the ones in VCRuntime. However VCRuntime does not diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp index df2db2afc..d6194b00a 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp @@ -18,22 +18,22 @@ // Aligned allocation was not provided before macosx10.12 and as a result we // get availability errors when the deployment target is older than macosx10.13. // However, AppleClang 10 (and older) don't trigger availability errors. -// XFAIL: !apple-clang-10 && availability=macosx10.12 -// XFAIL: !apple-clang-10 && availability=macosx10.11 -// XFAIL: !apple-clang-10 && availability=macosx10.10 -// XFAIL: !apple-clang-10 && availability=macosx10.9 -// XFAIL: !apple-clang-10 && availability=macosx10.8 -// XFAIL: !apple-clang-10 && availability=macosx10.7 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7 // On AppleClang 10 (and older), instead of getting an availability failure // like above, we get a link error when we link against a dylib that does // not export the aligned allocation functions. -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.12 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.11 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.10 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.9 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.8 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.7 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7 // On Windows libc++ doesn't provide its own definitions for new/delete // but instead depends on the ones in VCRuntime. However VCRuntime does not diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp index cf51b9714..59878aefd 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp @@ -18,22 +18,22 @@ // Aligned allocation was not provided before macosx10.12 and as a result we // get availability errors when the deployment target is older than macosx10.13. // However, AppleClang 10 (and older) don't trigger availability errors. -// XFAIL: !apple-clang-10 && availability=macosx10.12 -// XFAIL: !apple-clang-10 && availability=macosx10.11 -// XFAIL: !apple-clang-10 && availability=macosx10.10 -// XFAIL: !apple-clang-10 && availability=macosx10.9 -// XFAIL: !apple-clang-10 && availability=macosx10.8 -// XFAIL: !apple-clang-10 && availability=macosx10.7 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7 // On AppleClang 10 (and older), instead of getting an availability failure // like above, we get a link error when we link against a dylib that does // not export the aligned allocation functions. -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.12 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.11 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.10 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.9 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.8 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.7 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7 // On Windows libc++ doesn't provide its own definitions for new/delete // but instead depends on the ones in VCRuntime. However VCRuntime does not diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp index f463bc757..fc713dbf8 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp @@ -13,22 +13,22 @@ // Aligned allocation was not provided before macosx10.12 and as a result we // get availability errors when the deployment target is older than macosx10.13. // However, AppleClang 10 (and older) don't trigger availability errors. -// XFAIL: !apple-clang-10 && availability=macosx10.12 -// XFAIL: !apple-clang-10 && availability=macosx10.11 -// XFAIL: !apple-clang-10 && availability=macosx10.10 -// XFAIL: !apple-clang-10 && availability=macosx10.9 -// XFAIL: !apple-clang-10 && availability=macosx10.8 -// XFAIL: !apple-clang-10 && availability=macosx10.7 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7 // On AppleClang 10 (and older), instead of getting an availability failure // like above, we get a link error when we link against a dylib that does // not export the aligned allocation functions. -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.12 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.11 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.10 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.9 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.8 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.7 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7 // XFAIL: no-aligned-allocation && !gcc diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp index 36349a424..19cabcce1 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp @@ -19,22 +19,22 @@ // Aligned allocation was not provided before macosx10.12 and as a result we // get availability errors when the deployment target is older than macosx10.13. // However, AppleClang 10 (and older) don't trigger availability errors. -// XFAIL: !apple-clang-10 && availability=macosx10.12 -// XFAIL: !apple-clang-10 && availability=macosx10.11 -// XFAIL: !apple-clang-10 && availability=macosx10.10 -// XFAIL: !apple-clang-10 && availability=macosx10.9 -// XFAIL: !apple-clang-10 && availability=macosx10.8 -// XFAIL: !apple-clang-10 && availability=macosx10.7 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7 // On AppleClang 10 (and older), instead of getting an availability failure // like above, we get a link error when we link against a dylib that does // not export the aligned allocation functions. -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.12 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.11 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.10 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.9 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.8 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.7 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7 // On Windows libc++ doesn't provide its own definitions for new/delete // but instead depends on the ones in VCRuntime. However VCRuntime does not diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp index 754132707..7cf1aca3b 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp @@ -12,22 +12,22 @@ // Aligned allocation was not provided before macosx10.12 and as a result we // get availability errors when the deployment target is older than macosx10.13. // However, AppleClang 10 (and older) don't trigger availability errors. -// XFAIL: !apple-clang-10 && availability=macosx10.12 -// XFAIL: !apple-clang-10 && availability=macosx10.11 -// XFAIL: !apple-clang-10 && availability=macosx10.10 -// XFAIL: !apple-clang-10 && availability=macosx10.9 -// XFAIL: !apple-clang-10 && availability=macosx10.8 -// XFAIL: !apple-clang-10 && availability=macosx10.7 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7 // On AppleClang 10 (and older), instead of getting an availability failure // like above, we get a link error when we link against a dylib that does // not export the aligned allocation functions. -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.12 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.11 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.10 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.9 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.8 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.7 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7 // asan and msan will not call the new handler. // UNSUPPORTED: sanitizer-new-delete diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp index cfd225d7c..dd2666e00 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp @@ -12,22 +12,22 @@ // Aligned allocation was not provided before macosx10.12 and as a result we // get availability errors when the deployment target is older than macosx10.13. // However, AppleClang 10 (and older) don't trigger availability errors. -// XFAIL: !apple-clang-10 && availability=macosx10.12 -// XFAIL: !apple-clang-10 && availability=macosx10.11 -// XFAIL: !apple-clang-10 && availability=macosx10.10 -// XFAIL: !apple-clang-10 && availability=macosx10.9 -// XFAIL: !apple-clang-10 && availability=macosx10.8 -// XFAIL: !apple-clang-10 && availability=macosx10.7 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7 // On AppleClang 10 (and older), instead of getting an availability failure // like above, we get a link error when we link against a dylib that does // not export the aligned allocation functions. -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.12 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.11 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.10 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.9 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.8 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.7 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7 // asan and msan will not call the new handler. // UNSUPPORTED: sanitizer-new-delete diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp index c47ec4f8c..514a2b8af 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp @@ -13,22 +13,22 @@ // Aligned allocation was not provided before macosx10.12 and as a result we // get availability errors when the deployment target is older than macosx10.13. // However, AppleClang 10 (and older) don't trigger availability errors. -// XFAIL: !apple-clang-10 && availability=macosx10.12 -// XFAIL: !apple-clang-10 && availability=macosx10.11 -// XFAIL: !apple-clang-10 && availability=macosx10.10 -// XFAIL: !apple-clang-10 && availability=macosx10.9 -// XFAIL: !apple-clang-10 && availability=macosx10.8 -// XFAIL: !apple-clang-10 && availability=macosx10.7 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7 // On AppleClang 10 (and older), instead of getting an availability failure // like above, we get a link error when we link against a dylib that does // not export the aligned allocation functions. -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.12 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.11 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.10 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.9 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.8 -// XFAIL: apple-clang-10 && with_system_cxx_lib=macosx10.7 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8 +// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7 // NOTE: gcc doesn't provide -faligned-allocation flag to test for // XFAIL: no-aligned-allocation && !gcc From 5b19b0bb3ffd390d16ba8ff188d097f9bb22384b Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Thu, 6 Dec 2018 18:24:39 +0000 Subject: [PATCH 05/94] [libcxx] Add checks for unique value of array.begin() and array.end() The standard section [array.zero] requires the return value of begin() and end() methods of a zero-sized array to be unique. Eric Fiselier clarifies: "That unique value cannot be null, and must be properly aligned". This patch adds checks for the first part of this clarification: unique value returned by these methods cannot be null. Reviewed as https://reviews.llvm.org/D55366. Thanks to Andrey Maksimov for the patch. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348509 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/std/containers/sequences/array/begin.pass.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/std/containers/sequences/array/begin.pass.cpp b/test/std/containers/sequences/array/begin.pass.cpp index 1c7647221..37c6b5eec 100644 --- a/test/std/containers/sequences/array/begin.pass.cpp +++ b/test/std/containers/sequences/array/begin.pass.cpp @@ -14,6 +14,8 @@ #include #include +#include "test_macros.h" + // std::array is explicitly allowed to be initialized with A a = { init-list };. // Disable the missing braces warning for this reason. #include "disable_missing_braces_warning.h" @@ -40,6 +42,11 @@ int main() typedef NoDefault T; typedef std::array C; C c = {}; - assert(c.begin() == c.end()); + C::iterator ib, ie; + ib = c.begin(); + ie = c.end(); + assert(ib == ie); + LIBCPP_ASSERT(ib != nullptr); + LIBCPP_ASSERT(ie != nullptr); } } From 55a56d23703e52ba9f918270ffd7ec56a9831096 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Thu, 6 Dec 2018 19:24:20 +0000 Subject: [PATCH 06/94] [libcxx] Fix incorrect XFAILs for chrono tests on old macos deployment targets The tests were marked to fail based on the 'availability' LIT feature. However, those tests should really only be failing when we run them against the dylibs that were deployed on macosx10.7 and macosx10.8, which the deployment target has nothing to do with. This caused the tests to unexpectedly pass when running the tests with deployment target macosx10.{7,8} but running with a recent dylib. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348520 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../time/time.clock/time.clock.hires/consistency.pass.cpp | 7 ++++--- .../time/time.clock/time.clock.steady/consistency.pass.cpp | 7 ++++--- .../time/time.clock/time.clock.system/consistency.pass.cpp | 7 ++++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp index 2f8a707bf..47a610f00 100644 --- a/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp +++ b/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp @@ -12,9 +12,10 @@ // UNSUPPORTED: asan // Starting with C++17, Clock::is_steady is inlined (but not before LLVM-3.9!), -// but before C++17 it requires the symbol to be present in the dylib. -// XFAIL: availability=macosx10.7 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0) -// XFAIL: availability=macosx10.8 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0) +// but before C++17 it requires the symbol to be present in the dylib, which +// is only shipped starting with macosx10.9. +// XFAIL: with_system_cxx_lib=macosx10.7 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0) +// XFAIL: with_system_cxx_lib=macosx10.8 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0) // diff --git a/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp index 4458d6f21..e5e6de260 100644 --- a/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp +++ b/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp @@ -14,9 +14,10 @@ // UNSUPPORTED: asan // Starting with C++17, Clock::is_steady is inlined (but not before LLVM-3.9!), -// but before C++17 it requires the symbol to be present in the dylib. -// XFAIL: availability=macosx10.7 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0) -// XFAIL: availability=macosx10.8 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0) +// but before C++17 it requires the symbol to be present in the dylib, which +// is only shipped starting with macosx10.9. +// XFAIL: with_system_cxx_lib=macosx10.7 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0) +// XFAIL: with_system_cxx_lib=macosx10.8 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0) // diff --git a/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp index deb4615fa..c5ecb3227 100644 --- a/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp +++ b/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp @@ -12,9 +12,10 @@ // UNSUPPORTED: asan // Starting with C++17, Clock::is_steady is inlined (but not before LLVM-3.9!), -// but before C++17 it requires the symbol to be present in the dylib. -// XFAIL: availability=macosx10.7 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0) -// XFAIL: availability=macosx10.8 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0) +// but before C++17 it requires the symbol to be present in the dylib, which +// is only shipped starting with macosx10.9. +// XFAIL: with_system_cxx_lib=macosx10.7 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0) +// XFAIL: with_system_cxx_lib=macosx10.8 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0) // From 21e47d9ff848457a3e21a22eb187c304cee313d6 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Thu, 6 Dec 2018 20:09:15 +0000 Subject: [PATCH 07/94] [libcxx] Always convert 'use_system_cxx_lib' to an absolute path Otherwise, some tests would fail when a relative path was passed, because they'd use the relative path from a different directory than the current working directory. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348525 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/libcxx/test/config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/libcxx/test/config.py b/utils/libcxx/test/config.py index bdedd513c..25506852e 100644 --- a/utils/libcxx/test/config.py +++ b/utils/libcxx/test/config.py @@ -307,6 +307,7 @@ class Configuration(object): self.use_system_cxx_lib = False elif self.use_system_cxx_lib: assert os.path.isdir(self.use_system_cxx_lib), "the specified use_system_cxx_lib parameter (%s) is not a valid directory" % self.use_system_cxx_lib + self.use_system_cxx_lib = os.path.abspath(self.use_system_cxx_lib) self.lit_config.note( "inferred use_system_cxx_lib as: %r" % self.use_system_cxx_lib) From 5fe0a6a0bc22bd48d4d90f4b45fc26098a742347 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Thu, 6 Dec 2018 21:46:17 +0000 Subject: [PATCH 08/94] [libc++] Improve diagnostics for non-const comparators and hashers in associative containers Summary: When providing a non-const-callable comparator in a map or set, the warning diagnostic does not include the point of instantiation of the container that triggered the warning, which makes it difficult to track down the problem. This commit improves the diagnostic by placing it directly in the body of the associative container. The same change is applied to unordered associative containers, which had a similar problem. Finally, this commit cleans up the forward declarations of several map and unordered_map helpers, which are not needed anymore. Reviewers: EricWF, mclow.lists Subscribers: christof, dexonsmith, llvm-commits Differential Revision: https://reviews.llvm.org/D48955 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348529 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/UsingLibcxx.rst | 6 +- include/__hash_table | 60 +++++++------------ include/__tree | 30 ++-------- include/map | 5 +- include/set | 2 + include/unordered_map | 8 ++- include/unordered_set | 2 + .../associative/non_const_comparator.fail.cpp | 3 +- .../unord/non_const_comparator.fail.cpp | 8 ++- 9 files changed, 52 insertions(+), 72 deletions(-) diff --git a/docs/UsingLibcxx.rst b/docs/UsingLibcxx.rst index 41f410684..899656cca 100644 --- a/docs/UsingLibcxx.rst +++ b/docs/UsingLibcxx.rst @@ -203,8 +203,10 @@ thread safety annotations. This macro disables the additional diagnostics generated by libc++ using the `diagnose_if` attribute. These additional diagnostics include checks for: - * Giving `set`, `map`, `multiset`, `multimap` a comparator which is not - const callable. + * Giving `set`, `map`, `multiset`, `multimap` and their `unordered_` + counterparts a comparator which is not const callable. + * Giving an unordered associative container a hasher that is not const + callable. **_LIBCPP_NO_VCRUNTIME**: Microsoft's C and C++ headers are fairly entangled, and some of their C++ diff --git a/include/__hash_table b/include/__hash_table index 69ed8dd8b..6f5b18310 100644 --- a/include/__hash_table +++ b/include/__hash_table @@ -35,15 +35,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD template struct __hash_value_type; -template ::value && !__libcpp_is_final<_Hash>::value> -class __unordered_map_hasher; - -template ::value && !__libcpp_is_final<_Pred>::value - > -class __unordered_map_equal; - #ifndef _LIBCPP_CXX03_LANG template struct __is_hash_value_type_imp : false_type {}; @@ -418,7 +409,7 @@ public: _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT : __node_(__x.__node_) { @@ -871,35 +862,32 @@ struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc> }; #endif +template +struct __enforce_unordered_container_requirements { #ifndef _LIBCPP_CXX03_LANG -template -struct __diagnose_hash_table_helper { - static constexpr bool __trigger_diagnostics() - _LIBCPP_DIAGNOSE_WARNING(__check_hash_requirements<_Key, _Hash>::value - && !__invokable<_Hash const&, _Key const&>::value, - "the specified hash functor does not provide a const call operator") - _LIBCPP_DIAGNOSE_WARNING(is_copy_constructible<_Equal>::value - && !__invokable<_Equal const&, _Key const&, _Key const&>::value, - "the specified comparator type does not provide a const call operator") - { static_assert(__check_hash_requirements<_Key, _Hash>::value, - "the specified hash does not meet the Hash requirements"); + "the specified hash does not meet the Hash requirements"); static_assert(is_copy_constructible<_Equal>::value, - "the specified comparator is required to be copy constructible"); - return true; - } + "the specified comparator is required to be copy constructible"); +#endif + typedef int type; }; -template -struct __diagnose_hash_table_helper< - __hash_value_type<_Key, _Value>, - __unordered_map_hasher<_Key, __hash_value_type<_Key, _Value>, _Hash>, - __unordered_map_equal<_Key, __hash_value_type<_Key, _Value>, _Equal>, - _Alloc> -: __diagnose_hash_table_helper<_Key, _Hash, _Equal, _Alloc> -{ -}; -#endif // _LIBCPP_CXX03_LANG +template +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value, + "the specified comparator type does not provide a const call operator") + _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value, + "the specified hash functor does not provide a const call operator") +#endif +typename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type +__diagnose_unordered_container_requirements(int); + +// This dummy overload is used so that the compiler won't emit a spurious +// "no matching function for call to __diagnose_unordered_xxx" diagnostic +// when the overload above causes a hard error. +template +int __diagnose_unordered_container_requirements(void*); template class __hash_table @@ -963,10 +951,6 @@ private: typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits; typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; -#ifndef _LIBCPP_CXX03_LANG - static_assert(__diagnose_hash_table_helper<_Tp, _Hash, _Equal, _Alloc>::__trigger_diagnostics(), ""); -#endif - // --- Member data begin --- __bucket_list __bucket_list_; __compressed_pair<__first_node, __node_allocator> __p1_; diff --git a/include/__tree b/include/__tree index aa7370bfb..814851085 100644 --- a/include/__tree +++ b/include/__tree @@ -40,10 +40,6 @@ template class __tree_node; template struct __value_type; -template ::value && !__libcpp_is_final<_Compare>::value> -class __map_value_compare; - template class __map_node_destructor; template class _LIBCPP_TEMPLATE_VIS __map_iterator; template class _LIBCPP_TEMPLATE_VIS __map_const_iterator; @@ -966,24 +962,12 @@ private: }; +template #ifndef _LIBCPP_CXX03_LANG -template -struct __diagnose_tree_helper { - static constexpr bool __trigger_diagnostics() - _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Compare const&, _Tp const&, _Tp const&>::value, - "the specified comparator type does not provide a const call operator") - { return true; } -}; - -template -struct __diagnose_tree_helper< - __value_type<_Key, _Value>, - __map_value_compare<_Key, __value_type<_Key, _Value>, _KeyComp>, - _Alloc -> : __diagnose_tree_helper<_Key, _KeyComp, _Alloc> -{ -}; -#endif // !_LIBCPP_CXX03_LANG + _LIBCPP_DIAGNOSE_WARNING(!std::__invokable<_Compare const&, _Tp const&, _Tp const&>::value, + "the specified comparator type does not provide a const call operator") +#endif +int __diagnose_non_const_comparator(); template class __tree @@ -1855,10 +1839,6 @@ __tree<_Tp, _Compare, _Allocator>::~__tree() { static_assert((is_copy_constructible::value), "Comparator must be copy-constructible."); -#ifndef _LIBCPP_CXX03_LANG - static_assert((__diagnose_tree_helper<_Tp, _Compare, _Allocator>:: - __trigger_diagnostics()), ""); -#endif destroy(__root()); } diff --git a/include/map b/include/map index d3c59f3c5..f6f2b6835 100644 --- a/include/map +++ b/include/map @@ -486,7 +486,8 @@ swap(multimap& x, _LIBCPP_BEGIN_NAMESPACE_STD -template +template ::value && !__libcpp_is_final<_Compare>::value> class __map_value_compare : private _Compare { @@ -900,6 +901,7 @@ public: typedef value_type& reference; typedef const value_type& const_reference; + static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); static_assert((is_same::value), "Allocator::value_type must be same type as value_type"); @@ -1626,6 +1628,7 @@ public: typedef value_type& reference; typedef const value_type& const_reference; + static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); static_assert((is_same::value), "Allocator::value_type must be same type as value_type"); diff --git a/include/set b/include/set index ccf785ab1..fb15ecfa0 100644 --- a/include/set +++ b/include/set @@ -445,6 +445,7 @@ public: typedef value_type& reference; typedef const value_type& const_reference; + static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); static_assert((is_same::value), "Allocator::value_type must be same type as value_type"); @@ -925,6 +926,7 @@ public: typedef value_type& reference; typedef const value_type& const_reference; + static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); static_assert((is_same::value), "Allocator::value_type must be same type as value_type"); diff --git a/include/unordered_map b/include/unordered_map index 6f60749c9..5dd923607 100644 --- a/include/unordered_map +++ b/include/unordered_map @@ -414,7 +414,8 @@ template _LIBCPP_BEGIN_NAMESPACE_STD -template +template ::value && !__libcpp_is_final<_Hash>::value> class __unordered_map_hasher : private _Hash { @@ -482,7 +483,8 @@ swap(__unordered_map_hasher<_Key, _Cp, _Hash, __b>& __x, __x.swap(__y); } -template +template ::value && !__libcpp_is_final<_Pred>::value> class __unordered_map_equal : private _Pred { @@ -845,6 +847,7 @@ public: typedef const value_type& const_reference; static_assert((is_same::value), "Invalid allocator::value_type"); + static_assert(sizeof(__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), ""); private: typedef __hash_value_type __value_type; @@ -1667,6 +1670,7 @@ public: typedef const value_type& const_reference; static_assert((is_same::value), "Invalid allocator::value_type"); + static_assert(sizeof(__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), ""); private: typedef __hash_value_type __value_type; diff --git a/include/unordered_set b/include/unordered_set index de23ca2a3..25b92203f 100644 --- a/include/unordered_set +++ b/include/unordered_set @@ -384,6 +384,7 @@ public: typedef const value_type& const_reference; static_assert((is_same::value), "Invalid allocator::value_type"); + static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), ""); private: typedef __hash_table __table; @@ -976,6 +977,7 @@ public: typedef const value_type& const_reference; static_assert((is_same::value), "Invalid allocator::value_type"); + static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), ""); private: typedef __hash_table __table; diff --git a/test/libcxx/containers/associative/non_const_comparator.fail.cpp b/test/libcxx/containers/associative/non_const_comparator.fail.cpp index ea0d9ac09..ddd796089 100644 --- a/test/libcxx/containers/associative/non_const_comparator.fail.cpp +++ b/test/libcxx/containers/associative/non_const_comparator.fail.cpp @@ -27,7 +27,8 @@ int main() { static_assert(!std::__invokable::value, ""); static_assert(std::__invokable::value, ""); - // expected-warning@__tree:* 4 {{the specified comparator type does not provide a const call operator}} + // expected-warning@set:* 2 {{the specified comparator type does not provide a const call operator}} + // expected-warning@map:* 2 {{the specified comparator type does not provide a const call operator}} { using C = std::set; C s; diff --git a/test/libcxx/containers/unord/non_const_comparator.fail.cpp b/test/libcxx/containers/unord/non_const_comparator.fail.cpp index 8adc67589..f428ab9ac 100644 --- a/test/libcxx/containers/unord/non_const_comparator.fail.cpp +++ b/test/libcxx/containers/unord/non_const_comparator.fail.cpp @@ -11,7 +11,7 @@ // REQUIRES: diagnose-if-support, verify-support // Test that libc++ generates a warning diagnostic when the container is -// provided a non-const callable comparator. +// provided a non-const callable comparator or a non-const hasher. #include #include @@ -34,8 +34,10 @@ int main() { static_assert(!std::__invokable::value, ""); static_assert(std::__invokable::value, ""); - // expected-warning@__hash_table:* 4 {{the specified comparator type does not provide a const call operator}} - // expected-warning@__hash_table:* 4 {{the specified hash functor does not provide a const call operator}} + // expected-warning@unordered_set:* 2 {{the specified comparator type does not provide a const call operator}} + // expected-warning@unordered_map:* 2 {{the specified comparator type does not provide a const call operator}} + // expected-warning@unordered_set:* 2 {{the specified hash functor does not provide a const call operator}} + // expected-warning@unordered_map:* 2 {{the specified hash functor does not provide a const call operator}} { using C = std::unordered_set; From a796feb20d597bd2e7200aeef6013aca2a033383 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Fri, 7 Dec 2018 16:42:28 +0000 Subject: [PATCH 09/94] [libcxx] Add paranoid cast-to-void in comma operator git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348611 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/memory | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/memory b/include/memory index 9fca9fe41..3e8f5936e 100644 --- a/include/memory +++ b/include/memory @@ -1613,7 +1613,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits void __construct_forward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) { - for (; __begin1 != __end1; ++__begin1, ++__begin2) + for (; __begin1 != __end1; ++__begin1, (void) ++__begin2) construct(__a, _VSTD::__to_raw_pointer(__begin2), _VSTD::move_if_noexcept(*__begin1)); } From f01e82fd42de0ddf3104b219c6788259994b098a Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Fri, 7 Dec 2018 21:48:39 +0000 Subject: [PATCH 10/94] [libcxx] Remove the availability_markup LIT feature It is now equivalent to the 'availability' LIT feature, so there's no reason to keep both. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348653 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/DesignDocs/AvailabilityMarkup.rst | 29 +++++-------------- ...zed_delete_array_fsizeddeallocation.sh.cpp | 10 +++---- .../sized_delete_fsizeddeallocation.sh.cpp | 10 +++---- .../locale_char_pointer_cat.pass.cpp | 4 +-- .../locale.cons/locale_locale_cat.pass.cpp | 4 +-- .../locale.cons/locale_string_cat.pass.cpp | 4 +-- .../derive.pass.cpp | 14 ++++----- .../optional.specalg/make_optional.pass.cpp | 14 ++++----- .../variant.variant/variant.ctor/T.pass.cpp | 14 ++++----- .../in_place_index_init_list_args.pass.cpp | 14 ++++----- .../in_place_type_init_list_args.pass.cpp | 14 ++++----- utils/libcxx/test/config.py | 5 +--- 12 files changed, 60 insertions(+), 76 deletions(-) diff --git a/docs/DesignDocs/AvailabilityMarkup.rst b/docs/DesignDocs/AvailabilityMarkup.rst index 4ddef135f..4e6d80b50 100644 --- a/docs/DesignDocs/AvailabilityMarkup.rst +++ b/docs/DesignDocs/AvailabilityMarkup.rst @@ -55,7 +55,7 @@ or on a particular symbol: Testing ======= -Some parameters can be passed to lit to run the test-suite and exercising the +Some parameters can be passed to lit to run the test-suite and exercise the availability. * The `platform` parameter controls the deployment target. For example lit can @@ -69,8 +69,7 @@ availability. Tests can be marked as XFAIL based on multiple features made available by lit: -* if `use_system_cxx_lib` is passed to lit, assuming `--param=platform=macosx10.8` - is passed as well the following features will be available: +* if `--param=platform=macosx10.8` is passed, the following features will be available: - availability - availability=x86_64 @@ -82,8 +81,8 @@ Tests can be marked as XFAIL based on multiple features made available by lit: This feature is used to XFAIL a test that *is* using a class or a method marked as unavailable *and* that is expected to *fail* if deployed on an older system. -* if `use_system_cxx_lib` is passed to lit, the following features will also - be available: +* if `use_system_cxx_lib` and `--param=platform=macosx10.8` are passed to lit, + the following features will also be available: - with_system_cxx_lib - with_system_cxx_lib=x86_64 @@ -94,19 +93,7 @@ Tests can be marked as XFAIL based on multiple features made available by lit: This feature is used to XFAIL a test that is *not* using a class or a method marked as unavailable *but* that is expected to fail if deployed on an older - system. For example if we know that it exhibits a bug in the libc on a - particular system version. - -* if `with_availability` is passed to lit, the following features will also - be available: - - - availability_markup - - availability_markup=x86_64 - - availability_markup=macosx - - availability_markup=x86_64-macosx - - availability_markup=x86_64-apple-macosx10.8 - - availability_markup=macosx10.8 - - This feature is used to XFAIL a test that *is* using a class or a method - marked as unavailable *but* that is expected to *pass* if deployed on an older - system. For example if it is using a symbol in a statically evaluated context. + system. For example, if the test exhibits a bug in the libc on a particular + system version, or if the test uses a symbol that is not available on an + older version of the dylib (but for which there is no availability markup, + otherwise the XFAIL should use `availability` above). diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.sh.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.sh.cpp index e02c594c5..ab25a9be0 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.sh.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.sh.cpp @@ -13,11 +13,11 @@ // when sized deallocation is not supported, e.g., prior to C++14. // UNSUPPORTED: sanitizer-new-delete -// XFAIL: availability_markup=macosx10.11 -// XFAIL: availability_markup=macosx10.10 -// XFAIL: availability_markup=macosx10.9 -// XFAIL: availability_markup=macosx10.8 -// XFAIL: availability_markup=macosx10.7 +// XFAIL: availability=macosx10.11 +// XFAIL: availability=macosx10.10 +// XFAIL: availability=macosx10.9 +// XFAIL: availability=macosx10.8 +// XFAIL: availability=macosx10.7 // NOTE: Only clang-3.7 and GCC 5.1 and greater support -fsized-deallocation. diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp index 21ae88944..7d6f34845 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp @@ -13,11 +13,11 @@ // when sized deallocation is not supported, e.g., prior to C++14. // UNSUPPORTED: sanitizer-new-delete -// XFAIL: availability_markup=macosx10.11 -// XFAIL: availability_markup=macosx10.10 -// XFAIL: availability_markup=macosx10.9 -// XFAIL: availability_markup=macosx10.8 -// XFAIL: availability_markup=macosx10.7 +// XFAIL: availability=macosx10.11 +// XFAIL: availability=macosx10.10 +// XFAIL: availability=macosx10.9 +// XFAIL: availability=macosx10.8 +// XFAIL: availability=macosx10.7 // NOTE: Only clang-3.7 and GCC 5.1 and greater support -fsized-deallocation. // REQUIRES: -fsized-deallocation diff --git a/test/std/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp b/test/std/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp index e25fe3893..6a79d3943 100644 --- a/test/std/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp +++ b/test/std/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp @@ -11,8 +11,8 @@ // REQUIRES: locale.ru_RU.UTF-8 // UNSUPPORTED: sanitizer-new-delete -// XFAIL: availability_markup=macosx10.8 -// XFAIL: availability_markup=macosx10.7 +// XFAIL: availability=macosx10.8 +// XFAIL: availability=macosx10.7 // diff --git a/test/std/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp b/test/std/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp index 72d47a391..5bf6befed 100644 --- a/test/std/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp +++ b/test/std/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp @@ -11,8 +11,8 @@ // REQUIRES: locale.ru_RU.UTF-8 // UNSUPPORTED: sanitizer-new-delete -// XFAIL: availability_markup=macosx10.8 -// XFAIL: availability_markup=macosx10.7 +// XFAIL: availability=macosx10.8 +// XFAIL: availability=macosx10.7 // diff --git a/test/std/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp b/test/std/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp index 26ddfa600..946e8b530 100644 --- a/test/std/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp +++ b/test/std/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp @@ -11,8 +11,8 @@ // REQUIRES: locale.ru_RU.UTF-8 // UNSUPPORTED: sanitizer-new-delete -// XFAIL: availability_markup=macosx10.8 -// XFAIL: availability_markup=macosx10.7 +// XFAIL: availability=macosx10.8 +// XFAIL: availability=macosx10.7 // diff --git a/test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp b/test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp index cc1f7aead..930015a73 100644 --- a/test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp +++ b/test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp @@ -9,13 +9,13 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 -// XFAIL: availability_markup=macosx10.13 -// XFAIL: availability_markup=macosx10.12 -// XFAIL: availability_markup=macosx10.11 -// XFAIL: availability_markup=macosx10.10 -// XFAIL: availability_markup=macosx10.9 -// XFAIL: availability_markup=macosx10.8 -// XFAIL: availability_markup=macosx10.7 +// XFAIL: availability=macosx10.13 +// XFAIL: availability=macosx10.12 +// XFAIL: availability=macosx10.11 +// XFAIL: availability=macosx10.10 +// XFAIL: availability=macosx10.9 +// XFAIL: availability=macosx10.8 +// XFAIL: availability=macosx10.7 // diff --git a/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp b/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp index d09401fc1..421480aa8 100644 --- a/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp +++ b/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp @@ -10,13 +10,13 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 // -// XFAIL: availability_markup=macosx10.13 -// XFAIL: availability_markup=macosx10.12 -// XFAIL: availability_markup=macosx10.11 -// XFAIL: availability_markup=macosx10.10 -// XFAIL: availability_markup=macosx10.9 -// XFAIL: availability_markup=macosx10.8 -// XFAIL: availability_markup=macosx10.7 +// XFAIL: availability=macosx10.13 +// XFAIL: availability=macosx10.12 +// XFAIL: availability=macosx10.11 +// XFAIL: availability=macosx10.10 +// XFAIL: availability=macosx10.9 +// XFAIL: availability=macosx10.8 +// XFAIL: availability=macosx10.7 // template // constexpr optional> make_optional(T&& v); diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp index 0f9dbe982..d414c3503 100644 --- a/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp +++ b/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp @@ -12,13 +12,13 @@ // -// XFAIL: availability_markup=macosx10.13 -// XFAIL: availability_markup=macosx10.12 -// XFAIL: availability_markup=macosx10.11 -// XFAIL: availability_markup=macosx10.10 -// XFAIL: availability_markup=macosx10.9 -// XFAIL: availability_markup=macosx10.8 -// XFAIL: availability_markup=macosx10.7 +// XFAIL: availability=macosx10.13 +// XFAIL: availability=macosx10.12 +// XFAIL: availability=macosx10.11 +// XFAIL: availability=macosx10.10 +// XFAIL: availability=macosx10.9 +// XFAIL: availability=macosx10.8 +// XFAIL: availability=macosx10.7 // template class variant; diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp index 165ce098d..7dcd2541b 100644 --- a/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp +++ b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp @@ -12,13 +12,13 @@ // -// XFAIL: availability_markup=macosx10.13 -// XFAIL: availability_markup=macosx10.12 -// XFAIL: availability_markup=macosx10.11 -// XFAIL: availability_markup=macosx10.10 -// XFAIL: availability_markup=macosx10.9 -// XFAIL: availability_markup=macosx10.8 -// XFAIL: availability_markup=macosx10.7 +// XFAIL: availability=macosx10.13 +// XFAIL: availability=macosx10.12 +// XFAIL: availability=macosx10.11 +// XFAIL: availability=macosx10.10 +// XFAIL: availability=macosx10.9 +// XFAIL: availability=macosx10.8 +// XFAIL: availability=macosx10.7 // template class variant; diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_init_list_args.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_init_list_args.pass.cpp index cf948f2f1..7d632af9a 100644 --- a/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_init_list_args.pass.cpp +++ b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_init_list_args.pass.cpp @@ -12,13 +12,13 @@ // -// XFAIL: availability_markup=macosx10.13 -// XFAIL: availability_markup=macosx10.12 -// XFAIL: availability_markup=macosx10.11 -// XFAIL: availability_markup=macosx10.10 -// XFAIL: availability_markup=macosx10.9 -// XFAIL: availability_markup=macosx10.8 -// XFAIL: availability_markup=macosx10.7 +// XFAIL: availability=macosx10.13 +// XFAIL: availability=macosx10.12 +// XFAIL: availability=macosx10.11 +// XFAIL: availability=macosx10.10 +// XFAIL: availability=macosx10.9 +// XFAIL: availability=macosx10.8 +// XFAIL: availability=macosx10.7 // template class variant; diff --git a/utils/libcxx/test/config.py b/utils/libcxx/test/config.py index 25506852e..dbb250e93 100644 --- a/utils/libcxx/test/config.py +++ b/utils/libcxx/test/config.py @@ -407,11 +407,8 @@ class Configuration(object): if self.use_deployment: self.add_deployment_feature('with_system_cxx_lib') - # Configure the availability markup checks features. + # Configure the availability feature. if self.use_deployment: - self.config.available_features.add('availability_markup') - self.add_deployment_feature('availability_markup') - self.config.available_features.add('availability') self.add_deployment_feature('availability') From 49ad9aa8cb0b98d02154c53111a74ea13464a722 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Fri, 7 Dec 2018 22:16:26 +0000 Subject: [PATCH 11/94] Update a couple of vector tests that were testing libc++-specific bahavior. Thanks to Andrey Maksimov for the catch. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348660 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../vector.bool/construct_default.pass.cpp | 17 +++++++++++------ .../vector.bool/default_noexcept.pass.cpp | 6 ++++-- .../vector.cons/default_noexcept.pass.cpp | 4 ++-- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/test/std/containers/sequences/vector.bool/construct_default.pass.cpp b/test/std/containers/sequences/vector.bool/construct_default.pass.cpp index 0f51c219e..80bfce1ad 100644 --- a/test/std/containers/sequences/vector.bool/construct_default.pass.cpp +++ b/test/std/containers/sequences/vector.bool/construct_default.pass.cpp @@ -7,10 +7,15 @@ // //===----------------------------------------------------------------------===// -// // vector -// vector(const Alloc& = Alloc()); +// vector(); +// vector(const Alloc&); + +// This tests a conforming extension +// For vector<>, this was added to the standard by N4258, +// but vector was not changed. + #include #include @@ -24,9 +29,9 @@ void test0() { #if TEST_STD_VER > 14 - static_assert((noexcept(C{})), "" ); + LIBCPP_STATIC_ASSERT((noexcept(C{})), "" ); #elif TEST_STD_VER >= 11 - static_assert((noexcept(C()) == noexcept(typename C::allocator_type())), "" ); + LIBCPP_STATIC_ASSERT((noexcept(C()) == noexcept(typename C::allocator_type())), "" ); #endif C c; LIBCPP_ASSERT(c.__invariants()); @@ -45,9 +50,9 @@ void test1(const typename C::allocator_type& a) { #if TEST_STD_VER > 14 - static_assert((noexcept(C{typename C::allocator_type{}})), "" ); + LIBCPP_STATIC_ASSERT((noexcept(C{typename C::allocator_type{}})), "" ); #elif TEST_STD_VER >= 11 - static_assert((noexcept(C(typename C::allocator_type())) == std::is_nothrow_copy_constructible::value), "" ); + LIBCPP_STATIC_ASSERT((noexcept(C(typename C::allocator_type())) == std::is_nothrow_copy_constructible::value), "" ); #endif C c(a); LIBCPP_ASSERT(c.__invariants()); diff --git a/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp b/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp index 4e71df374..e2d94e225 100644 --- a/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp +++ b/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp @@ -6,6 +6,7 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 // @@ -13,8 +14,9 @@ // noexcept(is_nothrow_default_constructible::value); // This tests a conforming extension +// For vector<>, this was added to the standard by N4258, +// but vector was not changed. -// UNSUPPORTED: c++98, c++03 #include #include @@ -40,7 +42,6 @@ int main() typedef std::vector> C; static_assert(std::is_nothrow_default_constructible::value, ""); } -#endif // _LIBCPP_VERSION { typedef std::vector> C; static_assert(!std::is_nothrow_default_constructible::value, ""); @@ -49,4 +50,5 @@ int main() typedef std::vector> C; static_assert(!std::is_nothrow_default_constructible::value, ""); } +#endif // _LIBCPP_VERSION } diff --git a/test/std/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp b/test/std/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp index b244f75f2..f8c932a02 100644 --- a/test/std/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp @@ -6,15 +6,15 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 // // vector() // noexcept(is_nothrow_default_constructible::value); -// This tests a conforming extension +// This *was* a conforming extension, but it was adopted in N4258. -// UNSUPPORTED: c++98, c++03 #include #include From 5b3183215b1a30bcbb036d77e747f573767b9314 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Mon, 10 Dec 2018 18:14:09 +0000 Subject: [PATCH 12/94] Refactor std::function to more easily support alternative implementations. Patch from Jordan Soyke (jsoyke@google.com) Reviewed as D55520 This change adds a new internal class, called __value_func, that adds a minimal subset of value-type semantics to the internal __func interface. The change is NFC, and is cleanup for the upcoming ABI v2 function implementation (D55045). git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348778 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/functional | 510 +++++++++++++++++++++++++++------------------ 1 file changed, 310 insertions(+), 200 deletions(-) diff --git a/include/functional b/include/functional index 1bddb9fad..4ce3ffd81 100644 --- a/include/functional +++ b/include/functional @@ -1473,6 +1473,81 @@ bool __not_null(function<_Fp> const& __f) { return !!__f; } namespace __function { +// __alloc_func holds a functor and an allocator. + +template class __alloc_func; + +template +class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> +{ + __compressed_pair<_Fp, _Ap> __f_; + + public: + typedef _Fp _Target; + typedef _Ap _Alloc; + + _LIBCPP_INLINE_VISIBILITY + const _Target& __target() const { return __f_.first(); } + + _LIBCPP_INLINE_VISIBILITY + const _Alloc& __allocator() const { return __f_.second(); } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(_Target&& __f) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), + _VSTD::forward_as_tuple()) + { + } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(const _Target& __f, const _Alloc& __a) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), + _VSTD::forward_as_tuple(__a)) + { + } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(const _Target& __f, _Alloc&& __a) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), + _VSTD::forward_as_tuple(_VSTD::move(__a))) + { + } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(_Target&& __f, _Alloc&& __a) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), + _VSTD::forward_as_tuple(_VSTD::move(__a))) + { + } + + _LIBCPP_INLINE_VISIBILITY + _Rp operator()(_ArgTypes&&... __arg) + { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_.first(), + _VSTD::forward<_ArgTypes>(__arg)...); + } + + _LIBCPP_INLINE_VISIBILITY + __alloc_func* __clone() const + { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef + typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type + _AA; + _AA __a(__f_.second()); + typedef __allocator_destructor<_AA> _Dp; + unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a)); + return __hold.release(); + } + + _LIBCPP_INLINE_VISIBILITY + void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); } +}; + +// __base provides an abstract interface for copyable functors. + template class __base; template @@ -1494,37 +1569,37 @@ public: #endif // _LIBCPP_NO_RTTI }; +// __func implements __base for a given functor type. + template class __func; template class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> { - __compressed_pair<_Fp, _Alloc> __f_; + __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_; public: _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp&& __f) - : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), - _VSTD::forward_as_tuple()) {} + : __f_(_VSTD::move(__f)) {} + _LIBCPP_INLINE_VISIBILITY explicit __func(const _Fp& __f, const _Alloc& __a) - : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), - _VSTD::forward_as_tuple(__a)) {} + : __f_(__f, __a) {} _LIBCPP_INLINE_VISIBILITY explicit __func(const _Fp& __f, _Alloc&& __a) - : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), - _VSTD::forward_as_tuple(_VSTD::move(__a))) {} + : __f_(__f, _VSTD::move(__a)) {} _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp&& __f, _Alloc&& __a) - : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), - _VSTD::forward_as_tuple(_VSTD::move(__a))) {} + : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} + virtual __base<_Rp(_ArgTypes...)>* __clone() const; virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; virtual void destroy() _NOEXCEPT; virtual void destroy_deallocate() _NOEXCEPT; - virtual _Rp operator()(_ArgTypes&& ... __arg); + virtual _Rp operator()(_ArgTypes&&... __arg); #ifndef _LIBCPP_NO_RTTI virtual const void* target(const type_info&) const _NOEXCEPT; virtual const std::type_info& target_type() const _NOEXCEPT; @@ -1537,10 +1612,10 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); + _Ap __a(__f_.__allocator()); typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); + ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a)); return __hold.release(); } @@ -1548,14 +1623,14 @@ template void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const { - ::new (__p) __func(__f_.first(), __f_.second()); + ::new (__p) __func(__f_.__target(), __f_.__allocator()); } template void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT { - __f_.~__compressed_pair<_Fp, _Alloc>(); + __f_.destroy(); } template @@ -1564,8 +1639,8 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - __f_.~__compressed_pair<_Fp, _Alloc>(); + _Ap __a(__f_.__allocator()); + __f_.destroy(); __a.deallocate(this, 1); } @@ -1573,8 +1648,7 @@ template _Rp __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) { - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...); + return __f_(_VSTD::forward<_ArgTypes>(__arg)...); } #ifndef _LIBCPP_NO_RTTI @@ -1584,7 +1658,7 @@ const void* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT { if (__ti == typeid(_Fp)) - return &__f_.first(); + return &__f_.__target(); return (const void*)0; } @@ -1597,6 +1671,194 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT #endif // _LIBCPP_NO_RTTI +// __value_func creates a value-type from a __func. + +template class __value_func; + +template class __value_func<_Rp(_ArgTypes...)> +{ + typename aligned_storage<3 * sizeof(void*)>::type __buf_; + + typedef __base<_Rp(_ArgTypes...)> __func; + __func* __f_; + + _LIBCPP_NO_CFI static __func* __as_base(void* p) + { + return reinterpret_cast<__func*>(p); + } + + public: + _LIBCPP_INLINE_VISIBILITY + __value_func() _NOEXCEPT : __f_(0) {} + + template + _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc __a) + : __f_(0) + { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; + typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type + _FunAlloc; + + if (__function::__not_null(__f)) + { + _FunAlloc __af(__a); + if (sizeof(_Fun) <= sizeof(__buf_) && + is_nothrow_copy_constructible<_Fp>::value && + is_nothrow_copy_constructible<_FunAlloc>::value) + { + __f_ = + ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af)); + } + else + { + typedef __allocator_destructor<_FunAlloc> _Dp; + unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); + ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a)); + __f_ = __hold.release(); + } + } + } + + _LIBCPP_INLINE_VISIBILITY + __value_func(const __value_func& __f) + { + if (__f.__f_ == 0) + __f_ = 0; + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); + } + + _LIBCPP_INLINE_VISIBILITY + __value_func(__value_func&& __f) _NOEXCEPT + { + if (__f.__f_ == 0) + __f_ = 0; + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } + else + { + __f_ = __f.__f_; + __f.__f_ = 0; + } + } + + _LIBCPP_INLINE_VISIBILITY + ~__value_func() + { + if ((void*)__f_ == &__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); + } + + _LIBCPP_INLINE_VISIBILITY + __value_func& operator=(__value_func&& __f) + { + *this = nullptr; + if (__f.__f_ == 0) + __f_ = 0; + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } + else + { + __f_ = __f.__f_; + __f.__f_ = 0; + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __value_func& operator=(nullptr_t) + { + __func* __f = __f_; + __f_ = 0; + if ((void*)__f == &__buf_) + __f->destroy(); + else if (__f) + __f->destroy_deallocate(); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + _Rp operator()(_ArgTypes&&... __args) const + { + if (__f_ == 0) + __throw_bad_function_call(); + return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...); + } + + _LIBCPP_INLINE_VISIBILITY + void swap(__value_func& __f) _NOEXCEPT + { + if (&__f == this) + return; + if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) + { + typename aligned_storage::type __tempbuf; + __func* __t = __as_base(&__tempbuf); + __f_->__clone(__t); + __f_->destroy(); + __f_ = 0; + __f.__f_->__clone(__as_base(&__buf_)); + __f.__f_->destroy(); + __f.__f_ = 0; + __f_ = __as_base(&__buf_); + __t->__clone(__as_base(&__f.__buf_)); + __t->destroy(); + __f.__f_ = __as_base(&__f.__buf_); + } + else if ((void*)__f_ == &__buf_) + { + __f_->__clone(__as_base(&__f.__buf_)); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = __as_base(&__f.__buf_); + } + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f.__f_->__clone(__as_base(&__buf_)); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = __as_base(&__buf_); + } + else + _VSTD::swap(__f_, __f.__f_); + } + + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT { return __f_ != 0; } + +#ifndef _LIBCPP_NO_RTTI + _LIBCPP_INLINE_VISIBILITY + const std::type_info& target_type() const _NOEXCEPT + { + if (__f_ == 0) + return typeid(void); + return __f_->target_type(); + } + + template + _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT + { + if (__f_ == 0) + return 0; + return (const _Tp*)__f_->target(typeid(_Tp)); + } +#endif // _LIBCPP_NO_RTTI +}; + } // __function template @@ -1604,13 +1866,9 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> { - typedef __function::__base<_Rp(_ArgTypes...)> __base; - typename aligned_storage<3*sizeof(void*)>::type __buf_; - __base* __f_; + typedef __function::__value_func<_Rp(_ArgTypes...)> __func; - _LIBCPP_NO_CFI static __base *__as_base(void *p) { - return reinterpret_cast<__base*>(p); - } + __func __f_; template , function>::value>, @@ -1637,9 +1895,9 @@ public: // construct/copy/destroy: _LIBCPP_INLINE_VISIBILITY - function() _NOEXCEPT : __f_(0) {} + function() _NOEXCEPT { } _LIBCPP_INLINE_VISIBILITY - function(nullptr_t) _NOEXCEPT : __f_(0) {} + function(nullptr_t) _NOEXCEPT {} function(const function&); function(function&&) _NOEXCEPT; template> @@ -1648,10 +1906,10 @@ public: #if _LIBCPP_STD_VER <= 14 template _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&) _NOEXCEPT : __f_(0) {} + function(allocator_arg_t, const _Alloc&) _NOEXCEPT {} template _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT : __f_(0) {} + function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} template function(allocator_arg_t, const _Alloc&, const function&); template @@ -1680,7 +1938,9 @@ public: // function capacity: _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return __f_;} + _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT { + return static_cast(__f_); + } // deleted overloads close possible hole in the type system template @@ -1700,125 +1960,38 @@ public: }; template -function<_Rp(_ArgTypes...)>::function(const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if ((void *)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} +function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {} #if _LIBCPP_STD_VER <= 14 template template function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, - const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if ((void *)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} + const function& __f) : __f_(__f.__f_) {} #endif -template +template function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT -{ - if (__f.__f_ == 0) - __f_ = 0; - else if ((void *)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - { - __f_ = __f.__f_; - __f.__f_ = 0; - } -} + : __f_(_VSTD::move(__f.__f_)) {} #if _LIBCPP_STD_VER <= 14 template template function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, - function&& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if ((void *)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - { - __f_ = __f.__f_; - __f.__f_ = 0; - } -} + function&& __f) + : __f_(_VSTD::move(__f.__f_)) {} #endif -template +template template function<_Rp(_ArgTypes...)>::function(_Fp __f) - : __f_(0) -{ - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_ArgTypes...)> _FF; - if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value) - { - __f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__f)); - } - else - { - typedef allocator<_FF> _Ap; - _Ap __a; - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) _FF(_VSTD::move(__f), allocator<_Fp>(__a)); - __f_ = __hold.release(); - } - } -} + : __f_(_VSTD::move(__f), allocator<_Fp>()) {} #if _LIBCPP_STD_VER <= 14 -template +template template -function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f) - : __f_(0) -{ - typedef allocator_traits<_Alloc> __alloc_traits; - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _FF; - typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; - _Ap __a(__a0); - if (sizeof(_FF) <= sizeof(__buf_) && - is_nothrow_copy_constructible<_Fp>::value && is_nothrow_copy_constructible<_Ap>::value) - { - __f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__f), _Alloc(__a)); - } - else - { - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) _FF(_VSTD::move(__f), _Alloc(__a)); - __f_ = __hold.release(); - } - } -} +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, + _Fp __f) + : __f_(_VSTD::move(__f), __a) {} #endif template @@ -1833,19 +2006,7 @@ template function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT { - *this = nullptr; - if (__f.__f_ == 0) - __f_ = 0; - else if ((void *)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - { - __f_ = __f.__f_; - __f.__f_ = 0; - } + __f_ = std::move(__f.__f_); return *this; } @@ -1853,12 +2014,7 @@ template function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT { - __base* __t = __f_; - __f_ = 0; - if ((void *)__t == &__buf_) - __t->destroy(); - else if (__t) - __t->destroy_deallocate(); + __f_ = nullptr; return *this; } @@ -1872,60 +2028,20 @@ function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) } template -function<_Rp(_ArgTypes...)>::~function() -{ - if ((void *)__f_ == &__buf_) - __f_->destroy(); - else if (__f_) - __f_->destroy_deallocate(); -} +function<_Rp(_ArgTypes...)>::~function() {} template void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT { - if (_VSTD::addressof(__f) == this) - return; - if ((void *)__f_ == &__buf_ && (void *)__f.__f_ == &__f.__buf_) - { - typename aligned_storage::type __tempbuf; - __base* __t = __as_base(&__tempbuf); - __f_->__clone(__t); - __f_->destroy(); - __f_ = 0; - __f.__f_->__clone(__as_base(&__buf_)); - __f.__f_->destroy(); - __f.__f_ = 0; - __f_ = __as_base(&__buf_); - __t->__clone(__as_base(&__f.__buf_)); - __t->destroy(); - __f.__f_ = __as_base(&__f.__buf_); - } - else if ((void *)__f_ == &__buf_) - { - __f_->__clone(__as_base(&__f.__buf_)); - __f_->destroy(); - __f_ = __f.__f_; - __f.__f_ = __as_base(&__f.__buf_); - } - else if ((void *)__f.__f_ == &__f.__buf_) - { - __f.__f_->__clone(__as_base(&__buf_)); - __f.__f_->destroy(); - __f.__f_ = __f_; - __f_ = __as_base(&__buf_); - } - else - _VSTD::swap(__f_, __f.__f_); + __f_.swap(__f.__f_); } template _Rp function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const { - if (__f_ == 0) - __throw_bad_function_call(); - return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...); + return __f_(_VSTD::forward<_ArgTypes>(__arg)...); } #ifndef _LIBCPP_NO_RTTI @@ -1934,9 +2050,7 @@ template const std::type_info& function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT { - if (__f_ == 0) - return typeid(void); - return __f_->target_type(); + return __f_.target_type(); } template @@ -1944,9 +2058,7 @@ template _Tp* function<_Rp(_ArgTypes...)>::target() _NOEXCEPT { - if (__f_ == 0) - return nullptr; - return (_Tp*) const_cast(__f_->target(typeid(_Tp))); + return (_Tp*)(__f_.template target<_Tp>()); } template @@ -1954,9 +2066,7 @@ template const _Tp* function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT { - if (__f_ == 0) - return nullptr; - return (const _Tp*)__f_->target(typeid(_Tp)); + return __f_.template target<_Tp>(); } #endif // _LIBCPP_NO_RTTI From c1935f105d483f67eb011e60a253aae503d70eee Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Tue, 11 Dec 2018 00:14:34 +0000 Subject: [PATCH 13/94] Add a version of std::function that includes a few optimizations in ABI V2. Patch by Jordan Soyke (jsoyke@google.com) Reviewed as D55045 The result of running the benchmarks and comparing them can be found here: https://gist.github.com/EricWF/a77fd42ec87fc98da8039e26d0349498 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348812 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/__config | 2 + include/functional | 303 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 305 insertions(+) diff --git a/include/__config b/include/__config index a99fd16b9..b4367d0d3 100644 --- a/include/__config +++ b/include/__config @@ -95,6 +95,8 @@ // Use the smallest possible integer type to represent the index of the variant. // Previously libc++ used "unsigned int" exclusivly. # define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION +// Unstable attempt to provide a more optimized std::function +# define _LIBCPP_ABI_OPTIMIZED_FUNCTION #elif _LIBCPP_ABI_VERSION == 1 # if !defined(_LIBCPP_OBJECT_FORMAT_COFF) // Enable compiling copies of now inline methods into the dylib to support diff --git a/include/functional b/include/functional index 4ce3ffd81..bf3216f41 100644 --- a/include/functional +++ b/include/functional @@ -1859,6 +1859,305 @@ template class __value_func<_Rp(_ArgTypes...)> #endif // _LIBCPP_NO_RTTI }; +// Storage for a functor object, to be used with __policy to manage copy and +// destruction. +union __policy_storage +{ + mutable char __small[sizeof(void*) * 2]; + void* __large; +}; + +// True if _Fun can safely be held in __policy_storage.__small. +template +struct __use_small_storage + : public _VSTD::integral_constant< + bool, sizeof(_Fun) <= sizeof(__policy_storage) && + alignof(_Fun) <= alignof(__policy_storage) && + _VSTD::is_trivially_copy_constructible<_Fun>::value && + _VSTD::is_trivially_destructible<_Fun>::value> {}; + +// Policy contains information about how to copy, destroy, and move the +// underlying functor. You can think of it as a vtable of sorts. +struct __policy +{ + // Used to copy or destroy __large values. null for trivial objects. + void* (*const __clone)(const void*); + void (*const __destroy)(void*); + + // True if this is the null policy (no value). + const bool __is_null; + + // The target type. May be null if RTTI is disabled. + const std::type_info* const __type_info; + + // Returns a pointer to a static policy object suitable for the functor + // type. + template + _LIBCPP_INLINE_VISIBILITY static const __policy* __create() + { + return __choose_policy<_Fun>(__use_small_storage<_Fun>()); + } + + _LIBCPP_INLINE_VISIBILITY + static const __policy* __create_empty() + { + static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr, + true, +#ifndef _LIBCPP_NO_RTTI + &typeid(void) +#else + nullptr +#endif + }; + return &__policy_; + } + + private: + template static void* __large_clone(const void* __s) + { + const _Fun* __f = static_cast(__s); + return __f->__clone(); + } + + template static void __large_destroy(void* __s) + { + typedef allocator_traits __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type + _FunAlloc; + _Fun* __f = static_cast<_Fun*>(__s); + _FunAlloc __a(__f->__allocator()); + __f->destroy(); + __a.deallocate(__f, 1); + } + + template + _LIBCPP_INLINE_VISIBILITY static const __policy* + __choose_policy(/* is_small = */ false_type) + { + static const _LIBCPP_CONSTEXPR __policy __policy_ = { + &__large_clone<_Fun>, &__large_destroy<_Fun>, false, +#ifndef _LIBCPP_NO_RTTI + &typeid(typename _Fun::_Target) +#else + nullptr +#endif + }; + return &__policy_; + } + + template + _LIBCPP_INLINE_VISIBILITY static const __policy* + __choose_policy(/* is_small = */ true_type) + { + static const _LIBCPP_CONSTEXPR __policy __policy_ = { + nullptr, nullptr, false, +#ifndef _LIBCPP_NO_RTTI + &typeid(typename _Fun::_Target) +#else + nullptr +#endif + }; + return &__policy_; + } +}; + +// Used to choose between perfect forwarding or pass-by-value. Pass-by-value is +// faster for types that can be passed in registers. +template +using __fast_forward = + typename _VSTD::conditional<_VSTD::is_scalar<_Tp>::value, _Tp, _Tp&&>::type; + +// __policy_invoker calls an instance of __alloc_func held in __policy_storage. + +template struct __policy_invoker; + +template +struct __policy_invoker<_Rp(_ArgTypes...)> +{ + typedef _Rp (*__Call)(const __policy_storage*, + __fast_forward<_ArgTypes>...); + + __Call __call_; + + // Creates an invoker that throws bad_function_call. + _LIBCPP_INLINE_VISIBILITY + __policy_invoker() : __call_(&__call_empty) {} + + // Creates an invoker that calls the given instance of __func. + template + _LIBCPP_INLINE_VISIBILITY static __policy_invoker __create() + { + return __policy_invoker(&__call_impl<_Fun>); + } + + private: + _LIBCPP_INLINE_VISIBILITY + explicit __policy_invoker(__Call __c) : __call_(__c) {} + + static _Rp __call_empty(const __policy_storage*, + __fast_forward<_ArgTypes>...) + { + __throw_bad_function_call(); + } + + template + static _Rp __call_impl(const __policy_storage* __buf, + __fast_forward<_ArgTypes>... __args) + { + _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value + ? &__buf->__small + : __buf->__large); + return (*__f)(_VSTD::forward<_ArgTypes>(__args)...); + } +}; + +// __policy_func uses a __policy and __policy_invoker to create a type-erased, +// copyable functor. + +template class __policy_func; + +template class __policy_func<_Rp(_ArgTypes...)> +{ + // Inline storage for small objects. + __policy_storage __buf_; + + // Calls the value stored in __buf_. This could technically be part of + // policy, but storing it here eliminates a level of indirection inside + // operator(). + typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker; + __invoker __invoker_; + + // The policy that describes how to move / copy / destroy __buf_. Never + // null, even if the function is empty. + const __policy* __policy_; + + public: + _LIBCPP_INLINE_VISIBILITY + __policy_func() : __policy_(__policy::__create_empty()) {} + + template + _LIBCPP_INLINE_VISIBILITY __policy_func(_Fp&& __f, const _Alloc& __a) + : __policy_(__policy::__create_empty()) + { + typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type + _FunAlloc; + + if (__function::__not_null(__f)) + { + __invoker_ = __invoker::template __create<_Fun>(); + __policy_ = __policy::__create<_Fun>(); + + _FunAlloc __af(__a); + if (__use_small_storage<_Fun>()) + { + ::new ((void*)&__buf_.__small) + _Fun(_VSTD::move(__f), _Alloc(__af)); + } + else + { + typedef __allocator_destructor<_FunAlloc> _Dp; + unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); + ::new ((void*)__hold.get()) + _Fun(_VSTD::move(__f), _Alloc(__af)); + __buf_.__large = __hold.release(); + } + } + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func(const __policy_func& __f) + : __buf_(__f.__buf_), __invoker_(__f.__invoker_), + __policy_(__f.__policy_) + { + if (__policy_->__clone) + __buf_.__large = __policy_->__clone(__f.__buf_.__large); + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func(__policy_func&& __f) + : __buf_(__f.__buf_), __invoker_(__f.__invoker_), + __policy_(__f.__policy_) + { + if (__policy_->__destroy) + { + __f.__policy_ = __policy::__create_empty(); + __f.__invoker_ = __invoker(); + } + } + + _LIBCPP_INLINE_VISIBILITY + ~__policy_func() + { + if (__policy_->__destroy) + __policy_->__destroy(__buf_.__large); + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func& operator=(__policy_func&& __f) + { + *this = nullptr; + __buf_ = __f.__buf_; + __invoker_ = __f.__invoker_; + __policy_ = __f.__policy_; + __f.__policy_ = __policy::__create_empty(); + __f.__invoker_ = __invoker(); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func& operator=(nullptr_t) + { + const __policy* __p = __policy_; + __policy_ = __policy::__create_empty(); + __invoker_ = __invoker(); + if (__p->__destroy) + __p->__destroy(__buf_.__large); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + _Rp operator()(_ArgTypes&&... __args) const + { + return __invoker_.__call_(_VSTD::addressof(__buf_), + _VSTD::forward<_ArgTypes>(__args)...); + } + + _LIBCPP_INLINE_VISIBILITY + void swap(__policy_func& __f) + { + _VSTD::swap(__invoker_, __f.__invoker_); + _VSTD::swap(__policy_, __f.__policy_); + _VSTD::swap(__buf_, __f.__buf_); + } + + _LIBCPP_INLINE_VISIBILITY + explicit operator bool() const _NOEXCEPT + { + return !__policy_->__is_null; + } + +#ifndef _LIBCPP_NO_RTTI + _LIBCPP_INLINE_VISIBILITY + const std::type_info& target_type() const _NOEXCEPT + { + return *__policy_->__type_info; + } + + template + _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT + { + if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info) + return nullptr; + if (__policy_->__clone) // Out of line storage. + return reinterpret_cast(__buf_.__large); + else + return reinterpret_cast(&__buf_.__small); + } +#endif // _LIBCPP_NO_RTTI +}; + } // __function template @@ -1866,7 +2165,11 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> { +#ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION typedef __function::__value_func<_Rp(_ArgTypes...)> __func; +#else + typedef __function::__policy_func<_Rp(_ArgTypes...)> __func; +#endif __func __f_; From adde8aeb1cfcb1e3a5985e3fae6c8aabcda91d9d Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Tue, 11 Dec 2018 02:17:23 +0000 Subject: [PATCH 14/94] [pair] Mark constructors as conditionally noexcept Summary: std::tuple marks its constructors as noexcept when the corresponding memberwise constructors are noexcept too -- this commit improves std::pair so that it behaves the same. Note: I did not add support in the explicit and non-explicit `pair(_Tuple&& __p)` constructors because those are non-standard extensions, and supporting them properly is tedious (we have to copy the rvalue-referenceness of the deduced _Tuple&& onto the result of tuple_element). Reviewers: mclow.lists, EricWF Subscribers: christof, llvm-commits Differential Revision: https://reviews.llvm.org/D48669 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348824 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/utility | 22 ++++- .../utility/pairs/pairs.pair/U_V.pass.cpp | 54 ++++++++++++ .../const_first_const_second.pass.cpp | 62 +++++++++++++ .../pairs/pairs.pair/const_pair_U_V.pass.cpp | 64 ++++++++++++++ .../utility/pairs/pairs.pair/default.pass.cpp | 30 +++++++ .../pairs/pairs.pair/piecewise.pass.cpp | 38 ++++++++ .../pairs/pairs.pair/rv_pair_U_V.pass.cpp | 63 ++++++++++++++ .../pairs/pairs.pair/piecewise.pass.cpp | 5 +- test/support/archetypes.hpp | 9 +- test/support/archetypes.ipp | 86 ++++++++++--------- 10 files changed, 387 insertions(+), 46 deletions(-) create mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp create mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp create mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp create mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp create mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp create mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp diff --git a/include/utility b/include/utility index ddfa27e22..fb7f44705 100644 --- a/include/utility +++ b/include/utility @@ -409,13 +409,17 @@ struct _LIBCPP_TEMPLATE_VIS pair _CheckArgsDep<_Dummy>::template __enable_default<_T1, _T2>() > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - pair() : first(), second() {} + pair() _NOEXCEPT_(is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value) + : first(), second() {} template ::template __enable_explicit<_T1 const&, _T2 const&>() > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(_T1 const& __t1, _T2 const& __t2) + _NOEXCEPT_(is_nothrow_copy_constructible::value && + is_nothrow_copy_constructible::value) : first(__t1), second(__t2) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(_T1 const& __t1, _T2 const& __t2) + _NOEXCEPT_(is_nothrow_copy_constructible::value && + is_nothrow_copy_constructible::value) : first(__t1), second(__t2) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(_U1&& __u1, _U2&& __u2) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(_U1&& __u1, _U2&& __u2) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(pair<_U1, _U2> const& __p) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(__p.first), second(__p.second) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(pair<_U1, _U2> const& __p) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(__p.first), second(__p.second) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(pair<_U1, _U2>&&__p) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(pair<_U1, _U2>&& __p) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} template __first_args, tuple<_Args2...> __second_args) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : pair(__pc, __first_args, __second_args, typename __make_tuple_indices::type(), typename __make_tuple_indices::type()) {} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp new file mode 100644 index 000000000..6a3e613e9 --- /dev/null +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// template pair(U&& x, V&& y); + +#include + + +struct ExplicitT { + constexpr explicit ExplicitT(int x) : value(x) {} + int value; +}; + +struct ImplicitT { + constexpr ImplicitT(int x) : value(x) {} + int value; +}; + +struct ExplicitNothrowT { + explicit ExplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +struct ImplicitNothrowT { + ImplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +int main() { + { // explicit noexcept test + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert( std::is_nothrow_constructible, int, int>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert( std::is_nothrow_constructible, int, int>::value, ""); + } +} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp new file mode 100644 index 000000000..6a2401223 --- /dev/null +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// pair(const T1& x, const T2& y); + +#include + + +struct ExplicitT { + constexpr explicit ExplicitT(int x) : value(x) {} + constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {} + int value; +}; + +struct ImplicitT { + constexpr ImplicitT(int x) : value(x) {} + constexpr ImplicitT(ImplicitT const& o) : value(o.value) {} + int value; +}; + +struct ExplicitNothrowT { + explicit ExplicitNothrowT(ExplicitNothrowT const&) noexcept {} +}; + +struct ImplicitNothrowT { + ImplicitNothrowT(ImplicitNothrowT const&) noexcept {} +}; + +int main() { + { // explicit noexcept test + static_assert(!std::is_nothrow_constructible, + ExplicitT const&, ExplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + ExplicitNothrowT const&, ExplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + ExplicitT const&, ExplicitNothrowT const&>::value, ""); + static_assert( std::is_nothrow_constructible, + ExplicitNothrowT const&, ExplicitNothrowT const&>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible, + ImplicitT const&, ImplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + ImplicitNothrowT const&, ImplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + ImplicitT const&, ImplicitNothrowT const&>::value, ""); + static_assert( std::is_nothrow_constructible, + ImplicitNothrowT const&, ImplicitNothrowT const&>::value, ""); + } +} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp new file mode 100644 index 000000000..edb3bbf64 --- /dev/null +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// template EXPLICIT constexpr pair(const pair& p); + +#include + + +struct ExplicitT { + constexpr explicit ExplicitT(int x) : value(x) {} + constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {} + int value; +}; + +struct ImplicitT { + constexpr ImplicitT(int x) : value(x) {} + constexpr ImplicitT(ImplicitT const& o) : value(o.value) {} + int value; +}; + +struct ExplicitNothrowT { + explicit ExplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +struct ImplicitNothrowT { + ImplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +int main() { + { // explicit noexcept test + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert( std::is_nothrow_constructible, + std::pair const&>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert( std::is_nothrow_constructible, + std::pair const&>::value, ""); + } +} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp new file mode 100644 index 000000000..e513d55fb --- /dev/null +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template struct pair + +// constexpr pair(); + + +#include +#include + +#include "archetypes.hpp" + + +int main() { + using NonThrowingDefault = NonThrowingTypes::DefaultOnly; + using ThrowingDefault = NonTrivialTypes::DefaultOnly; + static_assert(!std::is_nothrow_default_constructible>::value, ""); + static_assert(!std::is_nothrow_default_constructible>::value, ""); + static_assert(!std::is_nothrow_default_constructible>::value, ""); + static_assert( std::is_nothrow_default_constructible>::value, ""); +} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp new file mode 100644 index 000000000..81dad3bc2 --- /dev/null +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// template +// pair(piecewise_construct_t, tuple first_args, +// tuple second_args); + +#include +#include +#include + +#include "archetypes.hpp" + + +int main() { + using NonThrowingConvert = NonThrowingTypes::ConvertingType; + using ThrowingConvert = NonTrivialTypes::ConvertingType; + static_assert(!std::is_nothrow_constructible, + std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); + static_assert( std::is_nothrow_constructible, + std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); +} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp new file mode 100644 index 000000000..5d8d36262 --- /dev/null +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// template pair(pair&& p); + +#include +#include + + +struct ExplicitT { + constexpr explicit ExplicitT(int x) : value(x) {} + int value; +}; + +struct ImplicitT { + constexpr ImplicitT(int x) : value(x) {} + int value; +}; + +struct ExplicitNothrowT { + explicit ExplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +struct ImplicitNothrowT { + ImplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +int main() { + { // explicit noexcept test + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert( std::is_nothrow_constructible, + std::pair&&>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert( std::is_nothrow_constructible, + std::pair&&>::value, ""); + } +} diff --git a/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp index c738adad7..aa86949dd 100644 --- a/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp +++ b/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp @@ -17,9 +17,10 @@ // pair(piecewise_construct_t, tuple first_args, // tuple second_args); -#include -#include #include +#include +#include + int main() { diff --git a/test/support/archetypes.hpp b/test/support/archetypes.hpp index 1695a6fc6..a0ea7c3ce 100644 --- a/test/support/archetypes.hpp +++ b/test/support/archetypes.hpp @@ -225,7 +225,6 @@ namespace ExplicitTypes { #include "archetypes.ipp" } - //============================================================================// // namespace NonConstexprTypes { @@ -241,12 +240,18 @@ namespace NonLiteralTypes { #include "archetypes.ipp" } +//============================================================================// +// Non-throwing implicit test types +namespace NonThrowingTypes { +#define DEFINE_NOEXCEPT noexcept +#include "archetypes.ipp" +} + //============================================================================// // Non-Trivially Copyable Implicit Test Types namespace NonTrivialTypes { #define DEFINE_CTOR {} #define DEFINE_ASSIGN { return *this; } -#define DEFINE_DEFAULT_CTOR = default #include "archetypes.ipp" } diff --git a/test/support/archetypes.ipp b/test/support/archetypes.ipp index 360450179..943dcf9f5 100644 --- a/test/support/archetypes.ipp +++ b/test/support/archetypes.ipp @@ -5,6 +5,9 @@ #ifndef DEFINE_EXPLICIT #define DEFINE_EXPLICIT #endif +#ifndef DEFINE_NOEXCEPT +#define DEFINE_NOEXCEPT +#endif #ifndef DEFINE_CONSTEXPR #ifdef TEST_WORKAROUND_EDG_EXPLICIT_CONSTEXPR #define DEFINE_CONSTEXPR @@ -36,114 +39,114 @@ struct AllCtors : DEFINE_BASE(AllCtors) { using Base = DEFINE_BASE(AllCtors); using Base::Base; using Base::operator=; - DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors const&) DEFINE_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors &&) DEFINE_CTOR; - DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors const&) DEFINE_ASSIGN; - DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors &&) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors const&) DEFINE_NOEXCEPT DEFINE_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors &&) DEFINE_NOEXCEPT DEFINE_CTOR; + DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; + DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(AllCtors) }; struct NoCtors : DEFINE_BASE(NoCtors) { using Base = DEFINE_BASE(NoCtors); - DEFINE_EXPLICIT NoCtors() = delete; - DEFINE_EXPLICIT NoCtors(NoCtors const&) = delete; - NoCtors& operator=(NoCtors const&) = delete; + DEFINE_EXPLICIT NoCtors() DEFINE_NOEXCEPT = delete; + DEFINE_EXPLICIT NoCtors(NoCtors const&) DEFINE_NOEXCEPT = delete; + NoCtors& operator=(NoCtors const&) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(NoCtors) }; struct NoDefault : DEFINE_BASE(NoDefault) { using Base = DEFINE_BASE(NoDefault); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR NoDefault() = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR NoDefault() DEFINE_NOEXCEPT = delete; DEFINE_DTOR(NoDefault) }; struct DefaultOnly : DEFINE_BASE(DefaultOnly) { using Base = DEFINE_BASE(DefaultOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR DefaultOnly() DEFINE_DEFAULT_CTOR; - DefaultOnly(DefaultOnly const&) = delete; - DefaultOnly& operator=(DefaultOnly const&) = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR DefaultOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DefaultOnly(DefaultOnly const&) DEFINE_NOEXCEPT = delete; + DefaultOnly& operator=(DefaultOnly const&) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(DefaultOnly) }; struct Copyable : DEFINE_BASE(Copyable) { using Base = DEFINE_BASE(Copyable); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable(Copyable const &) DEFINE_CTOR; - Copyable &operator=(Copyable const &) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable(Copyable const &) DEFINE_NOEXCEPT DEFINE_CTOR; + Copyable &operator=(Copyable const &) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(Copyable) }; struct CopyOnly : DEFINE_BASE(CopyOnly) { using Base = DEFINE_BASE(CopyOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly const &) DEFINE_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly &&) = delete; - CopyOnly &operator=(CopyOnly const &) DEFINE_ASSIGN; - CopyOnly &operator=(CopyOnly &&) = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly const &) DEFINE_NOEXCEPT DEFINE_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly &&) DEFINE_NOEXCEPT = delete; + CopyOnly &operator=(CopyOnly const &) DEFINE_NOEXCEPT DEFINE_ASSIGN; + CopyOnly &operator=(CopyOnly &&) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(CopyOnly) }; struct NonCopyable : DEFINE_BASE(NonCopyable) { using Base = DEFINE_BASE(NonCopyable); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable(NonCopyable const &) = delete; - NonCopyable &operator=(NonCopyable const &) = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable(NonCopyable const &) DEFINE_NOEXCEPT = delete; + NonCopyable &operator=(NonCopyable const &) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(NonCopyable) }; struct MoveOnly : DEFINE_BASE(MoveOnly) { using Base = DEFINE_BASE(MoveOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly(MoveOnly &&) DEFINE_CTOR; - MoveOnly &operator=(MoveOnly &&) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly(MoveOnly &&) DEFINE_NOEXCEPT DEFINE_CTOR; + MoveOnly &operator=(MoveOnly &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(MoveOnly) }; struct CopyAssignable : DEFINE_BASE(CopyAssignable) { using Base = DEFINE_BASE(CopyAssignable); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignable() = delete; - CopyAssignable& operator=(CopyAssignable const&) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignable() DEFINE_NOEXCEPT = delete; + CopyAssignable& operator=(CopyAssignable const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(CopyAssignable) }; struct CopyAssignOnly : DEFINE_BASE(CopyAssignOnly) { using Base = DEFINE_BASE(CopyAssignOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignOnly() = delete; - CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_ASSIGN; - CopyAssignOnly& operator=(CopyAssignOnly &&) = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignOnly() DEFINE_NOEXCEPT = delete; + CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; + CopyAssignOnly& operator=(CopyAssignOnly &&) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(CopyAssignOnly) }; struct MoveAssignOnly : DEFINE_BASE(MoveAssignOnly) { using Base = DEFINE_BASE(MoveAssignOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveAssignOnly() = delete; - MoveAssignOnly& operator=(MoveAssignOnly const&) = delete; - MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveAssignOnly() DEFINE_NOEXCEPT = delete; + MoveAssignOnly& operator=(MoveAssignOnly const&) DEFINE_NOEXCEPT = delete; + MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(MoveAssignOnly) }; struct ConvertingType : DEFINE_BASE(ConvertingType) { using Base = DEFINE_BASE(ConvertingType); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType const&) DEFINE_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType &&) DEFINE_CTOR; - ConvertingType& operator=(ConvertingType const&) DEFINE_ASSIGN; - ConvertingType& operator=(ConvertingType &&) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType const&) DEFINE_NOEXCEPT DEFINE_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType &&) DEFINE_NOEXCEPT DEFINE_CTOR; + ConvertingType& operator=(ConvertingType const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; + ConvertingType& operator=(ConvertingType &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; template - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(Args&&...) {} + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(Args&&...) DEFINE_NOEXCEPT {} template - ConvertingType& operator=(Arg&&) { return *this; } + ConvertingType& operator=(Arg&&) DEFINE_NOEXCEPT { return *this; } DEFINE_DTOR(ConvertingType) }; @@ -165,6 +168,7 @@ using ApplyTypes = List< #undef DEFINE_BASE #undef DEFINE_EXPLICIT +#undef DEFINE_NOEXCEPT #undef DEFINE_CONSTEXPR #undef DEFINE_ASSIGN_CONSTEXPR #undef DEFINE_CTOR From 21a8669ade46d7f95343cee9b11008f246282299 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Tue, 11 Dec 2018 02:32:46 +0000 Subject: [PATCH 15/94] Revert "[pair] Mark constructors as conditionally noexcept" This broke the tests on Linux. Reverting until I find out why the tests are broken (tomorrow). git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348825 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/utility | 22 +---- .../utility/pairs/pairs.pair/U_V.pass.cpp | 54 ------------ .../const_first_const_second.pass.cpp | 62 ------------- .../pairs/pairs.pair/const_pair_U_V.pass.cpp | 64 -------------- .../utility/pairs/pairs.pair/default.pass.cpp | 30 ------- .../pairs/pairs.pair/piecewise.pass.cpp | 38 -------- .../pairs/pairs.pair/rv_pair_U_V.pass.cpp | 63 -------------- .../pairs/pairs.pair/piecewise.pass.cpp | 5 +- test/support/archetypes.hpp | 9 +- test/support/archetypes.ipp | 86 +++++++++---------- 10 files changed, 46 insertions(+), 387 deletions(-) delete mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp delete mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp delete mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp delete mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp delete mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp delete mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp diff --git a/include/utility b/include/utility index fb7f44705..ddfa27e22 100644 --- a/include/utility +++ b/include/utility @@ -409,17 +409,13 @@ struct _LIBCPP_TEMPLATE_VIS pair _CheckArgsDep<_Dummy>::template __enable_default<_T1, _T2>() > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - pair() _NOEXCEPT_(is_nothrow_default_constructible::value && - is_nothrow_default_constructible::value) - : first(), second() {} + pair() : first(), second() {} template ::template __enable_explicit<_T1 const&, _T2 const&>() > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(_T1 const& __t1, _T2 const& __t2) - _NOEXCEPT_(is_nothrow_copy_constructible::value && - is_nothrow_copy_constructible::value) : first(__t1), second(__t2) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(_T1 const& __t1, _T2 const& __t2) - _NOEXCEPT_(is_nothrow_copy_constructible::value && - is_nothrow_copy_constructible::value) : first(__t1), second(__t2) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(_U1&& __u1, _U2&& __u2) - _NOEXCEPT_((is_nothrow_constructible::value && - is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(_U1&& __u1, _U2&& __u2) - _NOEXCEPT_((is_nothrow_constructible::value && - is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(pair<_U1, _U2> const& __p) - _NOEXCEPT_((is_nothrow_constructible::value && - is_nothrow_constructible::value)) : first(__p.first), second(__p.second) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(pair<_U1, _U2> const& __p) - _NOEXCEPT_((is_nothrow_constructible::value && - is_nothrow_constructible::value)) : first(__p.first), second(__p.second) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(pair<_U1, _U2>&&__p) - _NOEXCEPT_((is_nothrow_constructible::value && - is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(pair<_U1, _U2>&& __p) - _NOEXCEPT_((is_nothrow_constructible::value && - is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} template __first_args, tuple<_Args2...> __second_args) - _NOEXCEPT_((is_nothrow_constructible::value && - is_nothrow_constructible::value)) : pair(__pc, __first_args, __second_args, typename __make_tuple_indices::type(), typename __make_tuple_indices::type()) {} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp deleted file mode 100644 index 6a3e613e9..000000000 --- a/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp +++ /dev/null @@ -1,54 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03 - -// - -// template struct pair - -// template pair(U&& x, V&& y); - -#include - - -struct ExplicitT { - constexpr explicit ExplicitT(int x) : value(x) {} - int value; -}; - -struct ImplicitT { - constexpr ImplicitT(int x) : value(x) {} - int value; -}; - -struct ExplicitNothrowT { - explicit ExplicitNothrowT(int x) noexcept : value(x) {} - int value; -}; - -struct ImplicitNothrowT { - ImplicitNothrowT(int x) noexcept : value(x) {} - int value; -}; - -int main() { - { // explicit noexcept test - static_assert(!std::is_nothrow_constructible, int, int>::value, ""); - static_assert(!std::is_nothrow_constructible, int, int>::value, ""); - static_assert(!std::is_nothrow_constructible, int, int>::value, ""); - static_assert( std::is_nothrow_constructible, int, int>::value, ""); - } - { // implicit noexcept test - static_assert(!std::is_nothrow_constructible, int, int>::value, ""); - static_assert(!std::is_nothrow_constructible, int, int>::value, ""); - static_assert(!std::is_nothrow_constructible, int, int>::value, ""); - static_assert( std::is_nothrow_constructible, int, int>::value, ""); - } -} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp deleted file mode 100644 index 6a2401223..000000000 --- a/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp +++ /dev/null @@ -1,62 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03 - -// - -// template struct pair - -// pair(const T1& x, const T2& y); - -#include - - -struct ExplicitT { - constexpr explicit ExplicitT(int x) : value(x) {} - constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {} - int value; -}; - -struct ImplicitT { - constexpr ImplicitT(int x) : value(x) {} - constexpr ImplicitT(ImplicitT const& o) : value(o.value) {} - int value; -}; - -struct ExplicitNothrowT { - explicit ExplicitNothrowT(ExplicitNothrowT const&) noexcept {} -}; - -struct ImplicitNothrowT { - ImplicitNothrowT(ImplicitNothrowT const&) noexcept {} -}; - -int main() { - { // explicit noexcept test - static_assert(!std::is_nothrow_constructible, - ExplicitT const&, ExplicitT const&>::value, ""); - static_assert(!std::is_nothrow_constructible, - ExplicitNothrowT const&, ExplicitT const&>::value, ""); - static_assert(!std::is_nothrow_constructible, - ExplicitT const&, ExplicitNothrowT const&>::value, ""); - static_assert( std::is_nothrow_constructible, - ExplicitNothrowT const&, ExplicitNothrowT const&>::value, ""); - } - { // implicit noexcept test - static_assert(!std::is_nothrow_constructible, - ImplicitT const&, ImplicitT const&>::value, ""); - static_assert(!std::is_nothrow_constructible, - ImplicitNothrowT const&, ImplicitT const&>::value, ""); - static_assert(!std::is_nothrow_constructible, - ImplicitT const&, ImplicitNothrowT const&>::value, ""); - static_assert( std::is_nothrow_constructible, - ImplicitNothrowT const&, ImplicitNothrowT const&>::value, ""); - } -} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp deleted file mode 100644 index edb3bbf64..000000000 --- a/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp +++ /dev/null @@ -1,64 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03 - -// - -// template struct pair - -// template EXPLICIT constexpr pair(const pair& p); - -#include - - -struct ExplicitT { - constexpr explicit ExplicitT(int x) : value(x) {} - constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {} - int value; -}; - -struct ImplicitT { - constexpr ImplicitT(int x) : value(x) {} - constexpr ImplicitT(ImplicitT const& o) : value(o.value) {} - int value; -}; - -struct ExplicitNothrowT { - explicit ExplicitNothrowT(int x) noexcept : value(x) {} - int value; -}; - -struct ImplicitNothrowT { - ImplicitNothrowT(int x) noexcept : value(x) {} - int value; -}; - -int main() { - { // explicit noexcept test - static_assert(!std::is_nothrow_constructible, - std::pair const&>::value, ""); - static_assert(!std::is_nothrow_constructible, - std::pair const&>::value, ""); - static_assert(!std::is_nothrow_constructible, - std::pair const&>::value, ""); - static_assert( std::is_nothrow_constructible, - std::pair const&>::value, ""); - } - { // implicit noexcept test - static_assert(!std::is_nothrow_constructible, - std::pair const&>::value, ""); - static_assert(!std::is_nothrow_constructible, - std::pair const&>::value, ""); - static_assert(!std::is_nothrow_constructible, - std::pair const&>::value, ""); - static_assert( std::is_nothrow_constructible, - std::pair const&>::value, ""); - } -} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp deleted file mode 100644 index e513d55fb..000000000 --- a/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp +++ /dev/null @@ -1,30 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// - -// template struct pair - -// constexpr pair(); - - -#include -#include - -#include "archetypes.hpp" - - -int main() { - using NonThrowingDefault = NonThrowingTypes::DefaultOnly; - using ThrowingDefault = NonTrivialTypes::DefaultOnly; - static_assert(!std::is_nothrow_default_constructible>::value, ""); - static_assert(!std::is_nothrow_default_constructible>::value, ""); - static_assert(!std::is_nothrow_default_constructible>::value, ""); - static_assert( std::is_nothrow_default_constructible>::value, ""); -} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp deleted file mode 100644 index 81dad3bc2..000000000 --- a/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp +++ /dev/null @@ -1,38 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03 - -// - -// template struct pair - -// template -// pair(piecewise_construct_t, tuple first_args, -// tuple second_args); - -#include -#include -#include - -#include "archetypes.hpp" - - -int main() { - using NonThrowingConvert = NonThrowingTypes::ConvertingType; - using ThrowingConvert = NonTrivialTypes::ConvertingType; - static_assert(!std::is_nothrow_constructible, - std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); - static_assert(!std::is_nothrow_constructible, - std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); - static_assert(!std::is_nothrow_constructible, - std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); - static_assert( std::is_nothrow_constructible, - std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); -} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp deleted file mode 100644 index 5d8d36262..000000000 --- a/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp +++ /dev/null @@ -1,63 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03 - -// - -// template struct pair - -// template pair(pair&& p); - -#include -#include - - -struct ExplicitT { - constexpr explicit ExplicitT(int x) : value(x) {} - int value; -}; - -struct ImplicitT { - constexpr ImplicitT(int x) : value(x) {} - int value; -}; - -struct ExplicitNothrowT { - explicit ExplicitNothrowT(int x) noexcept : value(x) {} - int value; -}; - -struct ImplicitNothrowT { - ImplicitNothrowT(int x) noexcept : value(x) {} - int value; -}; - -int main() { - { // explicit noexcept test - static_assert(!std::is_nothrow_constructible, - std::pair&&>::value, ""); - static_assert(!std::is_nothrow_constructible, - std::pair&&>::value, ""); - static_assert(!std::is_nothrow_constructible, - std::pair&&>::value, ""); - static_assert( std::is_nothrow_constructible, - std::pair&&>::value, ""); - } - { // implicit noexcept test - static_assert(!std::is_nothrow_constructible, - std::pair&&>::value, ""); - static_assert(!std::is_nothrow_constructible, - std::pair&&>::value, ""); - static_assert(!std::is_nothrow_constructible, - std::pair&&>::value, ""); - static_assert( std::is_nothrow_constructible, - std::pair&&>::value, ""); - } -} diff --git a/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp index aa86949dd..c738adad7 100644 --- a/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp +++ b/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp @@ -17,10 +17,9 @@ // pair(piecewise_construct_t, tuple first_args, // tuple second_args); -#include -#include #include - +#include +#include int main() { diff --git a/test/support/archetypes.hpp b/test/support/archetypes.hpp index a0ea7c3ce..1695a6fc6 100644 --- a/test/support/archetypes.hpp +++ b/test/support/archetypes.hpp @@ -225,6 +225,7 @@ namespace ExplicitTypes { #include "archetypes.ipp" } + //============================================================================// // namespace NonConstexprTypes { @@ -240,18 +241,12 @@ namespace NonLiteralTypes { #include "archetypes.ipp" } -//============================================================================// -// Non-throwing implicit test types -namespace NonThrowingTypes { -#define DEFINE_NOEXCEPT noexcept -#include "archetypes.ipp" -} - //============================================================================// // Non-Trivially Copyable Implicit Test Types namespace NonTrivialTypes { #define DEFINE_CTOR {} #define DEFINE_ASSIGN { return *this; } +#define DEFINE_DEFAULT_CTOR = default #include "archetypes.ipp" } diff --git a/test/support/archetypes.ipp b/test/support/archetypes.ipp index 943dcf9f5..360450179 100644 --- a/test/support/archetypes.ipp +++ b/test/support/archetypes.ipp @@ -5,9 +5,6 @@ #ifndef DEFINE_EXPLICIT #define DEFINE_EXPLICIT #endif -#ifndef DEFINE_NOEXCEPT -#define DEFINE_NOEXCEPT -#endif #ifndef DEFINE_CONSTEXPR #ifdef TEST_WORKAROUND_EDG_EXPLICIT_CONSTEXPR #define DEFINE_CONSTEXPR @@ -39,114 +36,114 @@ struct AllCtors : DEFINE_BASE(AllCtors) { using Base = DEFINE_BASE(AllCtors); using Base::Base; using Base::operator=; - DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors const&) DEFINE_NOEXCEPT DEFINE_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors &&) DEFINE_NOEXCEPT DEFINE_CTOR; - DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; - DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors() DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors const&) DEFINE_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors &&) DEFINE_CTOR; + DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors const&) DEFINE_ASSIGN; + DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors &&) DEFINE_ASSIGN; DEFINE_DTOR(AllCtors) }; struct NoCtors : DEFINE_BASE(NoCtors) { using Base = DEFINE_BASE(NoCtors); - DEFINE_EXPLICIT NoCtors() DEFINE_NOEXCEPT = delete; - DEFINE_EXPLICIT NoCtors(NoCtors const&) DEFINE_NOEXCEPT = delete; - NoCtors& operator=(NoCtors const&) DEFINE_NOEXCEPT = delete; + DEFINE_EXPLICIT NoCtors() = delete; + DEFINE_EXPLICIT NoCtors(NoCtors const&) = delete; + NoCtors& operator=(NoCtors const&) = delete; DEFINE_DTOR(NoCtors) }; struct NoDefault : DEFINE_BASE(NoDefault) { using Base = DEFINE_BASE(NoDefault); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR NoDefault() DEFINE_NOEXCEPT = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR NoDefault() = delete; DEFINE_DTOR(NoDefault) }; struct DefaultOnly : DEFINE_BASE(DefaultOnly) { using Base = DEFINE_BASE(DefaultOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR DefaultOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; - DefaultOnly(DefaultOnly const&) DEFINE_NOEXCEPT = delete; - DefaultOnly& operator=(DefaultOnly const&) DEFINE_NOEXCEPT = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR DefaultOnly() DEFINE_DEFAULT_CTOR; + DefaultOnly(DefaultOnly const&) = delete; + DefaultOnly& operator=(DefaultOnly const&) = delete; DEFINE_DTOR(DefaultOnly) }; struct Copyable : DEFINE_BASE(Copyable) { using Base = DEFINE_BASE(Copyable); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable(Copyable const &) DEFINE_NOEXCEPT DEFINE_CTOR; - Copyable &operator=(Copyable const &) DEFINE_NOEXCEPT DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable() DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable(Copyable const &) DEFINE_CTOR; + Copyable &operator=(Copyable const &) DEFINE_ASSIGN; DEFINE_DTOR(Copyable) }; struct CopyOnly : DEFINE_BASE(CopyOnly) { using Base = DEFINE_BASE(CopyOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly const &) DEFINE_NOEXCEPT DEFINE_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly &&) DEFINE_NOEXCEPT = delete; - CopyOnly &operator=(CopyOnly const &) DEFINE_NOEXCEPT DEFINE_ASSIGN; - CopyOnly &operator=(CopyOnly &&) DEFINE_NOEXCEPT = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly() DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly const &) DEFINE_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly &&) = delete; + CopyOnly &operator=(CopyOnly const &) DEFINE_ASSIGN; + CopyOnly &operator=(CopyOnly &&) = delete; DEFINE_DTOR(CopyOnly) }; struct NonCopyable : DEFINE_BASE(NonCopyable) { using Base = DEFINE_BASE(NonCopyable); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable(NonCopyable const &) DEFINE_NOEXCEPT = delete; - NonCopyable &operator=(NonCopyable const &) DEFINE_NOEXCEPT = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable() DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable(NonCopyable const &) = delete; + NonCopyable &operator=(NonCopyable const &) = delete; DEFINE_DTOR(NonCopyable) }; struct MoveOnly : DEFINE_BASE(MoveOnly) { using Base = DEFINE_BASE(MoveOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly(MoveOnly &&) DEFINE_NOEXCEPT DEFINE_CTOR; - MoveOnly &operator=(MoveOnly &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly() DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly(MoveOnly &&) DEFINE_CTOR; + MoveOnly &operator=(MoveOnly &&) DEFINE_ASSIGN; DEFINE_DTOR(MoveOnly) }; struct CopyAssignable : DEFINE_BASE(CopyAssignable) { using Base = DEFINE_BASE(CopyAssignable); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignable() DEFINE_NOEXCEPT = delete; - CopyAssignable& operator=(CopyAssignable const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignable() = delete; + CopyAssignable& operator=(CopyAssignable const&) DEFINE_ASSIGN; DEFINE_DTOR(CopyAssignable) }; struct CopyAssignOnly : DEFINE_BASE(CopyAssignOnly) { using Base = DEFINE_BASE(CopyAssignOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignOnly() DEFINE_NOEXCEPT = delete; - CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; - CopyAssignOnly& operator=(CopyAssignOnly &&) DEFINE_NOEXCEPT = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignOnly() = delete; + CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_ASSIGN; + CopyAssignOnly& operator=(CopyAssignOnly &&) = delete; DEFINE_DTOR(CopyAssignOnly) }; struct MoveAssignOnly : DEFINE_BASE(MoveAssignOnly) { using Base = DEFINE_BASE(MoveAssignOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveAssignOnly() DEFINE_NOEXCEPT = delete; - MoveAssignOnly& operator=(MoveAssignOnly const&) DEFINE_NOEXCEPT = delete; - MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveAssignOnly() = delete; + MoveAssignOnly& operator=(MoveAssignOnly const&) = delete; + MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_ASSIGN; DEFINE_DTOR(MoveAssignOnly) }; struct ConvertingType : DEFINE_BASE(ConvertingType) { using Base = DEFINE_BASE(ConvertingType); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType const&) DEFINE_NOEXCEPT DEFINE_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType &&) DEFINE_NOEXCEPT DEFINE_CTOR; - ConvertingType& operator=(ConvertingType const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; - ConvertingType& operator=(ConvertingType &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType() DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType const&) DEFINE_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType &&) DEFINE_CTOR; + ConvertingType& operator=(ConvertingType const&) DEFINE_ASSIGN; + ConvertingType& operator=(ConvertingType &&) DEFINE_ASSIGN; template - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(Args&&...) DEFINE_NOEXCEPT {} + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(Args&&...) {} template - ConvertingType& operator=(Arg&&) DEFINE_NOEXCEPT { return *this; } + ConvertingType& operator=(Arg&&) { return *this; } DEFINE_DTOR(ConvertingType) }; @@ -168,7 +165,6 @@ using ApplyTypes = List< #undef DEFINE_BASE #undef DEFINE_EXPLICIT -#undef DEFINE_NOEXCEPT #undef DEFINE_CONSTEXPR #undef DEFINE_ASSIGN_CONSTEXPR #undef DEFINE_CTOR From 96484477d180c4dfe6c38913a4e22572908370e4 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Tue, 11 Dec 2018 04:35:44 +0000 Subject: [PATCH 16/94] Second part of P0482 - char8_t. Reviewed as https://reviews.llvm.org/D55308 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348828 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/__config | 4 + include/__string | 97 +++++++++++++++++++ include/iosfwd | 17 ++++ include/istream | 1 + include/limits | 1 + include/locale | 1 + include/ostream | 1 + include/string | 14 ++- include/string_view | 11 +++ include/type_traits | 2 +- include/version | 5 + .../algorithm.version.pass.cpp | 1 + .../any.version.pass.cpp | 1 + .../array.version.pass.cpp | 1 + .../atomic.version.pass.cpp | 14 ++- .../bit.version.pass.cpp | 1 + .../support.limits.general/charconv.pass.cpp | 1 + .../chrono.version.pass.cpp | 1 + .../cmath.version.pass.cpp | 1 + .../complex.version.pass.cpp | 1 + .../concepts.version.pass.cpp | 1 + .../cstddef.version.pass.cpp | 1 + .../deque.version.pass.cpp | 1 + .../exception.version.pass.cpp | 1 + .../execution.version.pass.cpp | 1 + .../filesystem.version.pass.cpp | 14 ++- .../forward_list.version.pass.cpp | 1 + .../functional.version.pass.cpp | 3 +- .../iomanip.version.pass.cpp | 1 + .../istream.version.pass.cpp | 43 ++++++++ .../iterator.version.pass.cpp | 1 + .../limits.version.pass.cpp | 43 ++++++++ .../list.version.pass.cpp | 1 + .../locale.version.pass.cpp | 43 ++++++++ .../map.version.pass.cpp | 1 + .../memory.version.pass.cpp | 1 + .../memory_resource.version.pass.cpp | 1 + .../mutex.version.pass.cpp | 1 + .../new.version.pass.cpp | 1 + .../numeric.version.pass.cpp | 1 + .../optional.version.pass.cpp | 1 + .../ostream.version.pass.cpp | 43 ++++++++ .../regex.version.pass.cpp | 1 + .../scoped_allocator.version.pass.cpp | 1 + .../set.version.pass.cpp | 1 + .../shared_mutex.version.pass.cpp | 1 + .../string.version.pass.cpp | 12 +++ .../string_view.version.pass.cpp | 12 +++ .../tuple.version.pass.cpp | 1 + .../type_traits.version.pass.cpp | 3 +- .../unordered_map.version.pass.cpp | 1 + .../unordered_set.version.pass.cpp | 1 + .../utility.version.pass.cpp | 1 + .../variant.version.pass.cpp | 1 + .../vector.version.pass.cpp | 1 + .../version.version.pass.cpp | 19 +++- .../basic.string.hash/enabled_hashes.pass.cpp | 3 + .../basic.string.hash/strings.pass.cpp | 3 + .../basic.string.literals/literal.pass.cpp | 52 +++++----- .../string_view_deduction.pass.cpp | 12 +++ .../string_view_size_size_deduction.pass.cpp | 12 +++ .../string.iterators/iterators.pass.cpp | 14 +++ .../assign2.pass.cpp | 39 ++++++++ .../assign3.pass.cpp | 30 ++++++ .../compare.pass.cpp | 56 +++++++++++ .../copy.pass.cpp | 32 ++++++ .../eof.pass.cpp | 26 +++++ .../eq.pass.cpp | 28 ++++++ .../eq_int_type.pass.cpp | 31 ++++++ .../find.pass.cpp | 46 +++++++++ .../length.pass.cpp | 39 ++++++++ .../lt.pass.cpp | 28 ++++++ .../move.pass.cpp | 36 +++++++ .../not_eof.pass.cpp | 31 ++++++ .../to_char_type.pass.cpp | 29 ++++++ .../to_int_type.pass.cpp | 29 ++++++ .../types.pass.cpp | 34 +++++++ .../strings/string.classes/typedefs.pass.cpp | 10 +- .../string.view.capacity/capacity.pass.cpp | 23 +++-- .../string.view.cons/assign.pass.cpp | 24 +++-- .../string.view.cons/default.pass.cpp | 16 ++- .../string.view.cons/from_string.pass.cpp | 6 ++ .../string.view.hash/enabled_hashes.pass.cpp | 3 + .../string.view.hash/string_view.pass.cpp | 3 + .../string.view.iterators/begin.pass.cpp | 15 +++ .../string.view.iterators/end.pass.cpp | 15 +++ .../string.view.iterators/rbegin.pass.cpp | 15 +++ .../string.view.iterators/rend.pass.cpp | 15 +++ .../string_view.literals/literal.pass.cpp | 58 +++++------ test/std/strings/string.view/types.pass.cpp | 3 + .../meta.unary.cat/is_integral.pass.cpp | 2 +- 91 files changed, 1152 insertions(+), 103 deletions(-) create mode 100644 test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/limits.version.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp create mode 100644 test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign2.pass.cpp create mode 100644 test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign3.pass.cpp create mode 100644 test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp create mode 100644 test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/copy.pass.cpp create mode 100644 test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eof.pass.cpp create mode 100644 test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq.pass.cpp create mode 100644 test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq_int_type.pass.cpp create mode 100644 test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/find.pass.cpp create mode 100644 test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/length.pass.cpp create mode 100644 test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/lt.pass.cpp create mode 100644 test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/move.pass.cpp create mode 100644 test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/not_eof.pass.cpp create mode 100644 test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_char_type.pass.cpp create mode 100644 test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_int_type.pass.cpp create mode 100644 test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/types.pass.cpp diff --git a/include/__config b/include/__config index b4367d0d3..88c207c72 100644 --- a/include/__config +++ b/include/__config @@ -1004,6 +1004,10 @@ template struct __static_assert_check {}; #define _LIBCPP_WCTYPE_IS_MASK #endif +#if _LIBCPP_STD_VER <= 17 || !defined(__cpp_char8_t) +#define _LIBCPP_NO_HAS_CHAR8_T +#endif + // Deprecation macros. // Deprecations warnings are only enabled when _LIBCPP_ENABLE_DEPRECATION_WARNINGS is defined. #if defined(_LIBCPP_ENABLE_DEPRECATION_WARNINGS) diff --git a/include/__string b/include/__string index 44c55987f..1ddeec714 100644 --- a/include/__string +++ b/include/__string @@ -47,6 +47,7 @@ struct char_traits template <> struct char_traits; template <> struct char_traits; +template <> struct char_traits; // c++20 } // std @@ -389,6 +390,102 @@ char_traits::find(const char_type* __s, size_t __n, const char_type& __ } +#ifndef _LIBCPP_NO_HAS_CHAR8_T + +template <> +struct _LIBCPP_TEMPLATE_VIS char_traits +{ + typedef char8_t char_type; + typedef unsigned int int_type; + typedef streamoff off_type; + typedef u8streampos pos_type; + typedef mbstate_t state_type; + + static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept + {__c1 = __c2;} + static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept + {return __c1 == __c2;} + static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept + {return __c1 < __c2;} + + static constexpr + int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + + static constexpr + size_t length(const char_type* __s) _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY static constexpr + const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; + + static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);} + + static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + { + _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); + return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n); + } + + static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT + {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);} + + static inline constexpr int_type not_eof(int_type __c) noexcept + {return eq_int_type(__c, eof()) ? ~eof() : __c;} + static inline constexpr char_type to_char_type(int_type __c) noexcept + {return char_type(__c);} + static inline constexpr int_type to_int_type(char_type __c) noexcept + {return int_type(__c);} + static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept + {return __c1 == __c2;} + static inline constexpr int_type eof() noexcept + {return int_type(EOF);} +}; + +// TODO use '__builtin_strlen' if it ever supports char8_t ?? +inline constexpr +size_t +char_traits::length(const char_type* __s) _NOEXCEPT +{ + size_t __len = 0; + for (; !eq(*__s, char_type(0)); ++__s) + ++__len; + return __len; +} + +inline constexpr +int +char_traits::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ +#if __has_feature(cxx_constexpr_string_builtins) + return __builtin_memcmp(__s1, __s2, __n); +#else + for (; __n; --__n, ++__s1, ++__s2) + { + if (lt(*__s1, *__s2)) + return -1; + if (lt(*__s2, *__s1)) + return 1; + } + return 0; +#endif +} + +// TODO use '__builtin_char_memchr' if it ever supports char8_t ?? +inline constexpr +const char8_t* +char_traits::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT +{ + for (; __n; --__n) + { + if (eq(*__s, __a)) + return __s; + ++__s; + } + return 0; +} + +#endif // #_LIBCPP_NO_HAS_CHAR8_T + #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS template <> diff --git a/include/iosfwd b/include/iosfwd index d4384859e..31f1902e5 100644 --- a/include/iosfwd +++ b/include/iosfwd @@ -18,6 +18,12 @@ namespace std { template struct char_traits; +template<> struct char_traits; +template<> struct char_traits; // C++20 +template<> struct char_traits; +template<> struct char_traits; +template<> struct char_traits; + template class allocator; class ios_base; @@ -98,6 +104,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD class _LIBCPP_TYPE_VIS ios_base; template struct _LIBCPP_TEMPLATE_VIS char_traits; +template<> struct char_traits; +#ifndef _LIBCPP_NO_HAS_CHAR8_T +template<> struct char_traits; +#endif +template<> struct char_traits; +template<> struct char_traits; +template<> struct char_traits; + template class _LIBCPP_TEMPLATE_VIS allocator; template > @@ -175,6 +189,9 @@ typedef basic_fstream wfstream; template class _LIBCPP_TEMPLATE_VIS fpos; typedef fpos streampos; typedef fpos wstreampos; +#ifndef _LIBCPP_NO_HAS_CHAR8_T +typedef fpos u8streampos; +#endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS typedef fpos u16streampos; typedef fpos u32streampos; diff --git a/include/istream b/include/istream index efbbae800..30ee4f4b8 100644 --- a/include/istream +++ b/include/istream @@ -160,6 +160,7 @@ template */ #include <__config> +#include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/include/limits b/include/limits index 5b75f4a9e..5ea9a9e6f 100644 --- a/include/limits +++ b/include/limits @@ -119,6 +119,7 @@ template<> class numeric_limits; _LIBCPP_PUSH_MACROS #include <__undef_macros> +#include _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/include/locale b/include/locale index 3a8dfbcf0..ac589d360 100644 --- a/include/locale +++ b/include/locale @@ -187,6 +187,7 @@ template class messages_byname; #include #include #include +#include #ifndef __APPLE__ #include #endif diff --git a/include/ostream b/include/ostream index d7a5d5289..d700a369b 100644 --- a/include/ostream +++ b/include/ostream @@ -140,6 +140,7 @@ template #include #include #include +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/include/string b/include/string index 31ad307e5..4dd6ddc4e 100644 --- a/include/string +++ b/include/string @@ -4170,11 +4170,13 @@ swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, __lhs.swap(__rhs); } -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS +#ifndef _LIBCPP_NO_HAS_CHAR8_T +typedef basic_string u8string; +#endif +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS typedef basic_string u16string; typedef basic_string u32string; - #endif // _LIBCPP_HAS_NO_UNICODE_CHARS _LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* __idx = 0, int __base = 10); @@ -4331,6 +4333,14 @@ inline namespace literals return basic_string (__str, __len); } +#ifndef _LIBCPP_NO_HAS_CHAR8_T + inline _LIBCPP_INLINE_VISIBILITY + basic_string operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT + { + return basic_string (__str, __len); + } +#endif + inline _LIBCPP_INLINE_VISIBILITY basic_string operator "" s( const char16_t *__str, size_t __len ) { diff --git a/include/string_view b/include/string_view index dd425a2e8..7d783122f 100644 --- a/include/string_view +++ b/include/string_view @@ -769,6 +769,9 @@ bool operator>=(typename common_type >::type } typedef basic_string_view string_view; +#ifndef _LIBCPP_NO_HAS_CHAR8_T +typedef basic_string_view u8string_view; +#endif typedef basic_string_view u16string_view; typedef basic_string_view u32string_view; typedef basic_string_view wstring_view; @@ -802,6 +805,14 @@ inline namespace literals return basic_string_view (__str, __len); } +#ifndef _LIBCPP_NO_HAS_CHAR8_T + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + basic_string_view operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT + { + return basic_string_view (__str, __len); + } +#endif + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR basic_string_view operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT { diff --git a/include/type_traits b/include/type_traits index 09c001970..ab010716f 100644 --- a/include/type_traits +++ b/include/type_traits @@ -709,7 +709,7 @@ template <> struct __libcpp_is_integral : public tr template <> struct __libcpp_is_integral : public true_type {}; template <> struct __libcpp_is_integral : public true_type {}; template <> struct __libcpp_is_integral : public true_type {}; -#if _LIBCPP_STD_VER > 17 && defined(__cpp_char8_t) +#ifndef _LIBCPP_NO_HAS_CHAR8_T template <> struct __libcpp_is_integral : public true_type {}; #endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS diff --git a/include/version b/include/version index aca84f8ed..5e758fce7 100644 --- a/include/version +++ b/include/version @@ -30,6 +30,8 @@ __cpp_lib_bit_cast 201806L __cpp_lib_bool_constant 201505L __cpp_lib_boyer_moore_searcher 201603L __cpp_lib_byte 201603L +__cpp_lib_char8_t 201811L + __cpp_lib_chrono 201611L __cpp_lib_chrono_udls 201304L __cpp_lib_clamp 201603L @@ -114,6 +116,9 @@ __cpp_lib_void_t 201411L #endif #if _LIBCPP_STD_VER > 17 +#ifndef _LIBCPP_NO_HAS_CHAR8_T +# define __cpp_lib_char8_t 201811L +#endif #endif #endif // _LIBCPP_VERSIONH diff --git a/test/std/language.support/support.limits/support.limits.general/algorithm.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/algorithm.version.pass.cpp index 37a636f32..24d2f8002 100644 --- a/test/std/language.support/support.limits/support.limits.general/algorithm.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/algorithm.version.pass.cpp @@ -20,6 +20,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/any.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/any.version.pass.cpp index 951afbc08..933730442 100644 --- a/test/std/language.support/support.limits/support.limits.general/any.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/any.version.pass.cpp @@ -16,6 +16,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/array.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/array.version.pass.cpp index 548abe648..5d25c628b 100644 --- a/test/std/language.support/support.limits/support.limits.general/array.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/array.version.pass.cpp @@ -17,6 +17,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp index 0c15dc539..a990cab9b 100644 --- a/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp @@ -11,6 +11,7 @@ // feature macros /* Constant Value + __cpp_lib_char8_t 201811L __cpp_lib_atomic_is_always_lock_free 201603L __cpp_lib_atomic_ref 201806L @@ -19,13 +20,24 @@ // UNSUPPORTED: libcpp-has-no-threads #include +#include #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in are defined. -#if _TEST_STD_VER > 14 +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_char8_t) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); +# else +# if __cpp_lib_char8_t < 201811L +# error "__cpp_lib_char8_t has an invalid value" +# endif +# endif +#endif + +#if TEST_STD_VER > 14 # if !defined(__cpp_lib_atomic_is_always_lock_free) # error "__cpp_lib_atomic_is_always_lock_free is not defined" # elif __cpp_lib_atomic_is_always_lock_free < 201603L diff --git a/test/std/language.support/support.limits/support.limits.general/bit.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/bit.version.pass.cpp index 2dfe4a8b1..5dd7d049a 100644 --- a/test/std/language.support/support.limits/support.limits.general/bit.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/bit.version.pass.cpp @@ -16,6 +16,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/charconv.pass.cpp b/test/std/language.support/support.limits/support.limits.general/charconv.pass.cpp index 26147fc54..f1e252f8e 100644 --- a/test/std/language.support/support.limits/support.limits.general/charconv.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/charconv.pass.cpp @@ -15,6 +15,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/chrono.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/chrono.version.pass.cpp index 9ec93f39c..1d0a79ec1 100644 --- a/test/std/language.support/support.limits/support.limits.general/chrono.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/chrono.version.pass.cpp @@ -17,6 +17,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/cmath.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/cmath.version.pass.cpp index e8479d1c8..b5b0309f8 100644 --- a/test/std/language.support/support.limits/support.limits.general/cmath.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/cmath.version.pass.cpp @@ -17,6 +17,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/complex.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/complex.version.pass.cpp index dd64efb11..be25d793d 100644 --- a/test/std/language.support/support.limits/support.limits.general/complex.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/complex.version.pass.cpp @@ -16,6 +16,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/concepts.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/concepts.version.pass.cpp index 06f244834..b21239122 100644 --- a/test/std/language.support/support.limits/support.limits.general/concepts.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/concepts.version.pass.cpp @@ -17,6 +17,7 @@ // XFAIL // #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/cstddef.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/cstddef.version.pass.cpp index ac8dfbb04..ad743b51e 100644 --- a/test/std/language.support/support.limits/support.limits.general/cstddef.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/cstddef.version.pass.cpp @@ -16,6 +16,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp index faa9063f4..d3ca7d9b0 100644 --- a/test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp @@ -17,6 +17,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/exception.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/exception.version.pass.cpp index a77ce5f1c..3ea235bdb 100644 --- a/test/std/language.support/support.limits/support.limits.general/exception.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/exception.version.pass.cpp @@ -16,6 +16,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/execution.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/execution.version.pass.cpp index e81061ead..2fcd44cd0 100644 --- a/test/std/language.support/support.limits/support.limits.general/execution.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/execution.version.pass.cpp @@ -17,6 +17,7 @@ // XFAIL // #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/filesystem.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/filesystem.version.pass.cpp index 46ad17d75..160a997ce 100644 --- a/test/std/language.support/support.limits/support.limits.general/filesystem.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/filesystem.version.pass.cpp @@ -11,18 +11,30 @@ // feature macros /* Constant Value + __cpp_lib_char8_t 201811L __cpp_lib_filesystem 201703L */ #include +#include #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in are defined. -#if _TEST_STD_VER > 14 +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_char8_t) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); +# else +# if __cpp_lib_char8_t < 201811L +# error "__cpp_lib_char8_t has an invalid value" +# endif +# endif +#endif + +#if TEST_STD_VER > 14 # if !defined(__cpp_lib_filesystem) # error "__cpp_lib_filesystem is not defined" # elif __cpp_lib_filesystem < 201703L diff --git a/test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp index b262d70dd..73c8462ca 100644 --- a/test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp @@ -19,6 +19,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/functional.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/functional.version.pass.cpp index a24de49f3..57978cbb3 100644 --- a/test/std/language.support/support.limits/support.limits.general/functional.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/functional.version.pass.cpp @@ -20,13 +20,14 @@ */ #include +#include #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in are defined. -#if _TEST_STD_VER > 14 +#if TEST_STD_VER > 14 # if !defined(__cpp_lib_invoke) # error "__cpp_lib_invoke is not defined" # elif __cpp_lib_invoke < 201411L diff --git a/test/std/language.support/support.limits/support.limits.general/iomanip.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/iomanip.version.pass.cpp index 35ed34b50..74ab48e3c 100644 --- a/test/std/language.support/support.limits/support.limits.general/iomanip.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/iomanip.version.pass.cpp @@ -16,6 +16,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp new file mode 100644 index 000000000..dfa0052e4 --- /dev/null +++ b/test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp @@ -0,0 +1,43 @@ + +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// feature macros + +/* Constant Value + __cpp_lib_char8_t 201811L + +*/ + +#include +#include +#include "test_macros.h" + +int main() +{ +// ensure that the macros that are supposed to be defined in are defined. + +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_char8_t) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); +# else +# if __cpp_lib_char8_t < 201811L +# error "__cpp_lib_char8_t has an invalid value" +# endif +# endif +#endif + +/* +#if !defined(__cpp_lib_fooby) +# error "__cpp_lib_fooby is not defined" +#elif __cpp_lib_fooby < 201606L +# error "__cpp_lib_fooby has an invalid value" +#endif +*/ +} diff --git a/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp index 02e028649..50c582fd8 100644 --- a/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp @@ -19,6 +19,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/limits.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/limits.version.pass.cpp new file mode 100644 index 000000000..5d4997153 --- /dev/null +++ b/test/std/language.support/support.limits/support.limits.general/limits.version.pass.cpp @@ -0,0 +1,43 @@ + +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// feature macros + +/* Constant Value + __cpp_lib_char8_t 201811L + +*/ + +#include +#include +#include "test_macros.h" + +int main() +{ +// ensure that the macros that are supposed to be defined in are defined. + +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_char8_t) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); +# else +# if __cpp_lib_char8_t < 201811L +# error "__cpp_lib_char8_t has an invalid value" +# endif +# endif +#endif + +/* +#if !defined(__cpp_lib_fooby) +# error "__cpp_lib_fooby is not defined" +#elif __cpp_lib_fooby < 201606L +# error "__cpp_lib_fooby has an invalid value" +#endif +*/ +} diff --git a/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp index ad666d152..3db799563 100644 --- a/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp @@ -19,6 +19,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp new file mode 100644 index 000000000..4c45c0a54 --- /dev/null +++ b/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp @@ -0,0 +1,43 @@ + +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// feature macros + +/* Constant Value + __cpp_lib_char8_t 201811L + +*/ + +#include +#include +#include "test_macros.h" + +int main() +{ +// ensure that the macros that are supposed to be defined in are defined. + +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_char8_t) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); +# else +# if __cpp_lib_char8_t < 201811L +# error "__cpp_lib_char8_t has an invalid value" +# endif +# endif +#endif + +/* +#if !defined(__cpp_lib_fooby) +# error "__cpp_lib_fooby is not defined" +#elif __cpp_lib_fooby < 201606L +# error "__cpp_lib_fooby has an invalid value" +#endif +*/ +} diff --git a/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp index 933449ce5..ffcc003e3 100644 --- a/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp @@ -20,6 +20,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp index 5dbd6ab5f..4ffb7bd80 100644 --- a/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp @@ -23,6 +23,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/memory_resource.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/memory_resource.version.pass.cpp index 30c27233b..857ece267 100644 --- a/test/std/language.support/support.limits/support.limits.general/memory_resource.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/memory_resource.version.pass.cpp @@ -17,6 +17,7 @@ // XFAIL // #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/mutex.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/mutex.version.pass.cpp index 1909b31a1..72209d9f4 100644 --- a/test/std/language.support/support.limits/support.limits.general/mutex.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/mutex.version.pass.cpp @@ -16,6 +16,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/new.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/new.version.pass.cpp index 6daca346f..856bd8b01 100644 --- a/test/std/language.support/support.limits/support.limits.general/new.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/new.version.pass.cpp @@ -17,6 +17,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp index fbe100ba8..61547621e 100644 --- a/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp @@ -17,6 +17,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/optional.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/optional.version.pass.cpp index b78eda604..b9795181a 100644 --- a/test/std/language.support/support.limits/support.limits.general/optional.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/optional.version.pass.cpp @@ -16,6 +16,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp new file mode 100644 index 000000000..5f2ffb296 --- /dev/null +++ b/test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp @@ -0,0 +1,43 @@ + +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// feature macros + +/* Constant Value + __cpp_lib_char8_t 201811L + +*/ + +#include +#include +#include "test_macros.h" + +int main() +{ +// ensure that the macros that are supposed to be defined in are defined. + +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_char8_t) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); +# else +# if __cpp_lib_char8_t < 201811L +# error "__cpp_lib_char8_t has an invalid value" +# endif +# endif +#endif + +/* +#if !defined(__cpp_lib_fooby) +# error "__cpp_lib_fooby is not defined" +#elif __cpp_lib_fooby < 201606L +# error "__cpp_lib_fooby has an invalid value" +#endif +*/ +} diff --git a/test/std/language.support/support.limits/support.limits.general/regex.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/regex.version.pass.cpp index 91222ce64..fdc499328 100644 --- a/test/std/language.support/support.limits/support.limits.general/regex.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/regex.version.pass.cpp @@ -16,6 +16,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/scoped_allocator.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/scoped_allocator.version.pass.cpp index c43069186..84b2dbdb2 100644 --- a/test/std/language.support/support.limits/support.limits.general/scoped_allocator.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/scoped_allocator.version.pass.cpp @@ -16,6 +16,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp index dc414f0fd..96918031d 100644 --- a/test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp @@ -19,6 +19,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/shared_mutex.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/shared_mutex.version.pass.cpp index d432e8beb..33387e890 100644 --- a/test/std/language.support/support.limits/support.limits.general/shared_mutex.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/shared_mutex.version.pass.cpp @@ -19,6 +19,7 @@ // UNSUPPORTED: libcpp-has-no-threads #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp index 2b755b691..02aa15c77 100644 --- a/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_char8_t 201811L __cpp_lib_nonmember_container_access 201411L __cpp_lib_string_udls 201304L __cpp_lib_string_view 201606L @@ -19,12 +20,23 @@ */ #include +#include #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_char8_t) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); +# else +# if __cpp_lib_char8_t < 201811L +# error "__cpp_lib_char8_t has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp index 53e76821b..82f1c66dd 100644 --- a/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp @@ -11,17 +11,29 @@ // feature macros /* Constant Value + __cpp_lib_char8_t 201811L __cpp_lib_string_view 201606L */ #include +#include #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_char8_t) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); +# else +# if __cpp_lib_char8_t < 201811L +# error "__cpp_lib_char8_t has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/test/std/language.support/support.limits/support.limits.general/tuple.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/tuple.version.pass.cpp index 921b8ae93..ddff29d78 100644 --- a/test/std/language.support/support.limits/support.limits.general/tuple.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/tuple.version.pass.cpp @@ -19,6 +19,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/type_traits.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/type_traits.version.pass.cpp index 9f7ecedb5..e53da7ef7 100644 --- a/test/std/language.support/support.limits/support.limits.general/type_traits.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/type_traits.version.pass.cpp @@ -28,13 +28,14 @@ */ #include +#include #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in are defined. -#if _TEST_STD_VER > 14 +#if TEST_STD_VER > 14 # if !defined(__cpp_lib_void_t) # error "__cpp_lib_void_t is not defined" # elif __cpp_lib_void_t < 201411L diff --git a/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp index cf01b4afc..38e011717 100644 --- a/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp @@ -19,6 +19,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp index b8e70636c..762a07c37 100644 --- a/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp @@ -18,6 +18,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/utility.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/utility.version.pass.cpp index 8f0322d86..dff687f4b 100644 --- a/test/std/language.support/support.limits/support.limits.general/utility.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/utility.version.pass.cpp @@ -19,6 +19,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/variant.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/variant.version.pass.cpp index 75f228ba9..5532e0446 100644 --- a/test/std/language.support/support.limits/support.limits.general/variant.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/variant.version.pass.cpp @@ -16,6 +16,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp index f033d4476..9932a61c5 100644 --- a/test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp @@ -18,6 +18,7 @@ */ #include +#include #include "test_macros.h" int main() diff --git a/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp index e52c188bf..f4be2eb09 100644 --- a/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp @@ -88,13 +88,14 @@ */ #include +#include #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in are defined. -#if _TEST_STD_VER > 14 +#if TEST_STD_VER > 14 # if !defined(__cpp_lib_atomic_is_always_lock_free) # error "__cpp_lib_atomic_is_always_lock_free is not defined" # elif __cpp_lib_atomic_is_always_lock_free < 201603L @@ -102,7 +103,7 @@ int main() # endif #endif -#if _TEST_STD_VER > 14 +#if TEST_STD_VER > 14 # if !defined(__cpp_lib_filesystem) # error "__cpp_lib_filesystem is not defined" # elif __cpp_lib_filesystem < 201703L @@ -110,7 +111,7 @@ int main() # endif #endif -#if _TEST_STD_VER > 14 +#if TEST_STD_VER > 14 # if !defined(__cpp_lib_invoke) # error "__cpp_lib_invoke is not defined" # elif __cpp_lib_invoke < 201411L @@ -118,7 +119,7 @@ int main() # endif #endif -#if _TEST_STD_VER > 14 +#if TEST_STD_VER > 14 # if !defined(__cpp_lib_void_t) # error "__cpp_lib_void_t is not defined" # elif __cpp_lib_void_t < 201411L @@ -126,6 +127,16 @@ int main() # endif #endif +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_char8_t) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); +# else +# if __cpp_lib_char8_t < 201811L +# error "__cpp_lib_char8_t has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp b/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp index 01f012189..e6f3d53a8 100644 --- a/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp +++ b/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp @@ -23,6 +23,9 @@ int main() { { test_hash_enabled_for_type(); test_hash_enabled_for_type(); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test_hash_enabled_for_type(); +#endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS test_hash_enabled_for_type(); test_hash_enabled_for_type(); diff --git a/test/std/strings/basic.string.hash/strings.pass.cpp b/test/std/strings/basic.string.hash/strings.pass.cpp index d74e48575..449ad8f11 100644 --- a/test/std/strings/basic.string.hash/strings.pass.cpp +++ b/test/std/strings/basic.string.hash/strings.pass.cpp @@ -44,6 +44,9 @@ test() int main() { test(); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test(); +#endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS test(); test(); diff --git a/test/std/strings/basic.string.literals/literal.pass.cpp b/test/std/strings/basic.string.literals/literal.pass.cpp index 65ebb3c50..cbb03ef61 100644 --- a/test/std/strings/basic.string.literals/literal.pass.cpp +++ b/test/std/strings/basic.string.literals/literal.pass.cpp @@ -15,48 +15,44 @@ #include "test_macros.h" +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + typedef std::u8string u8string; +#else + typedef std::string u8string; +#endif + + int main() { using namespace std::literals::string_literals; static_assert ( std::is_same::value, "" ); -// This is changed by P0482 to return a std::u8string -#if TEST_STD_VER <= 17 - static_assert ( std::is_same::value, "" ); -#endif + static_assert ( std::is_same::value, "" ); static_assert ( std::is_same::value, "" ); static_assert ( std::is_same::value, "" ); static_assert ( std::is_same::value, "" ); std::string foo; std::wstring Lfoo; + u8string u8foo; std::u16string ufoo; std::u32string Ufoo; - foo = ""s; assert( foo.size() == 0); -// This is changed by P0482 to return a std::u8string -#if TEST_STD_VER <= 17 - foo = u8""s; assert( foo.size() == 0); -#endif - Lfoo = L""s; assert(Lfoo.size() == 0); - ufoo = u""s; assert(ufoo.size() == 0); - Ufoo = U""s; assert(Ufoo.size() == 0); + foo = ""s; assert( foo.size() == 0); + u8foo = u8""s; assert(u8foo.size() == 0); + Lfoo = L""s; assert( Lfoo.size() == 0); + ufoo = u""s; assert( ufoo.size() == 0); + Ufoo = U""s; assert( Ufoo.size() == 0); - foo = " "s; assert( foo.size() == 1); -// This is changed by P0482 to return a std::u8string -#if TEST_STD_VER <= 17 - foo = u8" "s; assert( foo.size() == 1); -#endif - Lfoo = L" "s; assert(Lfoo.size() == 1); - ufoo = u" "s; assert(ufoo.size() == 1); - Ufoo = U" "s; assert(Ufoo.size() == 1); + foo = " "s; assert( foo.size() == 1); + u8foo = u8" "s; assert(u8foo.size() == 1); + Lfoo = L" "s; assert( Lfoo.size() == 1); + ufoo = u" "s; assert( ufoo.size() == 1); + Ufoo = U" "s; assert( Ufoo.size() == 1); - foo = "ABC"s; assert( foo == "ABC"); assert( foo == std::string ( "ABC")); -// This is changed by P0482 to return a std::u8string -#if TEST_STD_VER <= 17 - foo = u8"ABC"s; assert( foo == u8"ABC"); assert( foo == std::string (u8"ABC")); -#endif - Lfoo = L"ABC"s; assert(Lfoo == L"ABC"); assert(Lfoo == std::wstring ( L"ABC")); - ufoo = u"ABC"s; assert(ufoo == u"ABC"); assert(ufoo == std::u16string( u"ABC")); - Ufoo = U"ABC"s; assert(Ufoo == U"ABC"); assert(Ufoo == std::u32string( U"ABC")); + foo = "ABC"s; assert( foo == "ABC"); assert( foo == std::string ( "ABC")); + u8foo = u8"ABC"s; assert(u8foo == u8"ABC"); assert(u8foo == u8string (u8"ABC")); + Lfoo = L"ABC"s; assert( Lfoo == L"ABC"); assert( Lfoo == std::wstring ( L"ABC")); + ufoo = u"ABC"s; assert( ufoo == u"ABC"); assert( ufoo == std::u16string( u"ABC")); + Ufoo = U"ABC"s; assert( Ufoo == U"ABC"); assert( Ufoo == std::u32string( U"ABC")); } diff --git a/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp b/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp index df1e99e01..a1f3c4b51 100644 --- a/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp +++ b/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp @@ -72,6 +72,18 @@ int main() assert(s1.size() == sv.size()); assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0); } +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + { + std::u8string_view sv = u8"12345678901234"; + std::basic_string s1{sv, min_allocator{}}; + using S = decltype(s1); // what type did we get? + static_assert(std::is_same_v, ""); + static_assert(std::is_same_v>, ""); + static_assert(std::is_same_v>, ""); + assert(s1.size() == sv.size()); + assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0); + } +#endif { std::u16string_view sv = u"12345678901234"; std::basic_string s1{sv, min_allocator{}}; diff --git a/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp b/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp index 22ca2fdc1..fd9684e1f 100644 --- a/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp +++ b/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp @@ -76,6 +76,18 @@ int main() assert(s1.size() == 4); assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0); } +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + { + std::u8string_view sv = u8"12345678901234"; + std::basic_string s1{sv, 0, 4, min_allocator{}}; + using S = decltype(s1); // what type did we get? + static_assert(std::is_same_v, ""); + static_assert(std::is_same_v>, ""); + static_assert(std::is_same_v>, ""); + assert(s1.size() == 4); + assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0); + } +#endif { std::u16string_view sv = u"12345678901234"; std::basic_string s1{sv, 0, 4, min_allocator{}}; diff --git a/test/std/strings/basic.string/string.iterators/iterators.pass.cpp b/test/std/strings/basic.string/string.iterators/iterators.pass.cpp index 9466f1135..8bc6e4fb2 100644 --- a/test/std/strings/basic.string/string.iterators/iterators.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/iterators.pass.cpp @@ -47,6 +47,20 @@ int main() assert ( !(ii1 != cii )); } +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + { + typedef std::u8string C; + C::iterator ii1{}, ii2{}; + C::iterator ii4 = ii1; + C::const_iterator cii{}; + assert ( ii1 == ii2 ); + assert ( ii1 == ii4 ); + assert ( ii1 == cii ); + assert ( !(ii1 != ii2 )); + assert ( !(ii1 != cii )); + } +#endif + { // N3644 testing typedef std::u16string C; C::iterator ii1{}, ii2{}; diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign2.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign2.pass.cpp new file mode 100644 index 000000000..e293115fa --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign2.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 +// + +// template<> struct char_traits + +// static constexpr void assign(char_type& c1, const char_type& c2); + +#include +#include + +#include "test_macros.h" + +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L +constexpr bool test_constexpr() +{ + char8_t c = u'1'; + std::char_traits::assign(c, u'a'); + return c == u'a'; +} + +int main() +{ + char8_t c = u8'\0'; + std::char_traits::assign(c, u8'a'); + assert(c == u8'a'); + + static_assert(test_constexpr(), ""); +} +#else +int main () {} +#endif diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign3.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign3.pass.cpp new file mode 100644 index 000000000..d1fab485c --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign3.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template<> struct char_traits + +// static char_type* assign(char_type* s, size_t n, char_type a); + +#include +#include + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + char8_t s2[3] = {0}; + assert(std::char_traits::assign(s2, 3, char8_t(5)) == s2); + assert(s2[0] == char8_t(5)); + assert(s2[1] == char8_t(5)); + assert(s2[2] == char8_t(5)); + assert(std::char_traits::assign(NULL, 0, char8_t(5)) == NULL); +#endif +} diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp new file mode 100644 index 000000000..0ce036a97 --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template<> struct char_traits + +// static constexpr int compare(const char_type* s1, const char_type* s2, size_t n); + +#include +#include + +#include "test_macros.h" + +constexpr bool test_constexpr() +{ + return std::char_traits::compare(u8"123", u8"223", 3) < 0 + && std::char_traits::compare(u8"223", u8"123", 3) > 0 + && std::char_traits::compare(u8"123", u8"123", 3) == 0; +} + + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert(std::char_traits::compare(u8"", u8"", 0) == 0); + assert(std::char_traits::compare(NULL, NULL, 0) == 0); + + assert(std::char_traits::compare(u8"1", u8"1", 1) == 0); + assert(std::char_traits::compare(u8"1", u8"2", 1) < 0); + assert(std::char_traits::compare(u8"2", u8"1", 1) > 0); + + assert(std::char_traits::compare(u8"12", u8"12", 2) == 0); + assert(std::char_traits::compare(u8"12", u8"13", 2) < 0); + assert(std::char_traits::compare(u8"12", u8"22", 2) < 0); + assert(std::char_traits::compare(u8"13", u8"12", 2) > 0); + assert(std::char_traits::compare(u8"22", u8"12", 2) > 0); + + assert(std::char_traits::compare(u8"123", u8"123", 3) == 0); + assert(std::char_traits::compare(u8"123", u8"223", 3) < 0); + assert(std::char_traits::compare(u8"123", u8"133", 3) < 0); + assert(std::char_traits::compare(u8"123", u8"124", 3) < 0); + assert(std::char_traits::compare(u8"223", u8"123", 3) > 0); + assert(std::char_traits::compare(u8"133", u8"123", 3) > 0); + assert(std::char_traits::compare(u8"124", u8"123", 3) > 0); + + static_assert(test_constexpr(), "" ); +#endif +} diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/copy.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/copy.pass.cpp new file mode 100644 index 000000000..74d51667d --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/copy.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template<> struct char_traits + +// static char_type* copy(char_type* s1, const char_type* s2, size_t n); + +#include +#include + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + char8_t s1[] = {1, 2, 3}; + char8_t s2[3] = {0}; + assert(std::char_traits::copy(s2, s1, 3) == s2); + assert(s2[0] == char8_t(1)); + assert(s2[1] == char8_t(2)); + assert(s2[2] == char8_t(3)); + assert(std::char_traits::copy(NULL, s1, 0) == NULL); + assert(std::char_traits::copy(s1, NULL, 0) == s1); +#endif +} diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eof.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eof.pass.cpp new file mode 100644 index 000000000..c48e3aedd --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eof.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template<> struct char_traits + +// static constexpr int_type eof(); + +#include +#include + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + std::char_traits::int_type i = std::char_traits::eof(); + ((void)i); // Prevent unused warning +#endif +} diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq.pass.cpp new file mode 100644 index 000000000..2b7d793c7 --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template<> struct char_traits + +// static constexpr bool eq(char_type c1, char_type c2); + +#include +#include + +#include "test_macros.h" + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert( std::char_traits::eq(u8'a', u8'a')); + assert(!std::char_traits::eq(u8'a', u8'A')); +#endif +} diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq_int_type.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq_int_type.pass.cpp new file mode 100644 index 000000000..15e645e3a --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq_int_type.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template<> struct char_traits + +// static constexpr bool eq_int_type(int_type c1, int_type c2); + +#include +#include + +#include "test_macros.h" + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert( std::char_traits::eq_int_type(u8'a', u8'a')); + assert(!std::char_traits::eq_int_type(u8'a', u8'A')); + assert(!std::char_traits::eq_int_type(std::char_traits::eof(), u8'A')); + assert( std::char_traits::eq_int_type(std::char_traits::eof(), + std::char_traits::eof())); +#endif +} diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/find.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/find.pass.cpp new file mode 100644 index 000000000..f35816659 --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/find.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template<> struct char_traits + +// static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); + +#include +#include + +#include "test_macros.h" + +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L +constexpr bool test_constexpr() +{ + constexpr const char8_t *p = u8"123"; + return std::char_traits::find(p, 3, u8'1') == p + && std::char_traits::find(p, 3, u8'2') == p + 1 + && std::char_traits::find(p, 3, u8'3') == p + 2 + && std::char_traits::find(p, 3, u8'4') == nullptr; +} + +int main() +{ + char8_t s1[] = {1, 2, 3}; + assert(std::char_traits::find(s1, 3, char8_t(1)) == s1); + assert(std::char_traits::find(s1, 3, char8_t(2)) == s1+1); + assert(std::char_traits::find(s1, 3, char8_t(3)) == s1+2); + assert(std::char_traits::find(s1, 3, char8_t(4)) == 0); + assert(std::char_traits::find(s1, 3, char8_t(0)) == 0); + assert(std::char_traits::find(NULL, 0, char8_t(0)) == 0); + + static_assert(test_constexpr(), "" ); +} +#else +int main () {} +#endif diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/length.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/length.pass.cpp new file mode 100644 index 000000000..19f6c1e8d --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/length.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template<> struct char_traits + +// static constexpr size_t length(const char_type* s); + +#include +#include + +#include "test_macros.h" + +constexpr bool test_constexpr() +{ + return std::char_traits::length(u8"") == 0 + && std::char_traits::length(u8"abcd") == 4; +} + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert(std::char_traits::length(u8"") == 0); + assert(std::char_traits::length(u8"a") == 1); + assert(std::char_traits::length(u8"aa") == 2); + assert(std::char_traits::length(u8"aaa") == 3); + assert(std::char_traits::length(u8"aaaa") == 4); + + static_assert(test_constexpr(), ""); +#endif +} diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/lt.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/lt.pass.cpp new file mode 100644 index 000000000..73c703f77 --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/lt.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template<> struct char_traits + +// static constexpr bool lt(char_type c1, char_type c2); + +#include +#include + +#include "test_macros.h" + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert(!std::char_traits::lt(u8'a', u8'a')); + assert( std::char_traits::lt(u8'A', u8'a')); +#endif +} diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/move.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/move.pass.cpp new file mode 100644 index 000000000..688e55932 --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/move.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template<> struct char_traits + +// static char_type* move(char_type* s1, const char_type* s2, size_t n); + +#include +#include + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + char8_t s1[] = {1, 2, 3}; + assert(std::char_traits::move(s1, s1+1, 2) == s1); + assert(s1[0] == char8_t(2)); + assert(s1[1] == char8_t(3)); + assert(s1[2] == char8_t(3)); + s1[2] = char8_t(0); + assert(std::char_traits::move(s1+1, s1, 2) == s1+1); + assert(s1[0] == char8_t(2)); + assert(s1[1] == char8_t(2)); + assert(s1[2] == char8_t(3)); + assert(std::char_traits::move(NULL, s1, 0) == NULL); + assert(std::char_traits::move(s1, NULL, 0) == s1); +#endif +} diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/not_eof.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/not_eof.pass.cpp new file mode 100644 index 000000000..274d93f13 --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/not_eof.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template<> struct char_traits + +// static constexpr int_type not_eof(int_type c); + +#include +#include + +#include "test_macros.h" + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert(std::char_traits::not_eof(u8'a') == u8'a'); + assert(std::char_traits::not_eof(u8'A') == u8'A'); + assert(std::char_traits::not_eof(0) == 0); + assert(std::char_traits::not_eof(std::char_traits::eof()) != + std::char_traits::eof()); +#endif +} diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_char_type.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_char_type.pass.cpp new file mode 100644 index 000000000..96159209f --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_char_type.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template<> struct char_traits + +// static constexpr char_type to_char_type(int_type c); + +#include +#include + +#include "test_macros.h" + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert(std::char_traits::to_char_type(u8'a') == u8'a'); + assert(std::char_traits::to_char_type(u8'A') == u8'A'); + assert(std::char_traits::to_char_type(0) == 0); +#endif +} diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_int_type.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_int_type.pass.cpp new file mode 100644 index 000000000..659be36ad --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_int_type.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template<> struct char_traits + +// static constexpr int_type to_int_type(char_type c); + +#include +#include + +#include "test_macros.h" + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert(std::char_traits::to_int_type(u8'a') == u8'a'); + assert(std::char_traits::to_int_type(u8'A') == u8'A'); + assert(std::char_traits::to_int_type(0) == 0); +#endif +} diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/types.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/types.pass.cpp new file mode 100644 index 000000000..64c27ffd7 --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/types.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template<> struct char_traits + +// typedef char8_t char_type; +// typedef unsigned int int_type; +// typedef streamoff off_type; +// typedef u16streampos pos_type; +// typedef mbstate_t state_type; + +#include +#include +#include + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + static_assert((std::is_same::char_type, char8_t>::value), ""); + static_assert((std::is_same::int_type, unsigned int>::value), ""); + static_assert((std::is_same::off_type, std::streamoff>::value), ""); + static_assert((std::is_same::pos_type, std::u16streampos>::value), ""); + static_assert((std::is_same::state_type, std::mbstate_t>::value), ""); +#endif +} diff --git a/test/std/strings/string.classes/typedefs.pass.cpp b/test/std/strings/string.classes/typedefs.pass.cpp index 3aba1c3f1..15d971235 100644 --- a/test/std/strings/string.classes/typedefs.pass.cpp +++ b/test/std/strings/string.classes/typedefs.pass.cpp @@ -12,18 +12,24 @@ // Test for the existence of: // basic_string typedef names -// typedef basic_string string; +// typedef basic_string string; // typedef basic_string u16string; +// typedef basic_string u8string; // C++20 // typedef basic_string u32string; -// typedef basic_string wstring; +// typedef basic_string wstring; #include #include +#include "test_macros.h" + int main() { static_assert((std::is_same >::value), ""); static_assert((std::is_same >::value), ""); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + static_assert((std::is_same >::value), ""); +#endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS static_assert((std::is_same >::value), ""); static_assert((std::is_same >::value), ""); diff --git a/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp b/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp index b21ba0422..fda67c3bf 100644 --- a/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp +++ b/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp @@ -64,15 +64,13 @@ void test2 ( const CharT *s, size_t len ) { } int main () { - typedef std::string_view string_view; - typedef std::u16string_view u16string_view; - typedef std::u32string_view u32string_view; - typedef std::wstring_view wstring_view; - - test1 (); - test1 (); - test1 (); - test1 (); + test1 (); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test1 (); +#endif + test1 (); + test1 (); + test1 (); test2 ( "ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE", 105 ); test2 ( "ABCDE", 5 ); @@ -84,6 +82,13 @@ int main () { test2 ( L"a", 1 ); test2 ( L"", 0 ); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test2 ( u8"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE", 105 ); + test2 ( u8"ABCDE", 5 ); + test2 ( u8"a", 1 ); + test2 ( u8"", 0 ); +#endif + #if TEST_STD_VER >= 11 test2 ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE", 105 ); test2 ( u"ABCDE", 5 ); diff --git a/test/std/strings/string.view/string.view.cons/assign.pass.cpp b/test/std/strings/string.view/string.view.cons/assign.pass.cpp index 3307aa61d..bab788921 100644 --- a/test/std/strings/string.view/string.view.cons/assign.pass.cpp +++ b/test/std/strings/string.view/string.view.cons/assign.pass.cpp @@ -32,21 +32,27 @@ bool test (T sv0) int main () { - assert( test ( "1234")); + assert( test ( "1234")); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert( test (u8"1234")); +#endif #if TEST_STD_VER >= 11 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - assert( test (u"1234")); - assert( test (U"1234")); + assert( test ( u"1234")); + assert( test ( U"1234")); #endif #endif - assert( test (L"1234")); + assert( test ( L"1234")); #if TEST_STD_VER > 11 - static_assert( test ({ "abc", 3}), ""); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - static_assert( test ({u"abc", 3}), ""); - static_assert( test ({U"abc", 3}), ""); + static_assert( test ({ "abc", 3}), ""); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + static_assert( test ({u8"abc", 3}), ""); #endif - static_assert( test ({L"abc", 3}), ""); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + static_assert( test ({ u"abc", 3}), ""); + static_assert( test ({ U"abc", 3}), ""); +#endif + static_assert( test ({ L"abc", 3}), ""); #endif } diff --git a/test/std/strings/string.view/string.view.cons/default.pass.cpp b/test/std/strings/string.view/string.view.cons/default.pass.cpp index 79fadf619..0c94918b5 100644 --- a/test/std/strings/string.view/string.view.cons/default.pass.cpp +++ b/test/std/strings/string.view/string.view.cons/default.pass.cpp @@ -37,14 +37,12 @@ void test () { } int main () { - typedef std::string_view string_view; - typedef std::u16string_view u16string_view; - typedef std::u32string_view u32string_view; - typedef std::wstring_view wstring_view; - - test (); - test (); - test (); - test (); + test (); + test (); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test (); +#endif + test (); + test (); } diff --git a/test/std/strings/string.view/string.view.cons/from_string.pass.cpp b/test/std/strings/string.view/string.view.cons/from_string.pass.cpp index 5fad2bfaa..237d1221d 100644 --- a/test/std/strings/string.view/string.view.cons/from_string.pass.cpp +++ b/test/std/strings/string.view/string.view.cons/from_string.pass.cpp @@ -42,6 +42,12 @@ int main () { test ( std::wstring(L"") ); test ( std::wstring() ); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test ( std::u8string{u8"QBCDE"} ); + test ( std::u8string{u8""} ); + test ( std::u8string{} ); +#endif + #if TEST_STD_VER >= 11 test ( std::u16string{u"QBCDE"} ); test ( std::u16string{u""} ); diff --git a/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp b/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp index 2e9ebcb4c..70515bf48 100644 --- a/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp +++ b/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp @@ -23,6 +23,9 @@ int main() { { test_hash_enabled_for_type(); test_hash_enabled_for_type(); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test_hash_enabled_for_type(); +#endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS test_hash_enabled_for_type(); test_hash_enabled_for_type(); diff --git a/test/std/strings/string.view/string.view.hash/string_view.pass.cpp b/test/std/strings/string.view/string.view.hash/string_view.pass.cpp index 53c3d261d..042e1dfab 100644 --- a/test/std/strings/string.view/string.view.hash/string_view.pass.cpp +++ b/test/std/strings/string.view/string.view.hash/string_view.pass.cpp @@ -59,6 +59,9 @@ test() int main() { test(); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test(); +#endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS test(); test(); diff --git a/test/std/strings/string.view/string.view.iterators/begin.pass.cpp b/test/std/strings/string.view/string.view.iterators/begin.pass.cpp index b766c5168..339f1f8fd 100644 --- a/test/std/strings/string.view/string.view.iterators/begin.pass.cpp +++ b/test/std/strings/string.view/string.view.iterators/begin.pass.cpp @@ -43,6 +43,9 @@ test(S s) int main() { typedef std::string_view string_view; +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + typedef std::u8string_view u8string_view; +#endif typedef std::u16string_view u16string_view; typedef std::u32string_view u32string_view; typedef std::wstring_view wstring_view; @@ -53,6 +56,9 @@ int main() test(wstring_view ()); test(string_view ( "123")); test(wstring_view (L"123")); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test(u8string_view{u8"123"}); +#endif #if TEST_STD_VER >= 11 test(u16string_view{u"123"}); test(u32string_view{U"123"}); @@ -61,16 +67,25 @@ int main() #if TEST_STD_VER > 11 { constexpr string_view sv { "123", 3 }; +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + constexpr u8string_view u8sv {u8"123", 3 }; +#endif constexpr u16string_view u16sv {u"123", 3 }; constexpr u32string_view u32sv {U"123", 3 }; constexpr wstring_view wsv {L"123", 3 }; static_assert ( *sv.begin() == sv[0], "" ); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + static_assert ( *u8sv.begin() == u8sv[0], "" ); +#endif static_assert ( *u16sv.begin() == u16sv[0], "" ); static_assert ( *u32sv.begin() == u32sv[0], "" ); static_assert ( *wsv.begin() == wsv[0], "" ); static_assert ( *sv.cbegin() == sv[0], "" ); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + static_assert ( *u8sv.cbegin() == u8sv[0], "" ); +#endif static_assert ( *u16sv.cbegin() == u16sv[0], "" ); static_assert ( *u32sv.cbegin() == u32sv[0], "" ); static_assert ( *wsv.cbegin() == wsv[0], "" ); diff --git a/test/std/strings/string.view/string.view.iterators/end.pass.cpp b/test/std/strings/string.view/string.view.iterators/end.pass.cpp index b5759d701..1533b49ba 100644 --- a/test/std/strings/string.view/string.view.iterators/end.pass.cpp +++ b/test/std/strings/string.view/string.view.iterators/end.pass.cpp @@ -52,6 +52,9 @@ test(S s) int main() { typedef std::string_view string_view; +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + typedef std::u8string_view u8string_view; +#endif typedef std::u16string_view u16string_view; typedef std::u32string_view u32string_view; typedef std::wstring_view wstring_view; @@ -62,6 +65,9 @@ int main() test(wstring_view ()); test(string_view ( "123")); test(wstring_view (L"123")); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test(u8string_view{u8"123"}); +#endif #if TEST_STD_VER >= 11 test(u16string_view{u"123"}); test(u32string_view{U"123"}); @@ -70,16 +76,25 @@ int main() #if TEST_STD_VER > 11 { constexpr string_view sv { "123", 3 }; +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + constexpr u8string_view u8sv {u8"123", 3 }; +#endif constexpr u16string_view u16sv {u"123", 3 }; constexpr u32string_view u32sv {U"123", 3 }; constexpr wstring_view wsv {L"123", 3 }; static_assert ( sv.begin() != sv.end(), "" ); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + static_assert ( u8sv.begin() != u8sv.end(), "" ); +#endif static_assert ( u16sv.begin() != u16sv.end(), "" ); static_assert ( u32sv.begin() != u32sv.end(), "" ); static_assert ( wsv.begin() != wsv.end(), "" ); static_assert ( sv.begin() != sv.cend(), "" ); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + static_assert ( u8sv.begin() != u8sv.cend(), "" ); +#endif static_assert ( u16sv.begin() != u16sv.cend(), "" ); static_assert ( u32sv.begin() != u32sv.cend(), "" ); static_assert ( wsv.begin() != wsv.cend(), "" ); diff --git a/test/std/strings/string.view/string.view.iterators/rbegin.pass.cpp b/test/std/strings/string.view/string.view.iterators/rbegin.pass.cpp index 16a4da882..0ec838718 100644 --- a/test/std/strings/string.view/string.view.iterators/rbegin.pass.cpp +++ b/test/std/strings/string.view/string.view.iterators/rbegin.pass.cpp @@ -44,6 +44,9 @@ test(S s) int main() { typedef std::string_view string_view; +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + typedef std::u8string_view u8string_view; +#endif typedef std::u16string_view u16string_view; typedef std::u32string_view u32string_view; typedef std::wstring_view wstring_view; @@ -54,6 +57,9 @@ int main() test(wstring_view ()); test(string_view ( "123")); test(wstring_view (L"123")); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test(u8string_view{u8"123"}); +#endif #if TEST_STD_VER >= 11 test(u16string_view{u"123"}); test(u32string_view{U"123"}); @@ -62,16 +68,25 @@ int main() #if TEST_STD_VER > 14 { constexpr string_view sv { "123", 3 }; +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + constexpr u8string_view u8sv {u8"123", 3 }; +#endif constexpr u16string_view u16sv {u"123", 3 }; constexpr u32string_view u32sv {U"123", 3 }; constexpr wstring_view wsv {L"123", 3 }; static_assert ( *sv.rbegin() == sv[2], "" ); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + static_assert ( *u8sv.rbegin() == u8sv[2], "" ); +#endif static_assert ( *u16sv.rbegin() == u16sv[2], "" ); static_assert ( *u32sv.rbegin() == u32sv[2], "" ); static_assert ( *wsv.rbegin() == wsv[2], "" ); static_assert ( *sv.crbegin() == sv[2], "" ); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + static_assert ( *u8sv.crbegin() == u8sv[2], "" ); +#endif static_assert ( *u16sv.crbegin() == u16sv[2], "" ); static_assert ( *u32sv.crbegin() == u32sv[2], "" ); static_assert ( *wsv.crbegin() == wsv[2], "" ); diff --git a/test/std/strings/string.view/string.view.iterators/rend.pass.cpp b/test/std/strings/string.view/string.view.iterators/rend.pass.cpp index 08f9e5a77..dfcb836f1 100644 --- a/test/std/strings/string.view/string.view.iterators/rend.pass.cpp +++ b/test/std/strings/string.view/string.view.iterators/rend.pass.cpp @@ -52,6 +52,9 @@ test(S s) int main() { typedef std::string_view string_view; +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + typedef std::u8string_view u8string_view; +#endif typedef std::u16string_view u16string_view; typedef std::u32string_view u32string_view; typedef std::wstring_view wstring_view; @@ -62,6 +65,9 @@ int main() test(wstring_view ()); test(string_view ( "123")); test(wstring_view (L"123")); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test(u8string_view{u8"123"}); +#endif #if TEST_STD_VER >= 11 test(u16string_view{u"123"}); test(u32string_view{U"123"}); @@ -70,16 +76,25 @@ int main() #if TEST_STD_VER > 14 { constexpr string_view sv { "123", 3 }; +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + constexpr u8string_view u8sv {u8"123", 3 }; +#endif constexpr u16string_view u16sv {u"123", 3 }; constexpr u32string_view u32sv {U"123", 3 }; constexpr wstring_view wsv {L"123", 3 }; static_assert ( *--sv.rend() == sv[0], "" ); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + static_assert ( *--u8sv.rend() == u8sv[0], "" ); +#endif static_assert ( *--u16sv.rend() == u16sv[0], "" ); static_assert ( *--u32sv.rend() == u32sv[0], "" ); static_assert ( *--wsv.rend() == wsv[0], "" ); static_assert ( *--sv.crend() == sv[0], "" ); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + static_assert ( *--u8sv.crend() == u8sv[0], "" ); +#endif static_assert ( *--u16sv.crend() == u16sv[0], "" ); static_assert ( *--u32sv.crend() == u32sv[0], "" ); static_assert ( *--wsv.crend() == wsv[0], "" ); diff --git a/test/std/strings/string.view/string_view.literals/literal.pass.cpp b/test/std/strings/string.view/string_view.literals/literal.pass.cpp index 079533829..cc2202e83 100644 --- a/test/std/strings/string.view/string_view.literals/literal.pass.cpp +++ b/test/std/strings/string.view/string_view.literals/literal.pass.cpp @@ -18,65 +18,55 @@ #include "test_macros.h" +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + typedef std::u8string_view u8string_view; +#else + typedef std::string_view u8string_view; +#endif + int main() { using namespace std::literals::string_view_literals; static_assert ( std::is_same::value, "" ); -// This is changed by P0482 to return a std::u8string - re-enable when we implement that. -#if TEST_STD_VER <= 17 - static_assert ( std::is_same::value, "" ); -#endif + static_assert ( std::is_same::value, "" ); static_assert ( std::is_same::value, "" ); static_assert ( std::is_same::value, "" ); static_assert ( std::is_same::value, "" ); std::string_view foo; std::wstring_view Lfoo; + u8string_view u8foo; std::u16string_view ufoo; std::u32string_view Ufoo; - foo = ""sv; assert( foo.size() == 0); -// This is changed by P0482 to return a std::u8string - re-enable when we implement that. -#if TEST_STD_VER <= 17 - foo = u8""sv; assert( foo.size() == 0); -#endif - Lfoo = L""sv; assert(Lfoo.size() == 0); - ufoo = u""sv; assert(ufoo.size() == 0); - Ufoo = U""sv; assert(Ufoo.size() == 0); + + foo = ""sv; assert( foo.size() == 0); + u8foo = u8""sv; assert(u8foo.size() == 0); + Lfoo = L""sv; assert( Lfoo.size() == 0); + ufoo = u""sv; assert( ufoo.size() == 0); + Ufoo = U""sv; assert( Ufoo.size() == 0); - foo = " "sv; assert( foo.size() == 1); -// This is changed by P0482 to return a std::u8string - re-enable when we implement that. -#if TEST_STD_VER <= 17 - foo = u8" "sv; assert( foo.size() == 1); -#endif - Lfoo = L" "sv; assert(Lfoo.size() == 1); - ufoo = u" "sv; assert(ufoo.size() == 1); - Ufoo = U" "sv; assert(Ufoo.size() == 1); + foo = " "sv; assert( foo.size() == 1); + u8foo = u8" "sv; assert(u8foo.size() == 1); + Lfoo = L" "sv; assert( Lfoo.size() == 1); + ufoo = u" "sv; assert( ufoo.size() == 1); + Ufoo = U" "sv; assert( Ufoo.size() == 1); - foo = "ABC"sv; assert( foo == "ABC"); assert( foo == std::string_view ( "ABC")); -// This is changed by P0482 to return a std::u8string - re-enable when we implement that. -#if TEST_STD_VER <= 17 - foo = u8"ABC"sv; assert( foo == u8"ABC"); assert( foo == std::string_view (u8"ABC")); -#endif - Lfoo = L"ABC"sv; assert(Lfoo == L"ABC"); assert(Lfoo == std::wstring_view ( L"ABC")); - ufoo = u"ABC"sv; assert(ufoo == u"ABC"); assert(ufoo == std::u16string_view( u"ABC")); - Ufoo = U"ABC"sv; assert(Ufoo == U"ABC"); assert(Ufoo == std::u32string_view( U"ABC")); + foo = "ABC"sv; assert( foo == "ABC"); assert( foo == std::string_view ( "ABC")); + u8foo = u8"ABC"sv; assert(u8foo == u8"ABC"); assert(u8foo == u8string_view (u8"ABC")); + Lfoo = L"ABC"sv; assert( Lfoo == L"ABC"); assert( Lfoo == std::wstring_view ( L"ABC")); + ufoo = u"ABC"sv; assert( ufoo == u"ABC"); assert( ufoo == std::u16string_view( u"ABC")); + Ufoo = U"ABC"sv; assert( Ufoo == U"ABC"); assert( Ufoo == std::u32string_view( U"ABC")); static_assert( "ABC"sv.size() == 3, ""); -// This is changed by P0482 to return a std::u8string - re-enable when we implement that. -#if TEST_STD_VER <= 17 static_assert(u8"ABC"sv.size() == 3, ""); -#endif static_assert( L"ABC"sv.size() == 3, ""); static_assert( u"ABC"sv.size() == 3, ""); static_assert( U"ABC"sv.size() == 3, ""); static_assert(noexcept( "ABC"sv), ""); -// This is changed by P0482 to return a std::u8string - re-enable when we implement that. -#if TEST_STD_VER <= 17 static_assert(noexcept(u8"ABC"sv), ""); -#endif static_assert(noexcept( L"ABC"sv), ""); static_assert(noexcept( u"ABC"sv), ""); static_assert(noexcept( U"ABC"sv), ""); diff --git a/test/std/strings/string.view/types.pass.cpp b/test/std/strings/string.view/types.pass.cpp index 4c29959f0..2763f7fb4 100644 --- a/test/std/strings/string.view/types.pass.cpp +++ b/test/std/strings/string.view/types.pass.cpp @@ -72,6 +72,9 @@ int main() { test >(); test >(); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test >(); +#endif static_assert((std::is_same::traits_type, std::char_traits >::value), ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp index fa81b11b7..85c2c9817 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp @@ -85,7 +85,7 @@ int main() test_is_integral(); test_is_integral(); test_is_integral(); -#if TEST_STD_VER > 17 && defined(__cpp_char8_t) +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L test_is_integral(); #endif From 544d1ba9a388daf614f0d0d55d1b2c125757c857 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Tue, 11 Dec 2018 06:06:49 +0000 Subject: [PATCH 17/94] Fix problems with char8_t stuff on compilers that don't support char8_t yet git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348829 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../support.limits.general/atomic.version.pass.cpp | 2 +- .../support.limits.general/filesystem.version.pass.cpp | 2 +- .../support.limits.general/istream.version.pass.cpp | 2 +- .../support.limits.general/limits.version.pass.cpp | 2 +- .../support.limits.general/locale.version.pass.cpp | 2 +- .../support.limits.general/ostream.version.pass.cpp | 2 +- .../support.limits.general/string.version.pass.cpp | 2 +- .../support.limits.general/string_view.version.pass.cpp | 2 +- .../support.limits.general/version.version.pass.cpp | 2 +- .../char.traits.specializations.char8_t/compare.pass.cpp | 6 ++++-- 10 files changed, 13 insertions(+), 11 deletions(-) diff --git a/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp index a990cab9b..78ee09d2f 100644 --- a/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp @@ -27,7 +27,7 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. -#if TEST_STD_VER > 17 +#if TEST_STD_VER > 17 && defined(__cpp_char8_t) # if !defined(__cpp_lib_char8_t) LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); # else diff --git a/test/std/language.support/support.limits/support.limits.general/filesystem.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/filesystem.version.pass.cpp index 160a997ce..4d03634c2 100644 --- a/test/std/language.support/support.limits/support.limits.general/filesystem.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/filesystem.version.pass.cpp @@ -24,7 +24,7 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. -#if TEST_STD_VER > 17 +#if TEST_STD_VER > 17 && defined(__cpp_char8_t) # if !defined(__cpp_lib_char8_t) LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); # else diff --git a/test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp index dfa0052e4..7ede323ca 100644 --- a/test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp @@ -23,7 +23,7 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. -#if TEST_STD_VER > 17 +#if TEST_STD_VER > 17 && defined(__cpp_char8_t) # if !defined(__cpp_lib_char8_t) LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); # else diff --git a/test/std/language.support/support.limits/support.limits.general/limits.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/limits.version.pass.cpp index 5d4997153..7f1869237 100644 --- a/test/std/language.support/support.limits/support.limits.general/limits.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/limits.version.pass.cpp @@ -23,7 +23,7 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. -#if TEST_STD_VER > 17 +#if TEST_STD_VER > 17 && defined(__cpp_char8_t) # if !defined(__cpp_lib_char8_t) LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); # else diff --git a/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp index 4c45c0a54..602273329 100644 --- a/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp @@ -23,7 +23,7 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. -#if TEST_STD_VER > 17 +#if TEST_STD_VER > 17 && defined(__cpp_char8_t) # if !defined(__cpp_lib_char8_t) LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); # else diff --git a/test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp index 5f2ffb296..668b39e32 100644 --- a/test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp @@ -23,7 +23,7 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. -#if TEST_STD_VER > 17 +#if TEST_STD_VER > 17 && defined(__cpp_char8_t) # if !defined(__cpp_lib_char8_t) LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); # else diff --git a/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp index 02aa15c77..2f408b988 100644 --- a/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp @@ -27,7 +27,7 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. -#if TEST_STD_VER > 17 +#if TEST_STD_VER > 17 && defined(__cpp_char8_t) # if !defined(__cpp_lib_char8_t) LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); # else diff --git a/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp index 82f1c66dd..bbdeb0b5a 100644 --- a/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp @@ -24,7 +24,7 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. -#if TEST_STD_VER > 17 +#if TEST_STD_VER > 17 && defined(__cpp_char8_t) # if !defined(__cpp_lib_char8_t) LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); # else diff --git a/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp index f4be2eb09..e2179e08a 100644 --- a/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp @@ -127,7 +127,7 @@ int main() # endif #endif -#if TEST_STD_VER > 17 +#if TEST_STD_VER > 17 && defined(__cpp_char8_t) # if !defined(__cpp_lib_char8_t) LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); # else diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp index 0ce036a97..5ab1c9f0b 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp @@ -19,6 +19,7 @@ #include "test_macros.h" +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L constexpr bool test_constexpr() { return std::char_traits::compare(u8"123", u8"223", 3) < 0 @@ -29,7 +30,6 @@ constexpr bool test_constexpr() int main() { -#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L assert(std::char_traits::compare(u8"", u8"", 0) == 0); assert(std::char_traits::compare(NULL, NULL, 0) == 0); @@ -52,5 +52,7 @@ int main() assert(std::char_traits::compare(u8"124", u8"123", 3) > 0); static_assert(test_constexpr(), "" ); -#endif } +#else +int main () {} +#endif From 31355b0538e57e91a3a0d92e7c5bafbf6272e3ba Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Tue, 11 Dec 2018 14:15:54 +0000 Subject: [PATCH 18/94] [libcxx] Fix test on compilers that do not support char8_t yet git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348846 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../char.traits.specializations.char8_t/length.pass.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/length.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/length.pass.cpp index 19f6c1e8d..f200c2332 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/length.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/length.pass.cpp @@ -19,6 +19,7 @@ #include "test_macros.h" +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L constexpr bool test_constexpr() { return std::char_traits::length(u8"") == 0 @@ -27,7 +28,6 @@ constexpr bool test_constexpr() int main() { -#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L assert(std::char_traits::length(u8"") == 0); assert(std::char_traits::length(u8"a") == 1); assert(std::char_traits::length(u8"aa") == 2); @@ -35,5 +35,7 @@ int main() assert(std::char_traits::length(u8"aaaa") == 4); static_assert(test_constexpr(), ""); -#endif } +#else +int main() { } +#endif From bca4d67c16095cff106569bfc9e5b12b6e0d080c Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Tue, 11 Dec 2018 14:22:28 +0000 Subject: [PATCH 19/94] [pair] Mark constructors as conditionally noexcept Summary: std::tuple marks its constructors as noexcept when the corresponding memberwise constructors are noexcept too -- this commit improves std::pair so that it behaves the same. This is a re-application of r348824, which broke the build in C++03 mode because a test was marked as supported in C++03 when it shouldn't be. Note: I did not add support in the explicit and non-explicit `pair(_Tuple&& __p)` constructors because those are non-standard extensions, and supporting them properly is tedious (we have to copy the rvalue-referenceness of the deduced _Tuple&& onto the result of tuple_element). Reviewers: mclow.lists, EricWF Subscribers: christof, llvm-commits Differential Revision: https://reviews.llvm.org/D48669 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348847 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/utility | 22 ++++- .../utility/pairs/pairs.pair/U_V.pass.cpp | 54 ++++++++++++ .../const_first_const_second.pass.cpp | 62 +++++++++++++ .../pairs/pairs.pair/const_pair_U_V.pass.cpp | 64 ++++++++++++++ .../utility/pairs/pairs.pair/default.pass.cpp | 31 +++++++ .../pairs/pairs.pair/piecewise.pass.cpp | 38 ++++++++ .../pairs/pairs.pair/rv_pair_U_V.pass.cpp | 63 ++++++++++++++ .../pairs/pairs.pair/piecewise.pass.cpp | 5 +- test/support/archetypes.hpp | 9 +- test/support/archetypes.ipp | 86 ++++++++++--------- 10 files changed, 388 insertions(+), 46 deletions(-) create mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp create mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp create mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp create mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp create mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp create mode 100644 test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp diff --git a/include/utility b/include/utility index ddfa27e22..fb7f44705 100644 --- a/include/utility +++ b/include/utility @@ -409,13 +409,17 @@ struct _LIBCPP_TEMPLATE_VIS pair _CheckArgsDep<_Dummy>::template __enable_default<_T1, _T2>() > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - pair() : first(), second() {} + pair() _NOEXCEPT_(is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value) + : first(), second() {} template ::template __enable_explicit<_T1 const&, _T2 const&>() > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(_T1 const& __t1, _T2 const& __t2) + _NOEXCEPT_(is_nothrow_copy_constructible::value && + is_nothrow_copy_constructible::value) : first(__t1), second(__t2) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(_T1 const& __t1, _T2 const& __t2) + _NOEXCEPT_(is_nothrow_copy_constructible::value && + is_nothrow_copy_constructible::value) : first(__t1), second(__t2) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(_U1&& __u1, _U2&& __u2) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(_U1&& __u1, _U2&& __u2) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(pair<_U1, _U2> const& __p) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(__p.first), second(__p.second) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(pair<_U1, _U2> const& __p) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(__p.first), second(__p.second) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(pair<_U1, _U2>&&__p) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} template = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(pair<_U1, _U2>&& __p) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} template __first_args, tuple<_Args2...> __second_args) + _NOEXCEPT_((is_nothrow_constructible::value && + is_nothrow_constructible::value)) : pair(__pc, __first_args, __second_args, typename __make_tuple_indices::type(), typename __make_tuple_indices::type()) {} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp new file mode 100644 index 000000000..6a3e613e9 --- /dev/null +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// template pair(U&& x, V&& y); + +#include + + +struct ExplicitT { + constexpr explicit ExplicitT(int x) : value(x) {} + int value; +}; + +struct ImplicitT { + constexpr ImplicitT(int x) : value(x) {} + int value; +}; + +struct ExplicitNothrowT { + explicit ExplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +struct ImplicitNothrowT { + ImplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +int main() { + { // explicit noexcept test + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert( std::is_nothrow_constructible, int, int>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible, int, int>::value, ""); + static_assert( std::is_nothrow_constructible, int, int>::value, ""); + } +} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp new file mode 100644 index 000000000..6a2401223 --- /dev/null +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// pair(const T1& x, const T2& y); + +#include + + +struct ExplicitT { + constexpr explicit ExplicitT(int x) : value(x) {} + constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {} + int value; +}; + +struct ImplicitT { + constexpr ImplicitT(int x) : value(x) {} + constexpr ImplicitT(ImplicitT const& o) : value(o.value) {} + int value; +}; + +struct ExplicitNothrowT { + explicit ExplicitNothrowT(ExplicitNothrowT const&) noexcept {} +}; + +struct ImplicitNothrowT { + ImplicitNothrowT(ImplicitNothrowT const&) noexcept {} +}; + +int main() { + { // explicit noexcept test + static_assert(!std::is_nothrow_constructible, + ExplicitT const&, ExplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + ExplicitNothrowT const&, ExplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + ExplicitT const&, ExplicitNothrowT const&>::value, ""); + static_assert( std::is_nothrow_constructible, + ExplicitNothrowT const&, ExplicitNothrowT const&>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible, + ImplicitT const&, ImplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + ImplicitNothrowT const&, ImplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + ImplicitT const&, ImplicitNothrowT const&>::value, ""); + static_assert( std::is_nothrow_constructible, + ImplicitNothrowT const&, ImplicitNothrowT const&>::value, ""); + } +} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp new file mode 100644 index 000000000..edb3bbf64 --- /dev/null +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// template EXPLICIT constexpr pair(const pair& p); + +#include + + +struct ExplicitT { + constexpr explicit ExplicitT(int x) : value(x) {} + constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {} + int value; +}; + +struct ImplicitT { + constexpr ImplicitT(int x) : value(x) {} + constexpr ImplicitT(ImplicitT const& o) : value(o.value) {} + int value; +}; + +struct ExplicitNothrowT { + explicit ExplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +struct ImplicitNothrowT { + ImplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +int main() { + { // explicit noexcept test + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert( std::is_nothrow_constructible, + std::pair const&>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair const&>::value, ""); + static_assert( std::is_nothrow_constructible, + std::pair const&>::value, ""); + } +} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp new file mode 100644 index 000000000..07425cff1 --- /dev/null +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// constexpr pair(); + +#include +#include + +#include "archetypes.hpp" + + +int main() { + using NonThrowingDefault = NonThrowingTypes::DefaultOnly; + using ThrowingDefault = NonTrivialTypes::DefaultOnly; + static_assert(!std::is_nothrow_default_constructible>::value, ""); + static_assert(!std::is_nothrow_default_constructible>::value, ""); + static_assert(!std::is_nothrow_default_constructible>::value, ""); + static_assert( std::is_nothrow_default_constructible>::value, ""); +} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp new file mode 100644 index 000000000..81dad3bc2 --- /dev/null +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// template +// pair(piecewise_construct_t, tuple first_args, +// tuple second_args); + +#include +#include +#include + +#include "archetypes.hpp" + + +int main() { + using NonThrowingConvert = NonThrowingTypes::ConvertingType; + using ThrowingConvert = NonTrivialTypes::ConvertingType; + static_assert(!std::is_nothrow_constructible, + std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); + static_assert( std::is_nothrow_constructible, + std::piecewise_construct_t, std::tuple, std::tuple>::value, ""); +} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp new file mode 100644 index 000000000..5d8d36262 --- /dev/null +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// template struct pair + +// template pair(pair&& p); + +#include +#include + + +struct ExplicitT { + constexpr explicit ExplicitT(int x) : value(x) {} + int value; +}; + +struct ImplicitT { + constexpr ImplicitT(int x) : value(x) {} + int value; +}; + +struct ExplicitNothrowT { + explicit ExplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +struct ImplicitNothrowT { + ImplicitNothrowT(int x) noexcept : value(x) {} + int value; +}; + +int main() { + { // explicit noexcept test + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert( std::is_nothrow_constructible, + std::pair&&>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert(!std::is_nothrow_constructible, + std::pair&&>::value, ""); + static_assert( std::is_nothrow_constructible, + std::pair&&>::value, ""); + } +} diff --git a/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp index c738adad7..aa86949dd 100644 --- a/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp +++ b/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp @@ -17,9 +17,10 @@ // pair(piecewise_construct_t, tuple first_args, // tuple second_args); -#include -#include #include +#include +#include + int main() { diff --git a/test/support/archetypes.hpp b/test/support/archetypes.hpp index 1695a6fc6..a0ea7c3ce 100644 --- a/test/support/archetypes.hpp +++ b/test/support/archetypes.hpp @@ -225,7 +225,6 @@ namespace ExplicitTypes { #include "archetypes.ipp" } - //============================================================================// // namespace NonConstexprTypes { @@ -241,12 +240,18 @@ namespace NonLiteralTypes { #include "archetypes.ipp" } +//============================================================================// +// Non-throwing implicit test types +namespace NonThrowingTypes { +#define DEFINE_NOEXCEPT noexcept +#include "archetypes.ipp" +} + //============================================================================// // Non-Trivially Copyable Implicit Test Types namespace NonTrivialTypes { #define DEFINE_CTOR {} #define DEFINE_ASSIGN { return *this; } -#define DEFINE_DEFAULT_CTOR = default #include "archetypes.ipp" } diff --git a/test/support/archetypes.ipp b/test/support/archetypes.ipp index 360450179..943dcf9f5 100644 --- a/test/support/archetypes.ipp +++ b/test/support/archetypes.ipp @@ -5,6 +5,9 @@ #ifndef DEFINE_EXPLICIT #define DEFINE_EXPLICIT #endif +#ifndef DEFINE_NOEXCEPT +#define DEFINE_NOEXCEPT +#endif #ifndef DEFINE_CONSTEXPR #ifdef TEST_WORKAROUND_EDG_EXPLICIT_CONSTEXPR #define DEFINE_CONSTEXPR @@ -36,114 +39,114 @@ struct AllCtors : DEFINE_BASE(AllCtors) { using Base = DEFINE_BASE(AllCtors); using Base::Base; using Base::operator=; - DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors const&) DEFINE_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors &&) DEFINE_CTOR; - DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors const&) DEFINE_ASSIGN; - DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors &&) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors const&) DEFINE_NOEXCEPT DEFINE_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors &&) DEFINE_NOEXCEPT DEFINE_CTOR; + DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; + DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(AllCtors) }; struct NoCtors : DEFINE_BASE(NoCtors) { using Base = DEFINE_BASE(NoCtors); - DEFINE_EXPLICIT NoCtors() = delete; - DEFINE_EXPLICIT NoCtors(NoCtors const&) = delete; - NoCtors& operator=(NoCtors const&) = delete; + DEFINE_EXPLICIT NoCtors() DEFINE_NOEXCEPT = delete; + DEFINE_EXPLICIT NoCtors(NoCtors const&) DEFINE_NOEXCEPT = delete; + NoCtors& operator=(NoCtors const&) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(NoCtors) }; struct NoDefault : DEFINE_BASE(NoDefault) { using Base = DEFINE_BASE(NoDefault); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR NoDefault() = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR NoDefault() DEFINE_NOEXCEPT = delete; DEFINE_DTOR(NoDefault) }; struct DefaultOnly : DEFINE_BASE(DefaultOnly) { using Base = DEFINE_BASE(DefaultOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR DefaultOnly() DEFINE_DEFAULT_CTOR; - DefaultOnly(DefaultOnly const&) = delete; - DefaultOnly& operator=(DefaultOnly const&) = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR DefaultOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DefaultOnly(DefaultOnly const&) DEFINE_NOEXCEPT = delete; + DefaultOnly& operator=(DefaultOnly const&) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(DefaultOnly) }; struct Copyable : DEFINE_BASE(Copyable) { using Base = DEFINE_BASE(Copyable); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable(Copyable const &) DEFINE_CTOR; - Copyable &operator=(Copyable const &) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable(Copyable const &) DEFINE_NOEXCEPT DEFINE_CTOR; + Copyable &operator=(Copyable const &) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(Copyable) }; struct CopyOnly : DEFINE_BASE(CopyOnly) { using Base = DEFINE_BASE(CopyOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly const &) DEFINE_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly &&) = delete; - CopyOnly &operator=(CopyOnly const &) DEFINE_ASSIGN; - CopyOnly &operator=(CopyOnly &&) = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly const &) DEFINE_NOEXCEPT DEFINE_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly &&) DEFINE_NOEXCEPT = delete; + CopyOnly &operator=(CopyOnly const &) DEFINE_NOEXCEPT DEFINE_ASSIGN; + CopyOnly &operator=(CopyOnly &&) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(CopyOnly) }; struct NonCopyable : DEFINE_BASE(NonCopyable) { using Base = DEFINE_BASE(NonCopyable); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable(NonCopyable const &) = delete; - NonCopyable &operator=(NonCopyable const &) = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable(NonCopyable const &) DEFINE_NOEXCEPT = delete; + NonCopyable &operator=(NonCopyable const &) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(NonCopyable) }; struct MoveOnly : DEFINE_BASE(MoveOnly) { using Base = DEFINE_BASE(MoveOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly(MoveOnly &&) DEFINE_CTOR; - MoveOnly &operator=(MoveOnly &&) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly(MoveOnly &&) DEFINE_NOEXCEPT DEFINE_CTOR; + MoveOnly &operator=(MoveOnly &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(MoveOnly) }; struct CopyAssignable : DEFINE_BASE(CopyAssignable) { using Base = DEFINE_BASE(CopyAssignable); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignable() = delete; - CopyAssignable& operator=(CopyAssignable const&) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignable() DEFINE_NOEXCEPT = delete; + CopyAssignable& operator=(CopyAssignable const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(CopyAssignable) }; struct CopyAssignOnly : DEFINE_BASE(CopyAssignOnly) { using Base = DEFINE_BASE(CopyAssignOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignOnly() = delete; - CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_ASSIGN; - CopyAssignOnly& operator=(CopyAssignOnly &&) = delete; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignOnly() DEFINE_NOEXCEPT = delete; + CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; + CopyAssignOnly& operator=(CopyAssignOnly &&) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(CopyAssignOnly) }; struct MoveAssignOnly : DEFINE_BASE(MoveAssignOnly) { using Base = DEFINE_BASE(MoveAssignOnly); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveAssignOnly() = delete; - MoveAssignOnly& operator=(MoveAssignOnly const&) = delete; - MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveAssignOnly() DEFINE_NOEXCEPT = delete; + MoveAssignOnly& operator=(MoveAssignOnly const&) DEFINE_NOEXCEPT = delete; + MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(MoveAssignOnly) }; struct ConvertingType : DEFINE_BASE(ConvertingType) { using Base = DEFINE_BASE(ConvertingType); using Base::Base; - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType() DEFINE_DEFAULT_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType const&) DEFINE_CTOR; - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType &&) DEFINE_CTOR; - ConvertingType& operator=(ConvertingType const&) DEFINE_ASSIGN; - ConvertingType& operator=(ConvertingType &&) DEFINE_ASSIGN; + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType const&) DEFINE_NOEXCEPT DEFINE_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType &&) DEFINE_NOEXCEPT DEFINE_CTOR; + ConvertingType& operator=(ConvertingType const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; + ConvertingType& operator=(ConvertingType &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; template - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(Args&&...) {} + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(Args&&...) DEFINE_NOEXCEPT {} template - ConvertingType& operator=(Arg&&) { return *this; } + ConvertingType& operator=(Arg&&) DEFINE_NOEXCEPT { return *this; } DEFINE_DTOR(ConvertingType) }; @@ -165,6 +168,7 @@ using ApplyTypes = List< #undef DEFINE_BASE #undef DEFINE_EXPLICIT +#undef DEFINE_NOEXCEPT #undef DEFINE_CONSTEXPR #undef DEFINE_ASSIGN_CONSTEXPR #undef DEFINE_CTOR From 649e69dd22bc9fdb9b85e504985aa4ff16aaf8a2 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Tue, 11 Dec 2018 15:27:10 +0000 Subject: [PATCH 20/94] [libcxx] Fix test failure on GCC 4.9 GCC 4.9 seems to think that a constexpr default constructor implies the constructor to be noexcept. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348850 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../utility/pairs/pairs.pair/default.pass.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp index 07425cff1..2dbf5511d 100644 --- a/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp @@ -18,12 +18,17 @@ #include #include -#include "archetypes.hpp" +struct ThrowingDefault { + ThrowingDefault() { } +}; + +struct NonThrowingDefault { + NonThrowingDefault() noexcept { } +}; int main() { - using NonThrowingDefault = NonThrowingTypes::DefaultOnly; - using ThrowingDefault = NonTrivialTypes::DefaultOnly; + static_assert(!std::is_nothrow_default_constructible>::value, ""); static_assert(!std::is_nothrow_default_constructible>::value, ""); static_assert(!std::is_nothrow_default_constructible>::value, ""); From 2fa05e61c8309676405764c335b806ab85ea6bc9 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Tue, 11 Dec 2018 17:05:20 +0000 Subject: [PATCH 21/94] [NFC] Fix incorrect (but unreachable) LIT error message It is unreachable because we test that the cxx_stdlib_under_test is in the supported set of libraries elsewhere. Furthermore, this code relied on the `use_stdlib_type`, which is never defined. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348867 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/libcxx/test/config.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/utils/libcxx/test/config.py b/utils/libcxx/test/config.py index dbb250e93..361c3d3cd 100644 --- a/utils/libcxx/test/config.py +++ b/utils/libcxx/test/config.py @@ -757,9 +757,7 @@ class Configuration(object): elif self.cxx_stdlib_under_test == 'cxx_default': self.cxx.link_flags += ['-pthread'] else: - self.lit_config.fatal( - 'unsupported value for "use_stdlib_type": %s' - % use_stdlib_type) + self.lit_config.fatal('invalid stdlib under test') link_flags_str = self.get_lit_conf('link_flags', '') self.cxx.link_flags += shlex.split(link_flags_str) From 3b06e97b9390e1defefe5d99eadbcb6b7c593649 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Tue, 11 Dec 2018 17:29:55 +0000 Subject: [PATCH 22/94] [libcxx] Remove the no_default_flags LIT configuration This is part of an ongoing cleanup of the LIT test suite, where I'm trying to reduce the number of configuration options. In this case, the original intent seemed to be running the test suite with libstdc++, but this is now supported by specifying cxx_stdlib_under_test=libstdc++. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348868 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/TestingLibcxx.rst | 8 ----- utils/libcxx/test/config.py | 66 +++++++++++++++++-------------------- 2 files changed, 31 insertions(+), 43 deletions(-) diff --git a/docs/TestingLibcxx.rst b/docs/TestingLibcxx.rst index 43c0684dc..48b7271c3 100644 --- a/docs/TestingLibcxx.rst +++ b/docs/TestingLibcxx.rst @@ -155,14 +155,6 @@ configuration. Passing the option on the command line will override the default. the default value. Otherwise the default value is True on Windows and False on every other platform. -.. option:: no_default_flags= - - **Default**: False - - Disable all default compile and link flags from being added. When this - option is used only flags specified using the compile_flags and link_flags - will be used. - .. option:: compile_flags="" Specify additional compile flags as a space delimited string. diff --git a/utils/libcxx/test/config.py b/utils/libcxx/test/config.py index 361c3d3cd..c944b6b21 100644 --- a/utils/libcxx/test/config.py +++ b/utils/libcxx/test/config.py @@ -485,13 +485,7 @@ class Configuration(object): self.config.available_features.add("objective-c++") def configure_compile_flags(self): - no_default_flags = self.get_lit_bool('no_default_flags', False) - if not no_default_flags: - self.configure_default_compile_flags() - # This include is always needed so add so add it regardless of - # 'no_default_flags'. - support_path = os.path.join(self.libcxx_src_root, 'test/support') - self.cxx.compile_flags += ['-I' + support_path] + self.configure_default_compile_flags() # Configure extra flags compile_flags_str = self.get_lit_conf('compile_flags', '') self.cxx.compile_flags += shlex.split(compile_flags_str) @@ -572,6 +566,10 @@ class Configuration(object): self.cxx.flags += ['-arch', arch] self.cxx.flags += ['-m' + name + '-version-min=' + version] + # Add includes for support headers used in the tests. + support_path = os.path.join(self.libcxx_src_root, 'test/support') + self.cxx.compile_flags += ['-I' + support_path] + # FIXME(EricWF): variant_size.pass.cpp requires a slightly larger # template depth with older Clang versions. self.cxx.addFlagIfSupported('-ftemplate-depth=270') @@ -729,35 +727,33 @@ class Configuration(object): def configure_link_flags(self): - no_default_flags = self.get_lit_bool('no_default_flags', False) - if not no_default_flags: - # Configure library path - self.configure_link_flags_cxx_library_path() - self.configure_link_flags_abi_library_path() + # Configure library path + self.configure_link_flags_cxx_library_path() + self.configure_link_flags_abi_library_path() - # Configure libraries - if self.cxx_stdlib_under_test == 'libc++': - self.cxx.link_flags += ['-nodefaultlibs'] - # FIXME: Handle MSVCRT as part of the ABI library handling. - if self.is_windows: - self.cxx.link_flags += ['-nostdlib'] - self.configure_link_flags_cxx_library() - self.configure_link_flags_abi_library() - self.configure_extra_library_flags() - elif self.cxx_stdlib_under_test == 'libstdc++': - enable_fs = self.get_lit_bool('enable_filesystem', - default=False) - if enable_fs: - self.config.available_features.add('c++experimental') - self.cxx.link_flags += ['-lstdc++fs'] - self.cxx.link_flags += ['-lm', '-pthread'] - elif self.cxx_stdlib_under_test == 'msvc': - # FIXME: Correctly setup debug/release flags here. - pass - elif self.cxx_stdlib_under_test == 'cxx_default': - self.cxx.link_flags += ['-pthread'] - else: - self.lit_config.fatal('invalid stdlib under test') + # Configure libraries + if self.cxx_stdlib_under_test == 'libc++': + self.cxx.link_flags += ['-nodefaultlibs'] + # FIXME: Handle MSVCRT as part of the ABI library handling. + if self.is_windows: + self.cxx.link_flags += ['-nostdlib'] + self.configure_link_flags_cxx_library() + self.configure_link_flags_abi_library() + self.configure_extra_library_flags() + elif self.cxx_stdlib_under_test == 'libstdc++': + enable_fs = self.get_lit_bool('enable_filesystem', + default=False) + if enable_fs: + self.config.available_features.add('c++experimental') + self.cxx.link_flags += ['-lstdc++fs'] + self.cxx.link_flags += ['-lm', '-pthread'] + elif self.cxx_stdlib_under_test == 'msvc': + # FIXME: Correctly setup debug/release flags here. + pass + elif self.cxx_stdlib_under_test == 'cxx_default': + self.cxx.link_flags += ['-pthread'] + else: + self.lit_config.fatal('invalid stdlib under test') link_flags_str = self.get_lit_conf('link_flags', '') self.cxx.link_flags += shlex.split(link_flags_str) From 682614cc53e42b89225af91e9684b9a3b85265ab Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Tue, 11 Dec 2018 18:05:38 +0000 Subject: [PATCH 23/94] [libcxx] Only enable the availability LIT feature when we're testing libc++ Other standard libraries don't implement availability markup, so it doesn't make sense to e.g. XFAIL tests based on availability markup outside of libc++. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348871 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/libcxx/test/config.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/utils/libcxx/test/config.py b/utils/libcxx/test/config.py index c944b6b21..1aa52ddbb 100644 --- a/utils/libcxx/test/config.py +++ b/utils/libcxx/test/config.py @@ -407,8 +407,10 @@ class Configuration(object): if self.use_deployment: self.add_deployment_feature('with_system_cxx_lib') - # Configure the availability feature. - if self.use_deployment: + # Configure the availability feature. Availability is only enabled + # with libc++, because other standard libraries do not provide + # availability markup. + if self.use_deployment and self.cxx_stdlib_under_test == 'libc++': self.config.available_features.add('availability') self.add_deployment_feature('availability') From 2d1346288e7bc3fc9509ff85838d84fc7763b813 Mon Sep 17 00:00:00 2001 From: Michal Gorny Date: Tue, 11 Dec 2018 18:29:35 +0000 Subject: [PATCH 24/94] [test] Permit NetBSD in filesystem_dynamic_test_helper.py git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348872 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/support/filesystem_dynamic_test_helper.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/support/filesystem_dynamic_test_helper.py b/test/support/filesystem_dynamic_test_helper.py index 081e678b6..5bb5b258c 100644 --- a/test/support/filesystem_dynamic_test_helper.py +++ b/test/support/filesystem_dynamic_test_helper.py @@ -4,7 +4,8 @@ import stat # Ensure that this is being run on a specific platform assert sys.platform.startswith('linux') or sys.platform.startswith('darwin') \ - or sys.platform.startswith('cygwin') or sys.platform.startswith('freebsd') + or sys.platform.startswith('cygwin') or sys.platform.startswith('freebsd') \ + or sys.platform.startswith('netbsd') def env_path(): ep = os.environ.get('LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT') From 413329eb3521cda5ffe2682c32bafd854ae94d92 Mon Sep 17 00:00:00 2001 From: Michal Gorny Date: Wed, 12 Dec 2018 20:20:15 +0000 Subject: [PATCH 25/94] [test] [filesystems] Extend FreeBSD tv_sec==-1 workaround to NetBSD NetBSD also uses tv_sec==-1 as error status indicator, and does not support setting such a value. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348967 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp b/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp index 7a17f9577..11152e6ab 100644 --- a/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp +++ b/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp @@ -427,7 +427,7 @@ TEST_CASE(set_last_write_time_dynamic_env_test) epoch_time - Minutes(3) - Sec(42) - SubSec(17); // FreeBSD has a bug in their utimes implementation where the time is not update // when the number of seconds is '-1'. -#if defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(__NetBSD__) const file_time_type just_before_epoch_time = epoch_time - Sec(2) - SubSec(17); #else From 13d947cc06961d544dff4934861e4ac09a70ec7e Mon Sep 17 00:00:00 2001 From: Michal Gorny Date: Wed, 12 Dec 2018 20:28:52 +0000 Subject: [PATCH 26/94] [test] [filesystems] NetBSD can do symlink permissions too git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348968 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../fs.op.funcs/fs.op.permissions/permissions.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp b/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp index cbe2b2d09..b5fb838dd 100644 --- a/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp +++ b/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp @@ -159,7 +159,7 @@ TEST_CASE(test_no_resolve_symlink_on_symlink) {perms::owner_all, perms::group_all, perm_options::remove}, }; for (auto const& TC : cases) { -#if defined(__APPLE__) || defined(__FreeBSD__) +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) // On OS X symlink permissions are supported. We should get an empty // error code and the expected permissions. const auto expected_link_perms = TC.expected; From f0c3a12346c56026f2a86bfe35bc57540fc8edfe Mon Sep 17 00:00:00 2001 From: Michal Gorny Date: Wed, 12 Dec 2018 20:51:46 +0000 Subject: [PATCH 27/94] [test] [depr.c.headers] XFAIL uchar.h on NetBSD git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348973 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/std/depr/depr.c.headers/uchar_h.pass.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/std/depr/depr.c.headers/uchar_h.pass.cpp b/test/std/depr/depr.c.headers/uchar_h.pass.cpp index f12169845..be4ea0dae 100644 --- a/test/std/depr/depr.c.headers/uchar_h.pass.cpp +++ b/test/std/depr/depr.c.headers/uchar_h.pass.cpp @@ -10,6 +10,7 @@ // XFAIL: suse-linux-enterprise-server-11 // XFAIL: apple-darwin // XFAIL: newlib +// XFAIL: netbsd // From f77ee9b3c983dd641a3c4a449554cc878d650dc5 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Wed, 12 Dec 2018 23:58:25 +0000 Subject: [PATCH 28/94] [libcxx] Add assertion in deque::pop_back when popping from an empty deque Also, add tests making sure that vector and deque both catch the problem when assertions are enabled. Otherwise, deque would segfault and vector would never terminate. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@348994 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/deque | 9 ++++--- .../sequences/deque/pop_back_empty.pass.cpp | 25 +++++++++++++++++++ .../sequences/vector/pop_back_empty.pass.cpp | 25 +++++++++++++++++++ 3 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 test/libcxx/containers/sequences/deque/pop_back_empty.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/pop_back_empty.pass.cpp diff --git a/include/deque b/include/deque index 414c7a859..c232e53c3 100644 --- a/include/deque +++ b/include/deque @@ -987,7 +987,7 @@ public: #if _LIBCPP_STD_VER >= 14 _NOEXCEPT; #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable::value); #endif protected: @@ -1156,7 +1156,7 @@ __deque_base<_Tp, _Allocator>::swap(__deque_base& __c) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable::value) #endif { @@ -2342,7 +2342,7 @@ deque<_Tp, _Allocator>::__add_front_capacity() _Dp(__a, __base::__block_size)); __buf.push_back(__hold.get()); __hold.release(); - + for (typename __base::__map_pointer __i = __base::__map_.begin(); __i != __base::__map_.end(); ++__i) __buf.push_back(*__i); @@ -2604,6 +2604,7 @@ template void deque<_Tp, _Allocator>::pop_back() { + _LIBCPP_ASSERT(!empty(), "deque::pop_back called for empty deque"); allocator_type& __a = __base::__alloc(); size_type __p = __base::size() + __base::__start_ - 1; __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() + @@ -2854,7 +2855,7 @@ deque<_Tp, _Allocator>::swap(deque& __c) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable::value) #endif { diff --git a/test/libcxx/containers/sequences/deque/pop_back_empty.pass.cpp b/test/libcxx/containers/sequences/deque/pop_back_empty.pass.cpp new file mode 100644 index 000000000..1435f9563 --- /dev/null +++ b/test/libcxx/containers/sequences/deque/pop_back_empty.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// pop_back() more than the number of elements in a deque + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include + + +int main() { + std::deque q; + q.push_back(0); + q.pop_back(); + q.pop_back(); +} diff --git a/test/libcxx/containers/sequences/vector/pop_back_empty.pass.cpp b/test/libcxx/containers/sequences/vector/pop_back_empty.pass.cpp new file mode 100644 index 000000000..4714912ae --- /dev/null +++ b/test/libcxx/containers/sequences/vector/pop_back_empty.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// pop_back() more than the number of elements in a vector + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include + + +int main() { + std::vector v; + v.push_back(0); + v.pop_back(); + v.pop_back(); +} From d3f2d5ec4e82dcec69e3887b0847f6969d9b6b3c Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Thu, 13 Dec 2018 18:53:17 +0000 Subject: [PATCH 29/94] [libcxx] Fix pop_back() tests to make sure they don't always just pass git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349071 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/libcxx/containers/sequences/deque/pop_back_empty.pass.cpp | 1 + test/libcxx/containers/sequences/vector/pop_back_empty.pass.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/test/libcxx/containers/sequences/deque/pop_back_empty.pass.cpp b/test/libcxx/containers/sequences/deque/pop_back_empty.pass.cpp index 1435f9563..e4f5d0b01 100644 --- a/test/libcxx/containers/sequences/deque/pop_back_empty.pass.cpp +++ b/test/libcxx/containers/sequences/deque/pop_back_empty.pass.cpp @@ -22,4 +22,5 @@ int main() { q.push_back(0); q.pop_back(); q.pop_back(); + std::exit(1); } diff --git a/test/libcxx/containers/sequences/vector/pop_back_empty.pass.cpp b/test/libcxx/containers/sequences/vector/pop_back_empty.pass.cpp index 4714912ae..388dfa4e1 100644 --- a/test/libcxx/containers/sequences/vector/pop_back_empty.pass.cpp +++ b/test/libcxx/containers/sequences/vector/pop_back_empty.pass.cpp @@ -22,4 +22,5 @@ int main() { v.push_back(0); v.pop_back(); v.pop_back(); + std::exit(1); } From e713cc0acf1ae8b82f451bf58ebef67a46ceddfb Mon Sep 17 00:00:00 2001 From: Thomas Anderson Date: Thu, 13 Dec 2018 20:06:14 +0000 Subject: [PATCH 30/94] [libc++] Fix _LIBCPP_EXPORTED_FROM_ABI when visibility annotations are disabled Fixes a bug where functions would get exported when building with -fvisibility=hidden and defining _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS. No visibility annotations should be added in this case. The new logic for _LIBCPP_EXPORTED_FROM_ABI matches that of the other visibility annotations around it. Differential Revision: https://reviews.llvm.org/D55664 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349080 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/__config | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/__config b/include/__config index 88c207c72..b5e7b7632 100644 --- a/include/__config +++ b/include/__config @@ -715,7 +715,11 @@ typedef __char32_t char32_t; #endif #ifndef _LIBCPP_EXPORTED_FROM_ABI -# define _LIBCPP_EXPORTED_FROM_ABI __attribute__((__visibility__("default"))) +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_EXPORTED_FROM_ABI __attribute__((__visibility__("default"))) +# else +# define _LIBCPP_EXPORTED_FROM_ABI +# endif #endif #ifndef _LIBCPP_OVERRIDABLE_FUNC_VIS From 114125f97b7b321f2447d45ecfa12a0d4ee5d07f Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Fri, 14 Dec 2018 03:37:13 +0000 Subject: [PATCH 31/94] Update google benchmark version git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349126 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/google-benchmark/BUILD.bazel | 42 ------------- utils/google-benchmark/CONTRIBUTORS | 1 + utils/google-benchmark/README.md | 24 ++++++- .../include/benchmark/benchmark.h | 10 +++ utils/google-benchmark/src/benchmark.cc | 6 +- .../src/benchmark_register.cc | 11 +++- utils/google-benchmark/src/complexity.cc | 4 +- utils/google-benchmark/src/json_reporter.cc | 2 + utils/google-benchmark/src/reporter.cc | 3 +- utils/google-benchmark/src/string_util.h | 6 +- utils/google-benchmark/src/sysinfo.cc | 38 ++++++++++++ .../test/output_test_helper.cc | 44 ++++++++++++- .../test/reporter_output_test.cc | 13 ++++ .../test/string_util_gtest.cc | 62 +++++++++---------- utils/google-benchmark/tools/compare.py | 6 +- utils/google-benchmark/tools/gbench/report.py | 7 +-- utils/google-benchmark/tools/gbench/util.py | 15 +++-- 17 files changed, 194 insertions(+), 100 deletions(-) delete mode 100644 utils/google-benchmark/BUILD.bazel diff --git a/utils/google-benchmark/BUILD.bazel b/utils/google-benchmark/BUILD.bazel deleted file mode 100644 index 6ee69f290..000000000 --- a/utils/google-benchmark/BUILD.bazel +++ /dev/null @@ -1,42 +0,0 @@ -licenses(["notice"]) - -config_setting( - name = "windows", - values = { - "cpu": "x64_windows", - }, - visibility = [":__subpackages__"], -) - -cc_library( - name = "benchmark", - srcs = glob( - [ - "src/*.cc", - "src/*.h", - ], - exclude = ["src/benchmark_main.cc"], - ), - hdrs = ["include/benchmark/benchmark.h"], - linkopts = select({ - ":windows": ["-DEFAULTLIB:shlwapi.lib"], - "//conditions:default": ["-pthread"], - }), - strip_include_prefix = "include", - visibility = ["//visibility:public"], -) - -cc_library( - name = "benchmark_main", - srcs = ["src/benchmark_main.cc"], - hdrs = ["include/benchmark/benchmark.h"], - strip_include_prefix = "include", - visibility = ["//visibility:public"], - deps = [":benchmark"], -) - -cc_library( - name = "benchmark_internal_headers", - hdrs = glob(["src/*.h"]), - visibility = ["//test:__pkg__"], -) diff --git a/utils/google-benchmark/CONTRIBUTORS b/utils/google-benchmark/CONTRIBUTORS index f727bd1d0..ee74ff886 100644 --- a/utils/google-benchmark/CONTRIBUTORS +++ b/utils/google-benchmark/CONTRIBUTORS @@ -27,6 +27,7 @@ Arne Beer Billy Robert O'Neal III Chris Kennelly Christopher Seymour +Cyrille Faucheux David Coeurjolly Deniz Evrenci Dominic Hamon diff --git a/utils/google-benchmark/README.md b/utils/google-benchmark/README.md index 38203958f..858ea2334 100644 --- a/utils/google-benchmark/README.md +++ b/utils/google-benchmark/README.md @@ -255,7 +255,7 @@ that might be used to customize high-order term calculation. ```c++ BENCHMARK(BM_StringCompare)->RangeMultiplier(2) - ->Range(1<<10, 1<<18)->Complexity([](int n)->double{return n; }); + ->Range(1<<10, 1<<18)->Complexity([](int64_t n)->double{return n; }); ``` ### Templated benchmarks @@ -264,7 +264,7 @@ messages of size `sizeof(v)` `range_x` times. It also outputs throughput in the absence of multiprogramming. ```c++ -template int BM_Sequential(benchmark::State& state) { +template void BM_Sequential(benchmark::State& state) { Q q; typename Q::value_type v; for (auto _ : state) { @@ -428,6 +428,26 @@ BENCHMARK(BM_test)->Range(8, 8<<10)->UseRealTime(); Without `UseRealTime`, CPU time is used by default. +## Controlling timers +Normally, the entire duration of the work loop (`for (auto _ : state) {}`) +is measured. But sometimes, it is nessesary to do some work inside of +that loop, every iteration, but without counting that time to the benchmark time. +That is possible, althought it is not recommended, since it has high overhead. + +```c++ +static void BM_SetInsert_With_Timer_Control(benchmark::State& state) { + std::set data; + for (auto _ : state) { + state.PauseTiming(); // Stop timers. They will not count until they are resumed. + data = ConstructRandomSet(state.range(0)); // Do something that should not be measured + state.ResumeTiming(); // And resume timers. They are now counting again. + // The rest will be measured. + for (int j = 0; j < state.range(1); ++j) + data.insert(RandomNumber()); + } +} +BENCHMARK(BM_SetInsert_With_Timer_Control)->Ranges({{1<<10, 8<<10}, {128, 512}}); +``` ## Manual timing For benchmarking something for which neither CPU time nor real-time are diff --git a/utils/google-benchmark/include/benchmark/benchmark.h b/utils/google-benchmark/include/benchmark/benchmark.h index 1f072b135..a0fd7c6e1 100644 --- a/utils/google-benchmark/include/benchmark/benchmark.h +++ b/utils/google-benchmark/include/benchmark/benchmark.h @@ -1293,6 +1293,15 @@ struct CPUInfo { BENCHMARK_DISALLOW_COPY_AND_ASSIGN(CPUInfo); }; +//Adding Struct for System Information +struct SystemInfo { + std::string name; + static const SystemInfo& Get(); + private: + SystemInfo(); + BENCHMARK_DISALLOW_COPY_AND_ASSIGN(SystemInfo); +}; + // Interface for custom benchmark result printers. // By default, benchmark reports are printed to stdout. However an application // can control the destination of the reports by calling @@ -1302,6 +1311,7 @@ class BenchmarkReporter { public: struct Context { CPUInfo const& cpu_info; + SystemInfo const& sys_info; // The number of chars in the longest benchmark name. size_t name_field_width; static const char* executable_name; diff --git a/utils/google-benchmark/src/benchmark.cc b/utils/google-benchmark/src/benchmark.cc index 410493fde..aab07500a 100644 --- a/utils/google-benchmark/src/benchmark.cc +++ b/utils/google-benchmark/src/benchmark.cc @@ -57,9 +57,9 @@ DEFINE_bool(benchmark_list_tests, false, DEFINE_string(benchmark_filter, ".", "A regular expression that specifies the set of benchmarks " - "to execute. If this flag is empty, no benchmarks are run. " - "If this flag is the string \"all\", all benchmarks linked " - "into the process are run."); + "to execute. If this flag is empty, or if this flag is the " + "string \"all\", all benchmarks linked into the binary are " + "run."); DEFINE_double(benchmark_min_time, 0.5, "Minimum number of seconds we should run benchmark before " diff --git a/utils/google-benchmark/src/benchmark_register.cc b/utils/google-benchmark/src/benchmark_register.cc index a85a4b44d..f17f5b223 100644 --- a/utils/google-benchmark/src/benchmark_register.cc +++ b/utils/google-benchmark/src/benchmark_register.cc @@ -182,14 +182,19 @@ bool BenchmarkFamilies::FindBenchmarks( } } - instance.name += StrFormat("%d", arg); + // we know that the args are always non-negative (see 'AddRange()'), + // thus print as 'unsigned'. BUT, do a cast due to the 32-bit builds. + instance.name += StrFormat("%lu", static_cast(arg)); ++arg_i; } if (!IsZero(family->min_time_)) instance.name += StrFormat("/min_time:%0.3f", family->min_time_); - if (family->iterations_ != 0) - instance.name += StrFormat("/iterations:%d", family->iterations_); + if (family->iterations_ != 0) { + instance.name += + StrFormat("/iterations:%lu", + static_cast(family->iterations_)); + } if (family->repetitions_ != 0) instance.name += StrFormat("/repeats:%d", family->repetitions_); diff --git a/utils/google-benchmark/src/complexity.cc b/utils/google-benchmark/src/complexity.cc index 0be73e082..6ef17660c 100644 --- a/utils/google-benchmark/src/complexity.cc +++ b/utils/google-benchmark/src/complexity.cc @@ -73,8 +73,8 @@ std::string GetBigOString(BigO complexity) { // - time : Vector containing the times for the benchmark tests. // - fitting_curve : lambda expression (e.g. [](int64_t n) {return n; };). -// For a deeper explanation on the algorithm logic, look the README file at -// http://github.com/ismaelJimenez/Minimal-Cpp-Least-Squared-Fit +// For a deeper explanation on the algorithm logic, please refer to +// https://en.wikipedia.org/wiki/Least_squares#Least_squares,_regression_analysis_and_statistics LeastSq MinimalLeastSq(const std::vector& n, const std::vector& time, diff --git a/utils/google-benchmark/src/json_reporter.cc b/utils/google-benchmark/src/json_reporter.cc index f599425a8..7d01e8e4e 100644 --- a/utils/google-benchmark/src/json_reporter.cc +++ b/utils/google-benchmark/src/json_reporter.cc @@ -77,6 +77,8 @@ bool JSONReporter::ReportContext(const Context& context) { std::string walltime_value = LocalDateTimeString(); out << indent << FormatKV("date", walltime_value) << ",\n"; + out << indent << FormatKV("host_name", context.sys_info.name) << ",\n"; + if (Context::executable_name) { // windows uses backslash for its path separator, // which must be escaped in JSON otherwise it blows up conforming JSON diff --git a/utils/google-benchmark/src/reporter.cc b/utils/google-benchmark/src/reporter.cc index 056561de8..59bc5f710 100644 --- a/utils/google-benchmark/src/reporter.cc +++ b/utils/google-benchmark/src/reporter.cc @@ -79,7 +79,8 @@ void BenchmarkReporter::PrintBasicContext(std::ostream *out, // No initializer because it's already initialized to NULL. const char *BenchmarkReporter::Context::executable_name; -BenchmarkReporter::Context::Context() : cpu_info(CPUInfo::Get()) {} +BenchmarkReporter::Context::Context() + : cpu_info(CPUInfo::Get()), sys_info(SystemInfo::Get()) {} std::string BenchmarkReporter::Run::benchmark_name() const { std::string name = run_name; diff --git a/utils/google-benchmark/src/string_util.h b/utils/google-benchmark/src/string_util.h index 4a5501273..fc5f8b030 100644 --- a/utils/google-benchmark/src/string_util.h +++ b/utils/google-benchmark/src/string_util.h @@ -12,7 +12,11 @@ void AppendHumanReadable(int n, std::string* str); std::string HumanReadableNumber(double n, double one_k = 1024.0); -std::string StrFormat(const char* format, ...); +#ifdef __GNUC__ +__attribute__((format(printf, 1, 2))) +#endif +std::string +StrFormat(const char* format, ...); inline std::ostream& StrCatImp(std::ostream& out) BENCHMARK_NOEXCEPT { return out; diff --git a/utils/google-benchmark/src/sysinfo.cc b/utils/google-benchmark/src/sysinfo.cc index 0ad300ee0..c0c07e5e6 100644 --- a/utils/google-benchmark/src/sysinfo.cc +++ b/utils/google-benchmark/src/sysinfo.cc @@ -19,6 +19,7 @@ #undef StrCat // Don't let StrCat in string_util.h be renamed to lstrcatA #include #include +#include #else #include #ifndef BENCHMARK_OS_FUCHSIA @@ -52,6 +53,7 @@ #include #include #include +#include #include "check.h" #include "cycleclock.h" @@ -366,6 +368,35 @@ std::vector GetCacheSizes() { #endif } +std::string GetSystemName() { +#if defined(BENCHMARK_OS_WINDOWS) + std::string str; + const unsigned COUNT = MAX_COMPUTERNAME_LENGTH+1; + TCHAR hostname[COUNT] = {'\0'}; + DWORD DWCOUNT = COUNT; + if (!GetComputerName(hostname, &DWCOUNT)) + return std::string(""); +#ifndef UNICODE + str = std::string(hostname, DWCOUNT); +#else + //Using wstring_convert, Is deprecated in C++17 + using convert_type = std::codecvt_utf8; + std::wstring_convert converter; + std::wstring wStr(hostname, DWCOUNT); + str = converter.to_bytes(wStr); +#endif + return str; +#else // defined(BENCHMARK_OS_WINDOWS) +#ifdef BENCHMARK_OS_MACOSX //Mac Doesnt have HOST_NAME_MAX defined +#define HOST_NAME_MAX 64 +#endif + char hostname[HOST_NAME_MAX]; + int retVal = gethostname(hostname, HOST_NAME_MAX); + if (retVal != 0) return std::string(""); + return std::string(hostname); +#endif // Catch-all POSIX block. +} + int GetNumCPUs() { #ifdef BENCHMARK_HAS_SYSCTL int NumCPU = -1; @@ -609,4 +640,11 @@ CPUInfo::CPUInfo() scaling_enabled(CpuScalingEnabled(num_cpus)), load_avg(GetLoadAvg()) {} + +const SystemInfo& SystemInfo::Get() { + static const SystemInfo* info = new SystemInfo(); + return *info; +} + +SystemInfo::SystemInfo() : name(GetSystemName()) {} } // end namespace benchmark diff --git a/utils/google-benchmark/test/output_test_helper.cc b/utils/google-benchmark/test/output_test_helper.cc index f2da752e1..59c9dfb52 100644 --- a/utils/google-benchmark/test/output_test_helper.cc +++ b/utils/google-benchmark/test/output_test_helper.cc @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -207,7 +208,7 @@ void ResultsChecker::Add(const std::string& entry_pattern, ResultsCheckFn fn) { void ResultsChecker::CheckResults(std::stringstream& output) { // first reset the stream to the start { - auto start = std::ios::streampos(0); + auto start = std::stringstream::pos_type(0); // clear before calling tellg() output.clear(); // seek to zero only when needed @@ -438,11 +439,50 @@ int SubstrCnt(const std::string& haystack, const std::string& pat) { return count; } +static char ToHex(int ch) { + return ch < 10 ? static_cast('0' + ch) + : static_cast('a' + (ch - 10)); +} + +static char RandomHexChar() { + static std::mt19937 rd{std::random_device{}()}; + static std::uniform_int_distribution mrand{0, 15}; + return ToHex(mrand(rd)); +} + +static std::string GetRandomFileName() { + std::string model = "test.%%%%%%"; + for (auto & ch : model) { + if (ch == '%') + ch = RandomHexChar(); + } + return model; +} + +static bool FileExists(std::string const& name) { + std::ifstream in(name.c_str()); + return in.good(); +} + +static std::string GetTempFileName() { + // This function attempts to avoid race conditions where two tests + // create the same file at the same time. However, it still introduces races + // similar to tmpnam. + int retries = 3; + while (--retries) { + std::string name = GetRandomFileName(); + if (!FileExists(name)) + return name; + } + std::cerr << "Failed to create unique temporary file name" << std::endl; + std::abort(); +} + std::string GetFileReporterOutput(int argc, char* argv[]) { std::vector new_argv(argv, argv + argc); assert(static_cast(argc) == new_argv.size()); - std::string tmp_file_name = std::tmpnam(nullptr); + std::string tmp_file_name = GetTempFileName(); std::cout << "Will be using this as the tmp file: " << tmp_file_name << '\n'; std::string tmp = "--benchmark_out="; diff --git a/utils/google-benchmark/test/reporter_output_test.cc b/utils/google-benchmark/test/reporter_output_test.cc index 8a45471a4..8263831b9 100644 --- a/utils/google-benchmark/test/reporter_output_test.cc +++ b/utils/google-benchmark/test/reporter_output_test.cc @@ -23,6 +23,7 @@ static int AddContextCases() { {{"^\\{", MR_Default}, {"\"context\":", MR_Next}, {"\"date\": \"", MR_Next}, + {"\"host_name\":", MR_Next}, {"\"executable\": \".*(/|\\\\)reporter_output_test(\\.exe)?\",", MR_Next}, {"\"num_cpus\": %int,$", MR_Next}, @@ -219,6 +220,18 @@ ADD_CASES(TC_JSONOut, {"\"run_type\": \"iteration\",$", MR_Next}}); ADD_CASES(TC_CSVOut, {{"^\"BM_arg_names/first:2/5/third:4\",%csv_report$"}}); +// ========================================================================= // +// ------------------------ Testing Big Args Output ------------------------ // +// ========================================================================= // + +void BM_BigArgs(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_BigArgs)->RangeMultiplier(2)->Range(1U << 30U, 1U << 31U); +ADD_CASES(TC_ConsoleOut, {{"^BM_BigArgs/1073741824 %console_report$"}, + {"^BM_BigArgs/2147483648 %console_report$"}}); + // ========================================================================= // // ----------------------- Testing Complexity Output ----------------------- // // ========================================================================= // diff --git a/utils/google-benchmark/test/string_util_gtest.cc b/utils/google-benchmark/test/string_util_gtest.cc index 4c81734cf..2c5d073f6 100644 --- a/utils/google-benchmark/test/string_util_gtest.cc +++ b/utils/google-benchmark/test/string_util_gtest.cc @@ -9,56 +9,56 @@ namespace { TEST(StringUtilTest, stoul) { { size_t pos = 0; - EXPECT_EQ(0, benchmark::stoul("0", &pos)); - EXPECT_EQ(1, pos); + EXPECT_EQ(0ul, benchmark::stoul("0", &pos)); + EXPECT_EQ(1ul, pos); } { size_t pos = 0; - EXPECT_EQ(7, benchmark::stoul("7", &pos)); - EXPECT_EQ(1, pos); + EXPECT_EQ(7ul, benchmark::stoul("7", &pos)); + EXPECT_EQ(1ul, pos); } { size_t pos = 0; - EXPECT_EQ(135, benchmark::stoul("135", &pos)); - EXPECT_EQ(3, pos); + EXPECT_EQ(135ul, benchmark::stoul("135", &pos)); + EXPECT_EQ(3ul, pos); } #if ULONG_MAX == 0xFFFFFFFFul { size_t pos = 0; EXPECT_EQ(0xFFFFFFFFul, benchmark::stoul("4294967295", &pos)); - EXPECT_EQ(10, pos); + EXPECT_EQ(10ul, pos); } #elif ULONG_MAX == 0xFFFFFFFFFFFFFFFFul { size_t pos = 0; EXPECT_EQ(0xFFFFFFFFFFFFFFFFul, benchmark::stoul("18446744073709551615", &pos)); - EXPECT_EQ(20, pos); + EXPECT_EQ(20ul, pos); } #endif { size_t pos = 0; - EXPECT_EQ(10, benchmark::stoul("1010", &pos, 2)); - EXPECT_EQ(4, pos); + EXPECT_EQ(10ul, benchmark::stoul("1010", &pos, 2)); + EXPECT_EQ(4ul, pos); } { size_t pos = 0; - EXPECT_EQ(520, benchmark::stoul("1010", &pos, 8)); - EXPECT_EQ(4, pos); + EXPECT_EQ(520ul, benchmark::stoul("1010", &pos, 8)); + EXPECT_EQ(4ul, pos); } { size_t pos = 0; - EXPECT_EQ(1010, benchmark::stoul("1010", &pos, 10)); - EXPECT_EQ(4, pos); + EXPECT_EQ(1010ul, benchmark::stoul("1010", &pos, 10)); + EXPECT_EQ(4ul, pos); } { size_t pos = 0; - EXPECT_EQ(4112, benchmark::stoul("1010", &pos, 16)); - EXPECT_EQ(4, pos); + EXPECT_EQ(4112ul, benchmark::stoul("1010", &pos, 16)); + EXPECT_EQ(4ul, pos); } { size_t pos = 0; - EXPECT_EQ(0xBEEF, benchmark::stoul("BEEF", &pos, 16)); - EXPECT_EQ(4, pos); + EXPECT_EQ(0xBEEFul, benchmark::stoul("BEEF", &pos, 16)); + EXPECT_EQ(4ul, pos); } { ASSERT_THROW(benchmark::stoul("this is a test"), std::invalid_argument); @@ -69,42 +69,42 @@ TEST(StringUtilTest, stoi) { { size_t pos = 0; EXPECT_EQ(0, benchmark::stoi("0", &pos)); - EXPECT_EQ(1, pos); + EXPECT_EQ(1ul, pos); } { size_t pos = 0; EXPECT_EQ(-17, benchmark::stoi("-17", &pos)); - EXPECT_EQ(3, pos); + EXPECT_EQ(3ul, pos); } { size_t pos = 0; EXPECT_EQ(1357, benchmark::stoi("1357", &pos)); - EXPECT_EQ(4, pos); + EXPECT_EQ(4ul, pos); } { size_t pos = 0; EXPECT_EQ(10, benchmark::stoi("1010", &pos, 2)); - EXPECT_EQ(4, pos); + EXPECT_EQ(4ul, pos); } { size_t pos = 0; EXPECT_EQ(520, benchmark::stoi("1010", &pos, 8)); - EXPECT_EQ(4, pos); + EXPECT_EQ(4ul, pos); } { size_t pos = 0; EXPECT_EQ(1010, benchmark::stoi("1010", &pos, 10)); - EXPECT_EQ(4, pos); + EXPECT_EQ(4ul, pos); } { size_t pos = 0; EXPECT_EQ(4112, benchmark::stoi("1010", &pos, 16)); - EXPECT_EQ(4, pos); + EXPECT_EQ(4ul, pos); } { size_t pos = 0; EXPECT_EQ(0xBEEF, benchmark::stoi("BEEF", &pos, 16)); - EXPECT_EQ(4, pos); + EXPECT_EQ(4ul, pos); } { ASSERT_THROW(benchmark::stoi("this is a test"), std::invalid_argument); @@ -115,28 +115,28 @@ TEST(StringUtilTest, stod) { { size_t pos = 0; EXPECT_EQ(0.0, benchmark::stod("0", &pos)); - EXPECT_EQ(1, pos); + EXPECT_EQ(1ul, pos); } { size_t pos = 0; EXPECT_EQ(-84.0, benchmark::stod("-84", &pos)); - EXPECT_EQ(3, pos); + EXPECT_EQ(3ul, pos); } { size_t pos = 0; EXPECT_EQ(1234.0, benchmark::stod("1234", &pos)); - EXPECT_EQ(4, pos); + EXPECT_EQ(4ul, pos); } { size_t pos = 0; EXPECT_EQ(1.5, benchmark::stod("1.5", &pos)); - EXPECT_EQ(3, pos); + EXPECT_EQ(3ul, pos); } { size_t pos = 0; /* Note: exactly representable as double */ EXPECT_EQ(-1.25e+9, benchmark::stod("-1.25e+9", &pos)); - EXPECT_EQ(8, pos); + EXPECT_EQ(8ul, pos); } { ASSERT_THROW(benchmark::stod("this is a test"), std::invalid_argument); diff --git a/utils/google-benchmark/tools/compare.py b/utils/google-benchmark/tools/compare.py index 9ff5c1424..539ace6fb 100755 --- a/utils/google-benchmark/tools/compare.py +++ b/utils/google-benchmark/tools/compare.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +import unittest """ compare.py - versatile benchmark output compare tool """ @@ -244,9 +245,6 @@ def main(): print(ln) -import unittest - - class TestParser(unittest.TestCase): def setUp(self): self.parser = create_parser() @@ -402,7 +400,7 @@ class TestParser(unittest.TestCase): if __name__ == '__main__': - #unittest.main() + # unittest.main() main() # vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 diff --git a/utils/google-benchmark/tools/gbench/report.py b/utils/google-benchmark/tools/gbench/report.py index 28bab34af..5085b9319 100644 --- a/utils/google-benchmark/tools/gbench/report.py +++ b/utils/google-benchmark/tools/gbench/report.py @@ -1,3 +1,4 @@ +import unittest """report.py - Utilities for reporting statistics about benchmark results """ import os @@ -270,9 +271,6 @@ def generate_difference_report( # Unit tests -import unittest - - class TestGetUniqueBenchmarkNames(unittest.TestCase): def load_results(self): import json @@ -290,7 +288,7 @@ class TestGetUniqueBenchmarkNames(unittest.TestCase): 'BM_One', 'BM_Two', 'short', # These two are not sorted - 'medium', # These two are not sorted + 'medium', # These two are not sorted ] json = self.load_results() output_lines = get_unique_benchmark_names(json) @@ -300,6 +298,7 @@ class TestGetUniqueBenchmarkNames(unittest.TestCase): for i in range(0, len(output_lines)): self.assertEqual(expect_lines[i], output_lines[i]) + class TestReportDifference(unittest.TestCase): def load_results(self): import json diff --git a/utils/google-benchmark/tools/gbench/util.py b/utils/google-benchmark/tools/gbench/util.py index 07c237727..1f8e8e2c4 100644 --- a/utils/google-benchmark/tools/gbench/util.py +++ b/utils/google-benchmark/tools/gbench/util.py @@ -7,11 +7,13 @@ import subprocess import sys # Input file type enumeration -IT_Invalid = 0 -IT_JSON = 1 +IT_Invalid = 0 +IT_JSON = 1 IT_Executable = 2 _num_magic_bytes = 2 if sys.platform.startswith('win') else 4 + + def is_executable_file(filename): """ Return 'True' if 'filename' names a valid file which is likely @@ -46,7 +48,7 @@ def is_json_file(filename): with open(filename, 'r') as f: json.load(f) return True - except: + except BaseException: pass return False @@ -84,6 +86,7 @@ def check_input_file(filename): sys.exit(1) return ftype + def find_benchmark_flag(prefix, benchmark_flags): """ Search the specified list of flags for a flag matching `` and @@ -97,6 +100,7 @@ def find_benchmark_flag(prefix, benchmark_flags): result = f[len(prefix):] return result + def remove_benchmark_flags(prefix, benchmark_flags): """ Return a new list containing the specified benchmark_flags except those @@ -105,6 +109,7 @@ def remove_benchmark_flags(prefix, benchmark_flags): assert prefix.startswith('--') and prefix.endswith('=') return [f for f in benchmark_flags if not f.startswith(prefix)] + def load_benchmark_results(fname): """ Read benchmark output from a file and return the JSON object. @@ -129,7 +134,7 @@ def run_benchmark(exe_name, benchmark_flags): thandle, output_name = tempfile.mkstemp() os.close(thandle) benchmark_flags = list(benchmark_flags) + \ - ['--benchmark_out=%s' % output_name] + ['--benchmark_out=%s' % output_name] cmd = [exe_name] + benchmark_flags print("RUNNING: %s" % ' '.join(cmd)) @@ -156,4 +161,4 @@ def run_or_load_benchmark(filename, benchmark_flags): elif ftype == IT_Executable: return run_benchmark(filename, benchmark_flags) else: - assert False # This branch is unreachable \ No newline at end of file + assert False # This branch is unreachable From ea9230c04bd7b670653035e712d435eca7c601b3 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Fri, 14 Dec 2018 03:48:09 +0000 Subject: [PATCH 32/94] Update google benchmark again git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349127 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../google-benchmark/src/console_reporter.cc | 30 +++++++++++++++---- .../test/output_test_helper.cc | 11 +++---- .../test/reporter_output_test.cc | 2 +- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/utils/google-benchmark/src/console_reporter.cc b/utils/google-benchmark/src/console_reporter.cc index 7de71386f..ca364727c 100644 --- a/utils/google-benchmark/src/console_reporter.cc +++ b/utils/google-benchmark/src/console_reporter.cc @@ -53,7 +53,7 @@ bool ConsoleReporter::ReportContext(const Context& context) { } void ConsoleReporter::PrintHeader(const Run& run) { - std::string str = FormatString("%-*s %13s %13s %10s", static_cast(name_field_width_), + std::string str = FormatString("%-*s %13s %15s %12s", static_cast(name_field_width_), "Benchmark", "Time", "CPU", "Iterations"); if(!run.counters.empty()) { if(output_options_ & OO_Tabular) { @@ -98,6 +98,21 @@ static void IgnoreColorPrint(std::ostream& out, LogColor, const char* fmt, va_end(args); } + +static std::string FormatTime(double time) { + // Align decimal places... + if (time < 1.0) { + return FormatString("%10.3f", time); + } + if (time < 10.0) { + return FormatString("%10.2f", time); + } + if (time < 100.0) { + return FormatString("%10.1f", time); + } + return FormatString("%10.0f", time); +} + void ConsoleReporter::PrintRunData(const Run& result) { typedef void(PrinterFn)(std::ostream&, LogColor, const char*, ...); auto& Out = GetOutputStream(); @@ -117,18 +132,21 @@ void ConsoleReporter::PrintRunData(const Run& result) { const double real_time = result.GetAdjustedRealTime(); const double cpu_time = result.GetAdjustedCPUTime(); + const std::string real_time_str = FormatTime(real_time); + const std::string cpu_time_str = FormatTime(cpu_time); + if (result.report_big_o) { std::string big_o = GetBigOString(result.complexity); - printer(Out, COLOR_YELLOW, "%10.2f %s %10.2f %s ", real_time, big_o.c_str(), + printer(Out, COLOR_YELLOW, "%10.2f %-4s %10.2f %-4s ", real_time, big_o.c_str(), cpu_time, big_o.c_str()); } else if (result.report_rms) { - printer(Out, COLOR_YELLOW, "%10.0f %% %10.0f %% ", real_time * 100, - cpu_time * 100); + printer(Out, COLOR_YELLOW, "%10.0f %-4s %10.0f %-4s ", real_time * 100, "%", + cpu_time * 100, "%"); } else { const char* timeLabel = GetTimeUnitString(result.time_unit); - printer(Out, COLOR_YELLOW, "%10.0f %s %10.0f %s ", real_time, timeLabel, - cpu_time, timeLabel); + printer(Out, COLOR_YELLOW, "%s %-4s %s %-4s ", real_time_str.c_str(), timeLabel, + cpu_time_str.c_str(), timeLabel); } if (!result.report_big_o && !result.report_rms) { diff --git a/utils/google-benchmark/test/output_test_helper.cc b/utils/google-benchmark/test/output_test_helper.cc index 59c9dfb52..5dc951d2b 100644 --- a/utils/google-benchmark/test/output_test_helper.cc +++ b/utils/google-benchmark/test/output_test_helper.cc @@ -39,17 +39,18 @@ SubMap& GetSubstitutions() { // Don't use 'dec_re' from header because it may not yet be initialized. // clang-format off static std::string safe_dec_re = "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?"; + static std::string time_re = "([0-9]+[.])?[0-9]+"; static SubMap map = { {"%float", "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?"}, // human-readable float {"%hrfloat", "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?[kMGTPEZYmunpfazy]?"}, {"%int", "[ ]*[0-9]+"}, {" %s ", "[ ]+"}, - {"%time", "[ ]*[0-9]+ ns"}, - {"%console_report", "[ ]*[0-9]+ ns [ ]*[0-9]+ ns [ ]*[0-9]+"}, - {"%console_time_only_report", "[ ]*[0-9]+ ns [ ]*[0-9]+ ns"}, - {"%console_us_report", "[ ]*[0-9]+ us [ ]*[0-9]+ us [ ]*[0-9]+"}, - {"%console_us_time_only_report", "[ ]*[0-9]+ us [ ]*[0-9]+ us"}, + {"%time", "[ ]*" + time_re + "[ ]+ns"}, + {"%console_report", "[ ]*" + time_re + "[ ]+ns [ ]*" + time_re + "[ ]+ns [ ]*[0-9]+"}, + {"%console_time_only_report", "[ ]*" + time_re + "[ ]+ns [ ]*" + time_re + "[ ]+ns"}, + {"%console_us_report", "[ ]*" + time_re + "[ ]+us [ ]*" + time_re + "[ ]+us [ ]*[0-9]+"}, + {"%console_us_time_only_report", "[ ]*" + time_re + "[ ]+us [ ]*" + time_re + "[ ]+us"}, {"%csv_header", "name,iterations,real_time,cpu_time,time_unit,bytes_per_second," "items_per_second,label,error_occurred,error_message"}, diff --git a/utils/google-benchmark/test/reporter_output_test.cc b/utils/google-benchmark/test/reporter_output_test.cc index 8263831b9..ec6d51b35 100644 --- a/utils/google-benchmark/test/reporter_output_test.cc +++ b/utils/google-benchmark/test/reporter_output_test.cc @@ -534,7 +534,7 @@ ADD_CASES(TC_ConsoleOut, {{"^BM_UserStats/iterations:5/repeats:3/manual_time [ " {"^BM_UserStats/iterations:5/repeats:3/" "manual_time_median [ ]* 150 ns %time [ ]*3$"}, {"^BM_UserStats/iterations:5/repeats:3/" - "manual_time_stddev [ ]* 0 ns %time [ ]*3$"}, + "manual_time_stddev [ ]* 0.000 ns %time [ ]*3$"}, {"^BM_UserStats/iterations:5/repeats:3/manual_time_ " "[ ]* 150 ns %time [ ]*3$"}}); ADD_CASES( From 7213ea7c13d71179027c6ae7d9749661e7757b33 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Fri, 14 Dec 2018 18:19:14 +0000 Subject: [PATCH 33/94] [libcxx] Make sure use_system_cxx_lib does not override cxx_runtime_root for DYLD_LIBRARY_PATH Otherwise, even specifying a runtime root different from the library we're linking against won't work -- the library we're linking against is always used. This is undesirable if we try testing something like linking against a recent libc++.dylib but running the tests against an older version (the back-deployment use case). git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349171 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/TestingLibcxx.rst | 3 +-- utils/libcxx/test/target_info.py | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/TestingLibcxx.rst b/docs/TestingLibcxx.rst index 48b7271c3..ebbbf628a 100644 --- a/docs/TestingLibcxx.rst +++ b/docs/TestingLibcxx.rst @@ -138,8 +138,7 @@ configuration. Passing the option on the command line will override the default. Specify the directory of the libc++ library to use at runtime. This directory is not added to the linkers search path. This can be used to compile tests against one version of libc++ and run them using another. The default value - for this option is `cxx_library_root`. This option cannot be used - when use_system_cxx_lib is provided. + for this option is `cxx_library_root`. .. option:: use_system_cxx_lib= diff --git a/utils/libcxx/test/target_info.py b/utils/libcxx/test/target_info.py index 2ca09dc5d..3181d4bd3 100644 --- a/utils/libcxx/test/target_info.py +++ b/utils/libcxx/test/target_info.py @@ -144,12 +144,12 @@ class DarwinLocalTI(DefaultTargetInfo): def configure_env(self, env): library_paths = [] # Configure the library path for libc++ - if self.full_config.use_system_cxx_lib: + if self.full_config.cxx_runtime_root: + library_paths += [self.full_config.cxx_runtime_root] + elif self.full_config.use_system_cxx_lib: if (os.path.isdir(str(self.full_config.use_system_cxx_lib))): library_paths += [self.full_config.use_system_cxx_lib] - pass - elif self.full_config.cxx_runtime_root: - library_paths += [self.full_config.cxx_runtime_root] + # Configure the abi library path if self.full_config.abi_library_root: library_paths += [self.full_config.abi_library_root] From f927635d87ffd5954c84fcb00b1ffcd7d68e0ea5 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Fri, 14 Dec 2018 18:49:35 +0000 Subject: [PATCH 34/94] Implement P1209 - Adopt Consistent Container Erasure from Library Fundamentals 2 for C++20. Reviewed as https://reviews.llvm.org/D55532 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349178 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/deque | 18 ++++ include/forward_list | 17 ++++ include/functional | 12 +++ include/list | 17 ++++ include/map | 22 +++++ include/set | 20 ++++ include/string | 17 ++++ include/unordered_map | 20 ++++ include/unordered_set | 21 +++++ include/vector | 17 ++++ include/version | 4 + .../map/map.erasure/erase_if.pass.cpp | 79 ++++++++++++++++ .../multimap.erasure/erase_if.pass.cpp | 89 ++++++++++++++++++ .../multiset.erasure/erase_if.pass.cpp | 78 ++++++++++++++++ .../set/set.erasure/erase_if.pass.cpp | 67 ++++++++++++++ .../deque/deque.erasure/erase.pass.cpp | 78 ++++++++++++++++ .../deque/deque.erasure/erase_if.pass.cpp | 78 ++++++++++++++++ .../forwardlist.erasure/erase.pass.cpp | 78 ++++++++++++++++ .../forwardlist.erasure/erase_if.pass.cpp | 78 ++++++++++++++++ .../list/list.erasure/erase.pass.cpp | 78 ++++++++++++++++ .../list/list.erasure/erase_if.pass.cpp | 78 ++++++++++++++++ .../vector/vector.erasure/erase.pass.cpp | 78 ++++++++++++++++ .../vector/vector.erasure/erase_if.pass.cpp | 78 ++++++++++++++++ .../unord/unord.map/erase_if.pass.cpp | 80 ++++++++++++++++ .../unord/unord.multimap/erase_if.pass.cpp | 90 ++++++++++++++++++ .../unord/unord.multiset/erase_if.pass.cpp | 91 +++++++++++++++++++ .../unord/unord.set/erase_if.pass.cpp | 81 +++++++++++++++++ .../deque.version.pass.cpp | 11 +++ .../forward_list.version.pass.cpp | 11 +++ .../list.version.pass.cpp | 11 +++ .../map.version.pass.cpp | 11 +++ .../set.version.pass.cpp | 11 +++ .../string.version.pass.cpp | 11 +++ .../unordered_map.version.pass.cpp | 12 +++ .../unordered_set.version.pass.cpp | 11 +++ .../vector.version.pass.cpp | 11 +++ .../strings/strings.erasure/erase.pass.cpp | 76 ++++++++++++++++ .../strings/strings.erasure/erase_if.pass.cpp | 76 ++++++++++++++++ www/cxx2a_status.html | 2 +- 39 files changed, 1717 insertions(+), 1 deletion(-) create mode 100644 test/std/containers/associative/map/map.erasure/erase_if.pass.cpp create mode 100644 test/std/containers/associative/multimap/multimap.erasure/erase_if.pass.cpp create mode 100644 test/std/containers/associative/multiset/multiset.erasure/erase_if.pass.cpp create mode 100644 test/std/containers/associative/set/set.erasure/erase_if.pass.cpp create mode 100644 test/std/containers/sequences/deque/deque.erasure/erase.pass.cpp create mode 100644 test/std/containers/sequences/deque/deque.erasure/erase_if.pass.cpp create mode 100644 test/std/containers/sequences/forwardlist/forwardlist.erasure/erase.pass.cpp create mode 100644 test/std/containers/sequences/forwardlist/forwardlist.erasure/erase_if.pass.cpp create mode 100644 test/std/containers/sequences/list/list.erasure/erase.pass.cpp create mode 100644 test/std/containers/sequences/list/list.erasure/erase_if.pass.cpp create mode 100644 test/std/containers/sequences/vector/vector.erasure/erase.pass.cpp create mode 100644 test/std/containers/sequences/vector/vector.erasure/erase_if.pass.cpp create mode 100644 test/std/containers/unord/unord.map/erase_if.pass.cpp create mode 100644 test/std/containers/unord/unord.multimap/erase_if.pass.cpp create mode 100644 test/std/containers/unord/unord.multiset/erase_if.pass.cpp create mode 100644 test/std/containers/unord/unord.set/erase_if.pass.cpp create mode 100644 test/std/strings/strings.erasure/erase.pass.cpp create mode 100644 test/std/strings/strings.erasure/erase_if.pass.cpp diff --git a/include/deque b/include/deque index c232e53c3..6f7d04be5 100644 --- a/include/deque +++ b/include/deque @@ -150,6 +150,11 @@ template void swap(deque& x, deque& y) noexcept(noexcept(x.swap(y))); +template + void erase(deque& c, const U& value); // C++20 +template + void erase_if(deque& c, Predicate pred); // C++20 + } // std */ @@ -2928,6 +2933,19 @@ swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y) __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +void erase(deque<_Tp, _Allocator>& __c, const _Up& __v) +{ __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); } + +template +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) +{ __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); } +#endif + + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/include/forward_list b/include/forward_list index f9a71f033..b506acd1f 100644 --- a/include/forward_list +++ b/include/forward_list @@ -167,6 +167,11 @@ template void swap(forward_list& x, forward_list& y) noexcept(noexcept(x.swap(y))); +template + void erase(forward_list& c, const U& value); // C++20 +template + void erase_if(forward_list& c, Predicate pred); // C++20 + } // std */ @@ -1744,6 +1749,18 @@ swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y) __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) +{ __c.remove_if(__pred); } + +template +inline _LIBCPP_INLINE_VISIBILITY +void erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v) +{ _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); } +#endif + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/include/functional b/include/functional index bf3216f41..1fb44f271 100644 --- a/include/functional +++ b/include/functional @@ -2953,6 +2953,18 @@ template using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; #endif // > C++17 +template +inline void __libcpp_erase_if_container( _Container& __c, _Predicate __pred) +{ + for (typename _Container::iterator __iter = __c.begin(), __last = __c.end(); __iter != __last;) + { + if (__pred(*__iter)) + __iter = __c.erase(__iter); + else + ++__iter; + } +} + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_FUNCTIONAL diff --git a/include/list b/include/list index 1a28c21ab..c69e31d93 100644 --- a/include/list +++ b/include/list @@ -169,6 +169,11 @@ template void swap(list& x, list& y) noexcept(noexcept(x.swap(y))); +template + void erase(list& c, const U& value); // C++20 +template + void erase_if(list& c, Predicate pred); // C++20 + } // std */ @@ -2450,6 +2455,18 @@ swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred) +{ __c.remove_if(__pred); } + +template +inline _LIBCPP_INLINE_VISIBILITY +void erase(list<_Tp, _Allocator>& __c, const _Up& __v) +{ _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); } +#endif + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/include/map b/include/map index f6f2b6835..616bb46cf 100644 --- a/include/map +++ b/include/map @@ -254,6 +254,10 @@ void swap(map& x, map& y) noexcept(noexcept(x.swap(y))); +template + void erase_if(map& c, Predicate pred); // C++20 + + template , class Allocator = allocator>> class multimap @@ -465,6 +469,9 @@ swap(multimap& x, multimap& y) noexcept(noexcept(x.swap(y))); +template + void erase_if(multimap& c, Predicate pred); // C++20 + } // std */ @@ -1614,6 +1621,14 @@ swap(map<_Key, _Tp, _Compare, _Allocator>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + + template , class _Allocator = allocator > > class _LIBCPP_TEMPLATE_VIS multimap @@ -2151,6 +2166,13 @@ swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_MAP diff --git a/include/set b/include/set index fb15ecfa0..a0155f0b2 100644 --- a/include/set +++ b/include/set @@ -216,6 +216,9 @@ void swap(set& x, set& y) noexcept(noexcept(x.swap(y))); +template + void erase_if(set& c, Predicate pred); // C++20 + template , class Allocator = allocator> class multiset @@ -412,6 +415,9 @@ void swap(multiset& x, multiset& y) noexcept(noexcept(x.swap(y))); +template + void erase_if(multiset& c, Predicate pred); // C++20 + } // std */ @@ -912,6 +918,13 @@ swap(set<_Key, _Compare, _Allocator>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + template , class _Allocator = allocator<_Key> > class _LIBCPP_TEMPLATE_VIS multiset @@ -1392,6 +1405,13 @@ swap(multiset<_Key, _Compare, _Allocator>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_SET diff --git a/include/string b/include/string index 4dd6ddc4e..fb838d1e5 100644 --- a/include/string +++ b/include/string @@ -437,6 +437,11 @@ template basic_istream& getline(basic_istream& is, basic_string& str); +template +void erase(basic_string& c, const U& value); // C++20 +template +void erase_if(basic_string& c, Predicate pred); // C++20 + typedef basic_string string; typedef basic_string wstring; typedef basic_string u16string; @@ -4276,6 +4281,18 @@ getline(basic_istream<_CharT, _Traits>&& __is, #endif // _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +void erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) +{ __str.erase(_VSTD::remove(__str.begin(), __str.end(), __v), __str.end()); } + +template +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred) +{ __str.erase(_VSTD::remove_if(__str.begin(), __str.end(), __pred), __str.end()); } +#endif + #if _LIBCPP_DEBUG_LEVEL >= 2 template diff --git a/include/unordered_map b/include/unordered_map index 5dd923607..6035b05dc 100644 --- a/include/unordered_map +++ b/include/unordered_map @@ -384,6 +384,12 @@ template unordered_multimap& y) noexcept(noexcept(x.swap(y))); +template + void erase_if(unordered_set& c, Predicate pred); // C++20 + +template + void erase_if(unordered_multiset& c, Predicate pred); // C++20 + template bool operator==(const unordered_multimap& x, @@ -1626,6 +1632,13 @@ swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + template bool operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, @@ -2243,6 +2256,13 @@ swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + template bool operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, diff --git a/include/unordered_set b/include/unordered_set index 25b92203f..b4e61da89 100644 --- a/include/unordered_set +++ b/include/unordered_set @@ -339,6 +339,13 @@ template unordered_multiset& y) noexcept(noexcept(x.swap(y))); +template + void erase_if(unordered_set& c, Predicate pred); // C++20 + +template + void erase_if(unordered_multiset& c, Predicate pred); // C++20 + + template bool operator==(const unordered_multiset& x, @@ -934,6 +941,13 @@ swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(unordered_set<_Value, _Hash, _Pred, _Alloc>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + template bool operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, @@ -1497,6 +1511,13 @@ swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + template bool operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, diff --git a/include/vector b/include/vector index 196ea70ea..edb6d3e09 100644 --- a/include/vector +++ b/include/vector @@ -261,6 +261,11 @@ template void swap(vector& x, vector& y) noexcept(noexcept(x.swap(y))); +template + void erase(vector& c, const U& value); // C++20 +template + void erase_if(vector& c, Predicate pred); // C++20 + } // std */ @@ -3408,6 +3413,18 @@ swap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y) __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +void erase(vector<_Tp, _Allocator>& __c, const _Up& __v) +{ __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); } + +template +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(vector<_Tp, _Allocator>& __c, _Predicate __pred) +{ __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); } +#endif + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/include/version b/include/version index 5e758fce7..552d663d0 100644 --- a/include/version +++ b/include/version @@ -39,6 +39,9 @@ __cpp_lib_complex_udls 201309L __cpp_lib_concepts 201806L __cpp_lib_constexpr_swap_algorithms 201806L __cpp_lib_enable_shared_from_this 201603L +__cpp_lib_erase_if 201811L + + __cpp_lib_exchange_function 201304L __cpp_lib_execution 201603L __cpp_lib_filesystem 201703L @@ -118,6 +121,7 @@ __cpp_lib_void_t 201411L #if _LIBCPP_STD_VER > 17 #ifndef _LIBCPP_NO_HAS_CHAR8_T # define __cpp_lib_char8_t 201811L +#define __cpp_lib_erase_if 201811L #endif #endif diff --git a/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp b/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp new file mode 100644 index 000000000..f8cbc15d1 --- /dev/null +++ b/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase_if(map& c, Predicate pred); + +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list; +template +M make (Init vals) +{ + M ret; + for (int v : vals) + ret[v] = v + 10; + return ret; +} + +template +void +test0(Init vals, Pred p, Init expected) +{ + M s = make (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == make(expected)); +} + +template +void test() +{ + auto is1 = [](auto v) { return v.first == 1;}; + auto is2 = [](auto v) { return v.first == 2;}; + auto is3 = [](auto v) { return v.first == 3;}; + auto is4 = [](auto v) { return v.first == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0({}, is1, {}); + + test0({1}, is1, {}); + test0({1}, is2, {1}); + + test0({1,2}, is1, {2}); + test0({1,2}, is2, {1}); + test0({1,2}, is3, {1,2}); + + test0({1,2,3}, is1, {2,3}); + test0({1,2,3}, is2, {1,3}); + test0({1,2,3}, is3, {1,2}); + test0({1,2,3}, is4, {1,2,3}); + + test0({1,2,3}, True, {}); + test0({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test>(); + test, min_allocator>>> (); + test, test_allocator>>> (); + + test>(); + test>(); +} + diff --git a/test/std/containers/associative/multimap/multimap.erasure/erase_if.pass.cpp b/test/std/containers/associative/multimap/multimap.erasure/erase_if.pass.cpp new file mode 100644 index 000000000..8e786fdc9 --- /dev/null +++ b/test/std/containers/associative/multimap/multimap.erasure/erase_if.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase_if(multimap& c, Predicate pred); + +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list; +template +M make (Init vals) +{ + M ret; + for (int v : vals) + ret.insert(typename M::value_type(v, v + 10)); + return ret; +} + +template +void +test0(Init vals, Pred p, Init expected) +{ + M s = make (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == make(expected)); +} + +template +void test() +{ + auto is1 = [](auto v) { return v.first == 1;}; + auto is2 = [](auto v) { return v.first == 2;}; + auto is3 = [](auto v) { return v.first == 3;}; + auto is4 = [](auto v) { return v.first == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0({}, is1, {}); + + test0({1}, is1, {}); + test0({1}, is2, {1}); + + test0({1,2}, is1, {2}); + test0({1,2}, is2, {1}); + test0({1,2}, is3, {1,2}); + test0({1,1}, is1, {}); + test0({1,1}, is3, {1,1}); + + test0({1,2,3}, is1, {2,3}); + test0({1,2,3}, is2, {1,3}); + test0({1,2,3}, is3, {1,2}); + test0({1,2,3}, is4, {1,2,3}); + + test0({1,1,1}, is1, {}); + test0({1,1,1}, is2, {1,1,1}); + test0({1,1,2}, is1, {2}); + test0({1,1,2}, is2, {1,1}); + test0({1,1,2}, is3, {1,1,2}); + test0({1,2,2}, is1, {2,2}); + test0({1,2,2}, is2, {1}); + test0({1,2,2}, is3, {1,2,2}); + + test0({1,2,3}, True, {}); + test0({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test>(); + test, min_allocator>>> (); + test, test_allocator>>> (); + + test>(); + test>(); +} diff --git a/test/std/containers/associative/multiset/multiset.erasure/erase_if.pass.cpp b/test/std/containers/associative/multiset/multiset.erasure/erase_if.pass.cpp new file mode 100644 index 000000000..3c619bb68 --- /dev/null +++ b/test/std/containers/associative/multiset/multiset.erasure/erase_if.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase_if(multiset& c, Predicate pred); + +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test0(S s, Pred p, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == expected); +} + +template +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0(S(), is1, S()); + + test0(S({1}), is1, S()); + test0(S({1}), is2, S({1})); + + test0(S({1,2}), is1, S({2})); + test0(S({1,2}), is2, S({1})); + test0(S({1,2}), is3, S({1,2})); + test0(S({1,1}), is1, S()); + test0(S({1,1}), is3, S({1,1})); + + test0(S({1,2,3}), is1, S({2,3})); + test0(S({1,2,3}), is2, S({1,3})); + test0(S({1,2,3}), is3, S({1,2})); + test0(S({1,2,3}), is4, S({1,2,3})); + + test0(S({1,1,1}), is1, S()); + test0(S({1,1,1}), is2, S({1,1,1})); + test0(S({1,1,2}), is1, S({2})); + test0(S({1,1,2}), is2, S({1,1})); + test0(S({1,1,2}), is3, S({1,1,2})); + test0(S({1,2,2}), is1, S({2,2})); + test0(S({1,2,2}), is2, S({1})); + test0(S({1,2,2}), is3, S({1,2,2})); + + test0(S({1,2,3}), True, S()); + test0(S({1,2,3}), False, S({1,2,3})); +} + +int main() +{ + test>(); + test, min_allocator>> (); + test, test_allocator>> (); + + test>(); + test>(); +} diff --git a/test/std/containers/associative/set/set.erasure/erase_if.pass.cpp b/test/std/containers/associative/set/set.erasure/erase_if.pass.cpp new file mode 100644 index 000000000..a55a38c2d --- /dev/null +++ b/test/std/containers/associative/set/set.erasure/erase_if.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase_if(set& c, Predicate pred); + +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test0(S s, Pred p, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == expected); +} + +template +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0(S(), is1, S()); + + test0(S({1}), is1, S()); + test0(S({1}), is2, S({1})); + + test0(S({1,2}), is1, S({2})); + test0(S({1,2}), is2, S({1})); + test0(S({1,2}), is3, S({1,2})); + + test0(S({1,2,3}), is1, S({2,3})); + test0(S({1,2,3}), is2, S({1,3})); + test0(S({1,2,3}), is3, S({1,2})); + test0(S({1,2,3}), is4, S({1,2,3})); + + test0(S({1,2,3}), True, S()); + test0(S({1,2,3}), False, S({1,2,3})); +} + +int main() +{ + test>(); + test, min_allocator>> (); + test, test_allocator>> (); + + test>(); + test>(); +} diff --git a/test/std/containers/sequences/deque/deque.erasure/erase.pass.cpp b/test/std/containers/sequences/deque/deque.erasure/erase.pass.cpp new file mode 100644 index 000000000..9a8c698a5 --- /dev/null +++ b/test/std/containers/sequences/deque/deque.erasure/erase.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase(deque& c, const U& value); + + +#include +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test0(S s, U val, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase(s, val))); + std::erase(s, val); + assert(s == expected); +} + +template +void test() +{ + + test0(S(), 1, S()); + + test0(S({1}), 1, S()); + test0(S({1}), 2, S({1})); + + test0(S({1,2}), 1, S({2})); + test0(S({1,2}), 2, S({1})); + test0(S({1,2}), 3, S({1,2})); + test0(S({1,1}), 1, S()); + test0(S({1,1}), 3, S({1,1})); + + test0(S({1,2,3}), 1, S({2,3})); + test0(S({1,2,3}), 2, S({1,3})); + test0(S({1,2,3}), 3, S({1,2})); + test0(S({1,2,3}), 4, S({1,2,3})); + + test0(S({1,1,1}), 1, S()); + test0(S({1,1,1}), 2, S({1,1,1})); + test0(S({1,1,2}), 1, S({2})); + test0(S({1,1,2}), 2, S({1,1})); + test0(S({1,1,2}), 3, S({1,1,2})); + test0(S({1,2,2}), 1, S({2,2})); + test0(S({1,2,2}), 2, S({1})); + test0(S({1,2,2}), 3, S({1,2,2})); + +// Test cross-type erasure + using opt = std::optional; + test0(S({1,2,1}), opt(), S({1,2,1})); + test0(S({1,2,1}), opt(1), S({2})); + test0(S({1,2,1}), opt(2), S({1,1})); + test0(S({1,2,1}), opt(3), S({1,2,1})); +} + +int main() +{ + test>(); + test>> (); + test>> (); + + test>(); + test>(); +} diff --git a/test/std/containers/sequences/deque/deque.erasure/erase_if.pass.cpp b/test/std/containers/sequences/deque/deque.erasure/erase_if.pass.cpp new file mode 100644 index 000000000..a090eb694 --- /dev/null +++ b/test/std/containers/sequences/deque/deque.erasure/erase_if.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase_if(deque& c, Predicate pred); + +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test0(S s, Pred p, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == expected); +} + +template +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0(S(), is1, S()); + + test0(S({1}), is1, S()); + test0(S({1}), is2, S({1})); + + test0(S({1,2}), is1, S({2})); + test0(S({1,2}), is2, S({1})); + test0(S({1,2}), is3, S({1,2})); + test0(S({1,1}), is1, S()); + test0(S({1,1}), is3, S({1,1})); + + test0(S({1,2,3}), is1, S({2,3})); + test0(S({1,2,3}), is2, S({1,3})); + test0(S({1,2,3}), is3, S({1,2})); + test0(S({1,2,3}), is4, S({1,2,3})); + + test0(S({1,1,1}), is1, S()); + test0(S({1,1,1}), is2, S({1,1,1})); + test0(S({1,1,2}), is1, S({2})); + test0(S({1,1,2}), is2, S({1,1})); + test0(S({1,1,2}), is3, S({1,1,2})); + test0(S({1,2,2}), is1, S({2,2})); + test0(S({1,2,2}), is2, S({1})); + test0(S({1,2,2}), is3, S({1,2,2})); + + test0(S({1,2,3}), True, S()); + test0(S({1,2,3}), False, S({1,2,3})); +} + +int main() +{ + test>(); + test>> (); + test>> (); + + test>(); + test>(); +} diff --git a/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase.pass.cpp new file mode 100644 index 000000000..0163b8607 --- /dev/null +++ b/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase(forward_list& c, const U& value); + + +#include +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test0(S s, U val, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase(s, val))); + std::erase(s, val); + assert(s == expected); +} + +template +void test() +{ + + test0(S(), 1, S()); + + test0(S({1}), 1, S()); + test0(S({1}), 2, S({1})); + + test0(S({1,2}), 1, S({2})); + test0(S({1,2}), 2, S({1})); + test0(S({1,2}), 3, S({1,2})); + test0(S({1,1}), 1, S()); + test0(S({1,1}), 3, S({1,1})); + + test0(S({1,2,3}), 1, S({2,3})); + test0(S({1,2,3}), 2, S({1,3})); + test0(S({1,2,3}), 3, S({1,2})); + test0(S({1,2,3}), 4, S({1,2,3})); + + test0(S({1,1,1}), 1, S()); + test0(S({1,1,1}), 2, S({1,1,1})); + test0(S({1,1,2}), 1, S({2})); + test0(S({1,1,2}), 2, S({1,1})); + test0(S({1,1,2}), 3, S({1,1,2})); + test0(S({1,2,2}), 1, S({2,2})); + test0(S({1,2,2}), 2, S({1})); + test0(S({1,2,2}), 3, S({1,2,2})); + +// Test cross-type erasure + using opt = std::optional; + test0(S({1,2,1}), opt(), S({1,2,1})); + test0(S({1,2,1}), opt(1), S({2})); + test0(S({1,2,1}), opt(2), S({1,1})); + test0(S({1,2,1}), opt(3), S({1,2,1})); +} + +int main() +{ + test>(); + test>> (); + test>> (); + + test>(); + test>(); +} diff --git a/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase_if.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase_if.pass.cpp new file mode 100644 index 000000000..69685d2d3 --- /dev/null +++ b/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase_if.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase_if(forward_list& c, Predicate pred); + +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test0(S s, Pred p, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == expected); +} + +template +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0(S(), is1, S()); + + test0(S({1}), is1, S()); + test0(S({1}), is2, S({1})); + + test0(S({1,2}), is1, S({2})); + test0(S({1,2}), is2, S({1})); + test0(S({1,2}), is3, S({1,2})); + test0(S({1,1}), is1, S()); + test0(S({1,1}), is3, S({1,1})); + + test0(S({1,2,3}), is1, S({2,3})); + test0(S({1,2,3}), is2, S({1,3})); + test0(S({1,2,3}), is3, S({1,2})); + test0(S({1,2,3}), is4, S({1,2,3})); + + test0(S({1,1,1}), is1, S()); + test0(S({1,1,1}), is2, S({1,1,1})); + test0(S({1,1,2}), is1, S({2})); + test0(S({1,1,2}), is2, S({1,1})); + test0(S({1,1,2}), is3, S({1,1,2})); + test0(S({1,2,2}), is1, S({2,2})); + test0(S({1,2,2}), is2, S({1})); + test0(S({1,2,2}), is3, S({1,2,2})); + + test0(S({1,2,3}), True, S()); + test0(S({1,2,3}), False, S({1,2,3})); +} + +int main() +{ + test>(); + test>> (); + test>> (); + + test>(); + test>(); +} diff --git a/test/std/containers/sequences/list/list.erasure/erase.pass.cpp b/test/std/containers/sequences/list/list.erasure/erase.pass.cpp new file mode 100644 index 000000000..a9f65c053 --- /dev/null +++ b/test/std/containers/sequences/list/list.erasure/erase.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase(list& c, const U& value); + + +#include +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test0(S s, U val, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase(s, val))); + std::erase(s, val); + assert(s == expected); +} + +template +void test() +{ + + test0(S(), 1, S()); + + test0(S({1}), 1, S()); + test0(S({1}), 2, S({1})); + + test0(S({1,2}), 1, S({2})); + test0(S({1,2}), 2, S({1})); + test0(S({1,2}), 3, S({1,2})); + test0(S({1,1}), 1, S()); + test0(S({1,1}), 3, S({1,1})); + + test0(S({1,2,3}), 1, S({2,3})); + test0(S({1,2,3}), 2, S({1,3})); + test0(S({1,2,3}), 3, S({1,2})); + test0(S({1,2,3}), 4, S({1,2,3})); + + test0(S({1,1,1}), 1, S()); + test0(S({1,1,1}), 2, S({1,1,1})); + test0(S({1,1,2}), 1, S({2})); + test0(S({1,1,2}), 2, S({1,1})); + test0(S({1,1,2}), 3, S({1,1,2})); + test0(S({1,2,2}), 1, S({2,2})); + test0(S({1,2,2}), 2, S({1})); + test0(S({1,2,2}), 3, S({1,2,2})); + +// Test cross-type erasure + using opt = std::optional; + test0(S({1,2,1}), opt(), S({1,2,1})); + test0(S({1,2,1}), opt(1), S({2})); + test0(S({1,2,1}), opt(2), S({1,1})); + test0(S({1,2,1}), opt(3), S({1,2,1})); +} + +int main() +{ + test>(); + test>> (); + test>> (); + + test>(); + test>(); +} diff --git a/test/std/containers/sequences/list/list.erasure/erase_if.pass.cpp b/test/std/containers/sequences/list/list.erasure/erase_if.pass.cpp new file mode 100644 index 000000000..99b1c6530 --- /dev/null +++ b/test/std/containers/sequences/list/list.erasure/erase_if.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase_if(list& c, Predicate pred); + +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test0(S s, Pred p, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == expected); +} + +template +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0(S(), is1, S()); + + test0(S({1}), is1, S()); + test0(S({1}), is2, S({1})); + + test0(S({1,2}), is1, S({2})); + test0(S({1,2}), is2, S({1})); + test0(S({1,2}), is3, S({1,2})); + test0(S({1,1}), is1, S()); + test0(S({1,1}), is3, S({1,1})); + + test0(S({1,2,3}), is1, S({2,3})); + test0(S({1,2,3}), is2, S({1,3})); + test0(S({1,2,3}), is3, S({1,2})); + test0(S({1,2,3}), is4, S({1,2,3})); + + test0(S({1,1,1}), is1, S()); + test0(S({1,1,1}), is2, S({1,1,1})); + test0(S({1,1,2}), is1, S({2})); + test0(S({1,1,2}), is2, S({1,1})); + test0(S({1,1,2}), is3, S({1,1,2})); + test0(S({1,2,2}), is1, S({2,2})); + test0(S({1,2,2}), is2, S({1})); + test0(S({1,2,2}), is3, S({1,2,2})); + + test0(S({1,2,3}), True, S()); + test0(S({1,2,3}), False, S({1,2,3})); +} + +int main() +{ + test>(); + test>> (); + test>> (); + + test>(); + test>(); +} diff --git a/test/std/containers/sequences/vector/vector.erasure/erase.pass.cpp b/test/std/containers/sequences/vector/vector.erasure/erase.pass.cpp new file mode 100644 index 000000000..e88252f1d --- /dev/null +++ b/test/std/containers/sequences/vector/vector.erasure/erase.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase(vector& c, const U& value); + + +#include +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test0(S s, U val, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase(s, val))); + std::erase(s, val); + assert(s == expected); +} + +template +void test() +{ + + test0(S(), 1, S()); + + test0(S({1}), 1, S()); + test0(S({1}), 2, S({1})); + + test0(S({1,2}), 1, S({2})); + test0(S({1,2}), 2, S({1})); + test0(S({1,2}), 3, S({1,2})); + test0(S({1,1}), 1, S()); + test0(S({1,1}), 3, S({1,1})); + + test0(S({1,2,3}), 1, S({2,3})); + test0(S({1,2,3}), 2, S({1,3})); + test0(S({1,2,3}), 3, S({1,2})); + test0(S({1,2,3}), 4, S({1,2,3})); + + test0(S({1,1,1}), 1, S()); + test0(S({1,1,1}), 2, S({1,1,1})); + test0(S({1,1,2}), 1, S({2})); + test0(S({1,1,2}), 2, S({1,1})); + test0(S({1,1,2}), 3, S({1,1,2})); + test0(S({1,2,2}), 1, S({2,2})); + test0(S({1,2,2}), 2, S({1})); + test0(S({1,2,2}), 3, S({1,2,2})); + +// Test cross-type erasure + using opt = std::optional; + test0(S({1,2,1}), opt(), S({1,2,1})); + test0(S({1,2,1}), opt(1), S({2})); + test0(S({1,2,1}), opt(2), S({1,1})); + test0(S({1,2,1}), opt(3), S({1,2,1})); +} + +int main() +{ + test>(); + test>> (); + test>> (); + + test>(); + test>(); +} diff --git a/test/std/containers/sequences/vector/vector.erasure/erase_if.pass.cpp b/test/std/containers/sequences/vector/vector.erasure/erase_if.pass.cpp new file mode 100644 index 000000000..8025a3407 --- /dev/null +++ b/test/std/containers/sequences/vector/vector.erasure/erase_if.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase_if(vector& c, Predicate pred); + +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test0(S s, Pred p, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == expected); +} + +template +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0(S(), is1, S()); + + test0(S({1}), is1, S()); + test0(S({1}), is2, S({1})); + + test0(S({1,2}), is1, S({2})); + test0(S({1,2}), is2, S({1})); + test0(S({1,2}), is3, S({1,2})); + test0(S({1,1}), is1, S()); + test0(S({1,1}), is3, S({1,1})); + + test0(S({1,2,3}), is1, S({2,3})); + test0(S({1,2,3}), is2, S({1,3})); + test0(S({1,2,3}), is3, S({1,2})); + test0(S({1,2,3}), is4, S({1,2,3})); + + test0(S({1,1,1}), is1, S()); + test0(S({1,1,1}), is2, S({1,1,1})); + test0(S({1,1,2}), is1, S({2})); + test0(S({1,1,2}), is2, S({1,1})); + test0(S({1,1,2}), is3, S({1,1,2})); + test0(S({1,2,2}), is1, S({2,2})); + test0(S({1,2,2}), is2, S({1})); + test0(S({1,2,2}), is3, S({1,2,2})); + + test0(S({1,2,3}), True, S()); + test0(S({1,2,3}), False, S({1,2,3})); +} + +int main() +{ + test>(); + test>> (); + test>> (); + + test>(); + test>(); +} diff --git a/test/std/containers/unord/unord.map/erase_if.pass.cpp b/test/std/containers/unord/unord.map/erase_if.pass.cpp new file mode 100644 index 000000000..f6a580c21 --- /dev/null +++ b/test/std/containers/unord/unord.map/erase_if.pass.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase_if(unordered_map& c, Predicate pred); + +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list; +template +M make (Init vals) +{ + M ret; + for (int v : vals) + ret[v] = v + 10; + return ret; +} + +template +void +test0(Init vals, Pred p, Init expected) +{ + M s = make (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + M e = make(expected); + assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end()))); +} + +template +void test() +{ + auto is1 = [](auto v) { return v.first == 1;}; + auto is2 = [](auto v) { return v.first == 2;}; + auto is3 = [](auto v) { return v.first == 3;}; + auto is4 = [](auto v) { return v.first == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0({}, is1, {}); + + test0({1}, is1, {}); + test0({1}, is2, {1}); + + test0({1,2}, is1, {2}); + test0({1,2}, is2, {1}); + test0({1,2}, is3, {1,2}); + + test0({1,2,3}, is1, {2,3}); + test0({1,2,3}, is2, {1,3}); + test0({1,2,3}, is3, {1,2}); + test0({1,2,3}, is4, {1,2,3}); + + test0({1,2,3}, True, {}); + test0({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test>(); + test, std::equal_to, min_allocator>>> (); + test, std::equal_to, test_allocator>>> (); + + test>(); + test>(); +} + diff --git a/test/std/containers/unord/unord.multimap/erase_if.pass.cpp b/test/std/containers/unord/unord.multimap/erase_if.pass.cpp new file mode 100644 index 000000000..dc613269a --- /dev/null +++ b/test/std/containers/unord/unord.multimap/erase_if.pass.cpp @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase_if(unordered_multimap& c, Predicate pred); + +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list; +template +M make (Init vals) +{ + M ret; + for (int v : vals) + ret.insert(typename M::value_type(v, v + 10)); + return ret; +} + +template +void +test0(Init vals, Pred p, Init expected) +{ + M s = make (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + M e = make(expected); + assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end()))); +} + +template +void test() +{ + auto is1 = [](auto v) { return v.first == 1;}; + auto is2 = [](auto v) { return v.first == 2;}; + auto is3 = [](auto v) { return v.first == 3;}; + auto is4 = [](auto v) { return v.first == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0({}, is1, {}); + + test0({1}, is1, {}); + test0({1}, is2, {1}); + + test0({1,2}, is1, {2}); + test0({1,2}, is2, {1}); + test0({1,2}, is3, {1,2}); + test0({1,1}, is1, {}); + test0({1,1}, is3, {1,1}); + + test0({1,2,3}, is1, {2,3}); + test0({1,2,3}, is2, {1,3}); + test0({1,2,3}, is3, {1,2}); + test0({1,2,3}, is4, {1,2,3}); + + test0({1,1,1}, is1, {}); + test0({1,1,1}, is2, {1,1,1}); + test0({1,1,2}, is1, {2}); + test0({1,1,2}, is2, {1,1}); + test0({1,1,2}, is3, {1,1,2}); + test0({1,2,2}, is1, {2,2}); + test0({1,2,2}, is2, {1}); + test0({1,2,2}, is3, {1,2,2}); + + test0({1,2,3}, True, {}); + test0({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test>(); + test, std::equal_to, min_allocator>>> (); + test, std::equal_to, test_allocator>>> (); + + test>(); + test>(); +} diff --git a/test/std/containers/unord/unord.multiset/erase_if.pass.cpp b/test/std/containers/unord/unord.multiset/erase_if.pass.cpp new file mode 100644 index 000000000..7a9d93d43 --- /dev/null +++ b/test/std/containers/unord/unord.multiset/erase_if.pass.cpp @@ -0,0 +1,91 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase_if(unordered_multiset& c, Predicate pred); + +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list; + +template +M make (Init vals) +{ + M ret; + for (int v : vals) + ret.insert(v); + return ret; +} + +template +void +test0(Init vals, Pred p, Init expected) +{ + M s = make (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + M e = make(expected); + assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end()))); +} + +template +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0({}, is1, {}); + + test0({1}, is1, {}); + test0({1}, is2, {1}); + + test0({1,2}, is1, {2}); + test0({1,2}, is2, {1}); + test0({1,2}, is3, {1,2}); + test0({1,1}, is1, {}); + test0({1,1}, is3, {1,1}); + + test0({1,2,3}, is1, {2,3}); + test0({1,2,3}, is2, {1,3}); + test0({1,2,3}, is3, {1,2}); + test0({1,2,3}, is4, {1,2,3}); + + test0({1,1,1}, is1, {}); + test0({1,1,1}, is2, {1,1,1}); + test0({1,1,2}, is1, {2}); + test0({1,1,2}, is2, {1,1}); + test0({1,1,2}, is3, {1,1,2}); + test0({1,2,2}, is1, {2,2}); + test0({1,2,2}, is2, {1}); + test0({1,2,2}, is3, {1,2,2}); + + test0({1,2,3}, True, {}); + test0({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test>(); + test, std::equal_to, min_allocator>> (); + test, std::equal_to, test_allocator>> (); + + test>(); + test>(); +} diff --git a/test/std/containers/unord/unord.set/erase_if.pass.cpp b/test/std/containers/unord/unord.set/erase_if.pass.cpp new file mode 100644 index 000000000..e060fda1f --- /dev/null +++ b/test/std/containers/unord/unord.set/erase_if.pass.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase_if(unorderd_set& c, Predicate pred); + +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list; + +template +M make (Init vals) +{ + M ret; + for (int v : vals) + ret.insert(v); + return ret; +} + +template +void +test0(Init vals, Pred p, Init expected) +{ + M s = make (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + M e = make(expected); + assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end()))); +} + + +template +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0({}, is1, {}); + + test0({1}, is1, {}); + test0({1}, is2, {1}); + + test0({1,2}, is1, {2}); + test0({1,2}, is2, {1}); + test0({1,2}, is3, {1,2}); + + test0({1,2,3}, is1, {2,3}); + test0({1,2,3}, is2, {1,3}); + test0({1,2,3}, is3, {1,2}); + test0({1,2,3}, is4, {1,2,3}); + + test0({1,2,3}, True, {}); + test0({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test>(); + test, std::equal_to, min_allocator>> (); + test, std::equal_to, test_allocator>> (); + + test>(); + test>(); +} diff --git a/test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp index d3ca7d9b0..188d2f3c0 100644 --- a/test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_nonmember_container_access 201411L */ @@ -24,6 +25,16 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp index 73c8462ca..9b44f6e2c 100644 --- a/test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_incomplete_container_elements 201505L __cpp_lib_list_remove_return_type 201806L __cpp_lib_nonmember_container_access 201411L @@ -26,6 +27,16 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp index 3db799563..e6e65655b 100644 --- a/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_incomplete_container_elements 201505L __cpp_lib_list_remove_return_type 201806L __cpp_lib_nonmember_container_access 201411L @@ -26,6 +27,16 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp index ffcc003e3..e7dbf7d20 100644 --- a/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_generic_associative_lookup 201304L __cpp_lib_map_try_emplace 201411L __cpp_lib_node_extract 201606L @@ -27,6 +28,16 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp index 96918031d..716eae6d9 100644 --- a/test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_generic_associative_lookup 201304L __cpp_lib_node_extract 201606L __cpp_lib_nonmember_container_access 201411L @@ -26,6 +27,16 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp index 2f408b988..87e8c8f96 100644 --- a/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_char8_t 201811L __cpp_lib_nonmember_container_access 201411L __cpp_lib_string_udls 201304L @@ -27,6 +28,16 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + #if TEST_STD_VER > 17 && defined(__cpp_char8_t) # if !defined(__cpp_lib_char8_t) LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); diff --git a/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp index 38e011717..d23a91a30 100644 --- a/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_node_extract 201606L __cpp_lib_nonmember_container_access 201411L __cpp_lib_unordered_map_try_emplace 201411L @@ -26,6 +27,17 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp index 762a07c37..c4dbed14b 100644 --- a/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_node_extract 201606L __cpp_lib_nonmember_container_access 201411L @@ -25,6 +26,16 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp index 9932a61c5..e7cb1942c 100644 --- a/test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_incomplete_container_elements 201505L __cpp_lib_nonmember_container_access 201411L @@ -25,6 +26,16 @@ int main() { // ensure that the macros that are supposed to be defined in are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/test/std/strings/strings.erasure/erase.pass.cpp b/test/std/strings/strings.erasure/erase.pass.cpp new file mode 100644 index 000000000..657a56c73 --- /dev/null +++ b/test/std/strings/strings.erasure/erase.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase(basic_string& c, const U& value); + + +#include +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test0(S s, U val, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase(s, val))); + std::erase(s, val); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); +} + +template +void test() +{ + + test0(S(""), 'a', S("")); + + test0(S("a"), 'a', S("")); + test0(S("a"), 'b', S("a")); + + test0(S("ab"), 'a', S("b")); + test0(S("ab"), 'b', S("a")); + test0(S("ab"), 'c', S("ab")); + test0(S("aa"), 'a', S("")); + test0(S("aa"), 'c', S("aa")); + + test0(S("abc"), 'a', S("bc")); + test0(S("abc"), 'b', S("ac")); + test0(S("abc"), 'c', S("ab")); + test0(S("abc"), 'd', S("abc")); + + test0(S("aab"), 'a', S("b")); + test0(S("aab"), 'b', S("aa")); + test0(S("aab"), 'c', S("aab")); + test0(S("abb"), 'a', S("bb")); + test0(S("abb"), 'b', S("a")); + test0(S("abb"), 'c', S("abb")); + test0(S("aaa"), 'a', S("")); + test0(S("aaa"), 'b', S("aaa")); + +// Test cross-type erasure + using opt = std::optional; + test0(S("aba"), opt(), S("aba")); + test0(S("aba"), opt('a'), S("b")); + test0(S("aba"), opt('b'), S("aa")); + test0(S("aba"), opt('c'), S("aba")); +} + +int main() +{ + test(); + test, min_allocator>> (); + test, test_allocator>> (); +} diff --git a/test/std/strings/strings.erasure/erase_if.pass.cpp b/test/std/strings/strings.erasure/erase_if.pass.cpp new file mode 100644 index 000000000..d7014868f --- /dev/null +++ b/test/std/strings/strings.erasure/erase_if.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// void erase_if(basic_string& c, Predicate pred); + +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template +void +test0(S s, Pred p, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); +} + +template +void test() +{ + auto isA = [](auto ch) { return ch == 'a';}; + auto isB = [](auto ch) { return ch == 'b';}; + auto isC = [](auto ch) { return ch == 'c';}; + auto isD = [](auto ch) { return ch == 'd';}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0(S(""), isA, S("")); + + test0(S("a"), isA, S("")); + test0(S("a"), isB, S("a")); + + test0(S("ab"), isA, S("b")); + test0(S("ab"), isB, S("a")); + test0(S("ab"), isC, S("ab")); + test0(S("aa"), isA, S("")); + test0(S("aa"), isC, S("aa")); + + test0(S("abc"), isA, S("bc")); + test0(S("abc"), isB, S("ac")); + test0(S("abc"), isC, S("ab")); + test0(S("abc"), isD, S("abc")); + + test0(S("aab"), isA, S("b")); + test0(S("aab"), isB, S("aa")); + test0(S("aab"), isC, S("aab")); + test0(S("abb"), isA, S("bb")); + test0(S("abb"), isB, S("a")); + test0(S("abb"), isC, S("abb")); + test0(S("aaa"), isA, S("")); + test0(S("aaa"), isB, S("aaa")); + + test0(S("aba"), False, S("aba")); + test0(S("aba"), True, S("")); +} + +int main() +{ + test(); + test, min_allocator>> (); + test, test_allocator>> (); +} diff --git a/www/cxx2a_status.html b/www/cxx2a_status.html index 349d3c2bf..581191c76 100644 --- a/www/cxx2a_status.html +++ b/www/cxx2a_status.html @@ -131,7 +131,7 @@ P1123R0LWGEditorial Guidance for merging P0019r8 and P0528r3San Diego P1148R0LWGCleaning up Clause 20San Diego P1165R1LWGMake stateful allocator propagation more consistent for operator+(basic_string)San Diego - P1209R0LWGAdopt Consistent Container Erasure from Library Fundamentals 2 for C++20San Diego + P1209R0LWGAdopt Consistent Container Erasure from Library Fundamentals 2 for C++20San DiegoComplete8.0 P1210R0LWGCompleting the Rebase of Library Fundamentals, Version 3, Working DraftSan Diego P1236R1CWGAlternative Wording for P0907R4 Signed Integers are Two's ComplementSan Diego P1248R1LWGRemove CommonReference requirement from StrictWeakOrdering (a.k.a Fixing Relations)San Diego From 09e67411b752e2bcb276aef6ef9ac58ee36618a4 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Fri, 14 Dec 2018 19:25:22 +0000 Subject: [PATCH 35/94] When resolving a merge conflict, I put something inside an #ifdef. Fixed. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349181 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/version b/include/version index 552d663d0..d6ccb138f 100644 --- a/include/version +++ b/include/version @@ -121,8 +121,8 @@ __cpp_lib_void_t 201411L #if _LIBCPP_STD_VER > 17 #ifndef _LIBCPP_NO_HAS_CHAR8_T # define __cpp_lib_char8_t 201811L -#define __cpp_lib_erase_if 201811L #endif +#define __cpp_lib_erase_if 201811L #endif #endif // _LIBCPP_VERSIONH From 03017b26751a5c41c46bfc30b00b50a3ef65880f Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Fri, 14 Dec 2018 20:22:44 +0000 Subject: [PATCH 36/94] [libcxx] Mark some tests as still failing on macosx10.14 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349187 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/libcxx/language.support/cxa_deleted_virtual.pass.cpp | 1 + .../std/utilities/charconv/charconv.from.chars/integral.pass.cpp | 1 + test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/test/libcxx/language.support/cxa_deleted_virtual.pass.cpp b/test/libcxx/language.support/cxa_deleted_virtual.pass.cpp index ddef5d00e..7e3130cf9 100644 --- a/test/libcxx/language.support/cxa_deleted_virtual.pass.cpp +++ b/test/libcxx/language.support/cxa_deleted_virtual.pass.cpp @@ -12,6 +12,7 @@ // Test exporting the symbol: "__cxa_deleted_virtual" in macosx // But don't expect the symbol to be exported in previous versions. // +// XFAIL: with_system_cxx_lib=macosx10.14 // XFAIL: with_system_cxx_lib=macosx10.13 // XFAIL: with_system_cxx_lib=macosx10.12 // XFAIL: with_system_cxx_lib=macosx10.11 diff --git a/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp b/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp index b6a940f80..4dec67e87 100644 --- a/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp +++ b/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp @@ -9,6 +9,7 @@ // UNSUPPORTED: c++98, c++03, c++11 +// XFAIL: with_system_cxx_lib=macosx10.14 // XFAIL: with_system_cxx_lib=macosx10.13 // XFAIL: with_system_cxx_lib=macosx10.12 // XFAIL: with_system_cxx_lib=macosx10.11 diff --git a/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp b/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp index ab78ca464..ddf614e33 100644 --- a/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp +++ b/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp @@ -9,6 +9,7 @@ // UNSUPPORTED: c++98, c++03, c++11 +// XFAIL: with_system_cxx_lib=macosx10.14 // XFAIL: with_system_cxx_lib=macosx10.13 // XFAIL: with_system_cxx_lib=macosx10.12 // XFAIL: with_system_cxx_lib=macosx10.11 From 01fac08922c500d79b295cc1a2d2ba6dd16434cd Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Fri, 14 Dec 2018 20:42:36 +0000 Subject: [PATCH 37/94] Tolerate Clangs new static_assert messages git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349189 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../utility/pairs/pairs.pair/pair.tuple_element.fail.cpp | 2 +- .../variant.variant/variant.helper/variant_alternative.fail.cpp | 2 +- .../alg.modifying.operations/alg.random.sample/sample.fail.cpp | 2 +- test/std/containers/sequences/array/array.tuple/get.fail.cpp | 2 +- .../sequences/array/array.tuple/tuple_element.fail.cpp | 2 +- test/std/containers/views/span.cons/default.fail.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp index 2a92240a6..2a25780b0 100644 --- a/test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp @@ -20,6 +20,6 @@ int main() { typedef std::pair P; std::tuple_element<2, P>::type foo; // expected-note {{requested here}} - // expected-error@utility:* {{static_assert failed "Index out of bounds in std::tuple_element>"}} + // expected-error-re@utility:* {{static_assert failed{{( due to requirement '2UL < 2')?}} "Index out of bounds in std::tuple_element>"}} } } diff --git a/test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.cpp b/test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.cpp index f39a445b9..2559048d5 100644 --- a/test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.cpp +++ b/test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.cpp @@ -31,6 +31,6 @@ int main() { typedef std::variant T; std::variant_alternative<2, T>::type foo; // expected-note {{requested here}} - // expected-error@variant:* {{static_assert failed "Index out of bounds in std::variant_alternative<>"}} + // expected-error-re@variant:* {{static_assert failed{{( due to requirement '2UL < sizeof...\(_Types\)')?}} "Index out of bounds in std::variant_alternative<>"}} } } diff --git a/test/std/algorithms/alg.modifying.operations/alg.random.sample/sample.fail.cpp b/test/std/algorithms/alg.modifying.operations/alg.random.sample/sample.fail.cpp index d769ad850..3d37d052c 100644 --- a/test/std/algorithms/alg.modifying.operations/alg.random.sample/sample.fail.cpp +++ b/test/std/algorithms/alg.modifying.operations/alg.random.sample/sample.fail.cpp @@ -34,7 +34,7 @@ template void test() { } int main() { - // expected-error@algorithm:* {{static_assert failed "SampleIterator must meet the requirements of RandomAccessIterator"}} + // expected-error-re@algorithm:* {{static_assert failed{{( due to requirement '.*')?}} "SampleIterator must meet the requirements of RandomAccessIterator"}} // expected-error@algorithm:* 2 {{does not provide a subscript operator}} // expected-error@algorithm:* {{invalid operands}} test, output_iterator >(); diff --git a/test/std/containers/sequences/array/array.tuple/get.fail.cpp b/test/std/containers/sequences/array/array.tuple/get.fail.cpp index 45e1d2b46..d575b088a 100644 --- a/test/std/containers/sequences/array/array.tuple/get.fail.cpp +++ b/test/std/containers/sequences/array/array.tuple/get.fail.cpp @@ -31,6 +31,6 @@ int main() typedef std::array C; C c = {1, 2, 3.5}; std::get<3>(c) = 5.5; // expected-note {{requested here}} - // expected-error@array:* {{static_assert failed "Index out of bounds in std::get<> (std::array)"}} + // expected-error-re@array:* {{static_assert failed{{( due to requirement '3UL < 3UL')?}} "Index out of bounds in std::get<> (std::array)"}} } } diff --git a/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp b/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp index c9fe695f9..dd29d1263 100644 --- a/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp +++ b/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp @@ -30,6 +30,6 @@ int main() typedef double T; typedef std::array C; std::tuple_element<3, C> foo; // expected-note {{requested here}} - // expected-error@array:* {{static_assert failed "Index out of bounds in std::tuple_element<> (std::array)"}} + // expected-error-re@array:* {{static_assert failed{{( due to requirement '3UL < 3UL')?}} "Index out of bounds in std::tuple_element<> (std::array)"}} } } diff --git a/test/std/containers/views/span.cons/default.fail.cpp b/test/std/containers/views/span.cons/default.fail.cpp index e30425cfe..ef63a6e31 100644 --- a/test/std/containers/views/span.cons/default.fail.cpp +++ b/test/std/containers/views/span.cons/default.fail.cpp @@ -25,7 +25,7 @@ int main () { - std::span s; // expected-error@span:* {{static_assert failed "Can't default construct a statically sized span with size > 0"}} + std::span s; // expected-error-re@span:* {{static_assert failed{{( due to requirement '2L == 0')?}} "Can't default construct a statically sized span with size > 0"}} // TODO: This is what I want: // eXpected-error {{no matching constructor for initialization of 'std::span'}} From c9296e7eabe018f33fb597e56b3ccda919ebd785 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Sat, 15 Dec 2018 03:24:33 +0000 Subject: [PATCH 38/94] Rework docker setup to make it easier to work around bugs on buildbots git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349234 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/docker/debian9/Dockerfile | 6 ++++-- utils/docker/scripts/docker_start_buildbots.sh | 8 ++++++++ utils/docker/scripts/run_buildbot.sh | 7 +++++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100755 utils/docker/scripts/docker_start_buildbots.sh diff --git a/utils/docker/debian9/Dockerfile b/utils/docker/debian9/Dockerfile index 560cbd148..8dc43f401 100644 --- a/utils/docker/debian9/Dockerfile +++ b/utils/docker/debian9/Dockerfile @@ -109,5 +109,7 @@ RUN apt-get install -y --no-install-recommends \ python \ buildbot-slave -ADD scripts /libcxx-scripts/ -RUN /libcxx-scripts/install_clang_packages.sh +ADD scripts/install_clang_packages.sh /tmp/install_clang_packages.sh +RUN /tmp/install_clang_packages.sh && rm /tmp/install_clang_packages.sh + +RUN git clone https://git.llvm.org/git/libcxx.git /libcxx diff --git a/utils/docker/scripts/docker_start_buildbots.sh b/utils/docker/scripts/docker_start_buildbots.sh new file mode 100755 index 000000000..1da394258 --- /dev/null +++ b/utils/docker/scripts/docker_start_buildbots.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -x + +# Update the libc++ sources in the image in order to use the most recent version of +# run_buildbots.sh +cd /libcxx +git pull +source utils/docker/scripts/run_buildbots.sh "$@" diff --git a/utils/docker/scripts/run_buildbot.sh b/utils/docker/scripts/run_buildbot.sh index 10cc09b6f..45f5a1cf6 100755 --- a/utils/docker/scripts/run_buildbot.sh +++ b/utils/docker/scripts/run_buildbot.sh @@ -12,6 +12,13 @@ mkdir -p $BOT_DIR apt-get update -y apt-get upgrade -y +# FIXME(EricWF): Remove this hack. It's only in place to temporarily fix linking libclang_rt from the +# debian packages. +# WARNING: If you're not a buildbot, DO NOT RUN! +apt-get install lld-8 +rm /usr/bin/ld +ln -s /usr/bin/lld-8 /usr/bin/ld + systemctl set-property buildslave.service TasksMax=100000 buildslave stop $BOT_DIR From 9468ef149484bfb4b6b1de6342e7ce6c37bf0232 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Sat, 15 Dec 2018 03:45:21 +0000 Subject: [PATCH 39/94] Fix bug in buildbot start script git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349235 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/docker/scripts/docker_start_buildbots.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/docker/scripts/docker_start_buildbots.sh b/utils/docker/scripts/docker_start_buildbots.sh index 1da394258..a1d252dac 100755 --- a/utils/docker/scripts/docker_start_buildbots.sh +++ b/utils/docker/scripts/docker_start_buildbots.sh @@ -5,4 +5,4 @@ set -x # run_buildbots.sh cd /libcxx git pull -source utils/docker/scripts/run_buildbots.sh "$@" +/libcxx/utils/docker/scripts/run_buildbots.sh "$@" From 48df810b1a158f2a898dc34e81def13d5d1abb6a Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Sat, 15 Dec 2018 03:48:08 +0000 Subject: [PATCH 40/94] Try 2: Fix bug in buildbot start script git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349236 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/docker/scripts/docker_start_buildbots.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/docker/scripts/docker_start_buildbots.sh b/utils/docker/scripts/docker_start_buildbots.sh index a1d252dac..f47ddcd24 100755 --- a/utils/docker/scripts/docker_start_buildbots.sh +++ b/utils/docker/scripts/docker_start_buildbots.sh @@ -5,4 +5,4 @@ set -x # run_buildbots.sh cd /libcxx git pull -/libcxx/utils/docker/scripts/run_buildbots.sh "$@" +/libcxx/utils/docker/scripts/run_buildbot.sh "$@" From 8c36703b2b27d0b0089049ab6872bc31fb9f8952 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Sat, 15 Dec 2018 05:18:56 +0000 Subject: [PATCH 41/94] Fix static assert diagnostic checks in i386 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349252 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../utility/pairs/pairs.pair/pair.tuple_element.fail.cpp | 2 +- .../variant.variant/variant.helper/variant_alternative.fail.cpp | 2 +- test/std/containers/sequences/array/array.tuple/get.fail.cpp | 2 +- .../sequences/array/array.tuple/tuple_element.fail.cpp | 2 +- test/std/containers/views/span.cons/default.fail.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp index 2a25780b0..8bfeeea5d 100644 --- a/test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp @@ -20,6 +20,6 @@ int main() { typedef std::pair P; std::tuple_element<2, P>::type foo; // expected-note {{requested here}} - // expected-error-re@utility:* {{static_assert failed{{( due to requirement '2UL < 2')?}} "Index out of bounds in std::tuple_element>"}} + // expected-error-re@utility:* {{static_assert failed{{( due to requirement '2U[L]{0,2} < 2')?}} "Index out of bounds in std::tuple_element>"}} } } diff --git a/test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.cpp b/test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.cpp index 2559048d5..c4522682c 100644 --- a/test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.cpp +++ b/test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.cpp @@ -31,6 +31,6 @@ int main() { typedef std::variant T; std::variant_alternative<2, T>::type foo; // expected-note {{requested here}} - // expected-error-re@variant:* {{static_assert failed{{( due to requirement '2UL < sizeof...\(_Types\)')?}} "Index out of bounds in std::variant_alternative<>"}} + // expected-error-re@variant:* {{static_assert failed{{( due to requirement '2U[L]{0,2} < sizeof...\(_Types\)')?}} "Index out of bounds in std::variant_alternative<>"}} } } diff --git a/test/std/containers/sequences/array/array.tuple/get.fail.cpp b/test/std/containers/sequences/array/array.tuple/get.fail.cpp index d575b088a..a7e56fcce 100644 --- a/test/std/containers/sequences/array/array.tuple/get.fail.cpp +++ b/test/std/containers/sequences/array/array.tuple/get.fail.cpp @@ -31,6 +31,6 @@ int main() typedef std::array C; C c = {1, 2, 3.5}; std::get<3>(c) = 5.5; // expected-note {{requested here}} - // expected-error-re@array:* {{static_assert failed{{( due to requirement '3UL < 3UL')?}} "Index out of bounds in std::get<> (std::array)"}} + // expected-error-re@array:* {{static_assert failed{{( due to requirement '3U[L]{0,2} < 3U[L]{0,2}')?}} "Index out of bounds in std::get<> (std::array)"}} } } diff --git a/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp b/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp index dd29d1263..2139fc1ad 100644 --- a/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp +++ b/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp @@ -30,6 +30,6 @@ int main() typedef double T; typedef std::array C; std::tuple_element<3, C> foo; // expected-note {{requested here}} - // expected-error-re@array:* {{static_assert failed{{( due to requirement '3UL < 3UL')?}} "Index out of bounds in std::tuple_element<> (std::array)"}} + // expected-error-re@array:* {{static_assert failed{{( due to requirement '3U[L]{0,2} < 3U[L]{0,2}')?}} "Index out of bounds in std::tuple_element<> (std::array)"}} } } diff --git a/test/std/containers/views/span.cons/default.fail.cpp b/test/std/containers/views/span.cons/default.fail.cpp index ef63a6e31..813939f39 100644 --- a/test/std/containers/views/span.cons/default.fail.cpp +++ b/test/std/containers/views/span.cons/default.fail.cpp @@ -25,7 +25,7 @@ int main () { - std::span s; // expected-error-re@span:* {{static_assert failed{{( due to requirement '2L == 0')?}} "Can't default construct a statically sized span with size > 0"}} + std::span s; // expected-error-re@span:* {{static_assert failed{{( due to requirement '2[LL]{0,2} == 0')?}} "Can't default construct a statically sized span with size > 0"}} // TODO: This is what I want: // eXpected-error {{no matching constructor for initialization of 'std::span'}} From dc700f1239a92c8b27cadaccfc7e2539864a6164 Mon Sep 17 00:00:00 2001 From: Michal Gorny Date: Sun, 16 Dec 2018 09:18:26 +0000 Subject: [PATCH 42/94] [regex] Use distinct __regex_word on NetBSD NetBSD defines character classes up to 0x2000. Use 0x8000 as a safe __regex_word that hopefully will not collide with other values in the foreseeable future. Differential Revision: https://reviews.llvm.org/D55657 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349293 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/regex | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/regex b/include/regex index 18585003a..bd83d7c10 100644 --- a/include/regex +++ b/include/regex @@ -990,6 +990,10 @@ public: #if defined(__mips__) && defined(__GLIBC__) static const char_class_type __regex_word = static_cast(_ISbit(15)); +#elif defined(__NetBSD__) + // NetBSD defines classes up to 0x2000 + // see sys/ctype_bits.h, _CTYPE_Q + static const char_class_type __regex_word = 0x8000; #else static const char_class_type __regex_word = 0x80; #endif From 36feb1b037d3c0746ffff086c822395284c43473 Mon Sep 17 00:00:00 2001 From: Michal Gorny Date: Sun, 16 Dec 2018 09:18:31 +0000 Subject: [PATCH 43/94] [test] [ctime] Ignore -Wformat-zero-length warnings Explicitly disable the -Wformat-zero-length diagnostic when running ctime tests, since one of the test cases passes zero-length format string to strftime(). When strftime() is appropriately decorated with __attribute__(format, ...), this caused the test to fail because of this warning (e.g. on NetBSD). Differential Revision: https://reviews.llvm.org/D55661 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349294 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/std/utilities/time/date.time/ctime.pass.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/std/utilities/time/date.time/ctime.pass.cpp b/test/std/utilities/time/date.time/ctime.pass.cpp index cd1f32be2..f6dd75d24 100644 --- a/test/std/utilities/time/date.time/ctime.pass.cpp +++ b/test/std/utilities/time/date.time/ctime.pass.cpp @@ -26,6 +26,10 @@ #endif #endif +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wformat-zero-length" +#endif + int main() { std::clock_t c = 0; From a443a0013d336593743fa1d523f2ee428814beb1 Mon Sep 17 00:00:00 2001 From: Michal Gorny Date: Sun, 16 Dec 2018 15:12:06 +0000 Subject: [PATCH 44/94] [test] [support] Use socket()+bind() to create unix sockets portably Replace the mknod() call with socket() + bind() for creating unix sockets. The mknod() method is not portable and does not work on NetBSD while binding the socket should work on all systems supporting unix sockets. Differential Revision: https://reviews.llvm.org/D55576 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349305 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/support/filesystem_dynamic_test_helper.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/support/filesystem_dynamic_test_helper.py b/test/support/filesystem_dynamic_test_helper.py index 5bb5b258c..078958274 100644 --- a/test/support/filesystem_dynamic_test_helper.py +++ b/test/support/filesystem_dynamic_test_helper.py @@ -1,5 +1,6 @@ import sys import os +import socket import stat # Ensure that this is being run on a specific platform @@ -76,8 +77,13 @@ def create_fifo(source): def create_socket(source): - mode = 0o600 | stat.S_IFSOCK - os.mknod(sanitize(source), mode) + sock = socket.socket(socket.AF_UNIX) + sanitized_source = sanitize(source) + # AF_UNIX sockets may have very limited path length, so split it + # into chdir call (with technically unlimited length) followed + # by bind() relative to the directory + os.chdir(os.path.dirname(sanitized_source)) + sock.bind(os.path.basename(sanitized_source)) if __name__ == '__main__': From 8f7fa38fb91c2d8e22b1ce23d89d8521660472be Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Mon, 17 Dec 2018 16:04:39 +0000 Subject: [PATCH 45/94] [libcxx] Speeding up partition_point/lower_bound/upper_bound This is a re-application of r345525, which had been reverted by fear of a regression. Reviewed as https://reviews.llvm.org/D53994. Thanks to Denis Yaroshevskiy for the patch. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349358 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../algorithms.partition_point.bench.cpp | 124 ++++++++++++++++++ include/algorithm | 34 ++++- test/libcxx/algorithms/half_positive.pass.cpp | 56 ++++++++ 3 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 benchmarks/algorithms.partition_point.bench.cpp create mode 100644 test/libcxx/algorithms/half_positive.pass.cpp diff --git a/benchmarks/algorithms.partition_point.bench.cpp b/benchmarks/algorithms.partition_point.bench.cpp new file mode 100644 index 000000000..00a3bb272 --- /dev/null +++ b/benchmarks/algorithms.partition_point.bench.cpp @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include +#include + +#include "benchmark/benchmark.h" + +#include "CartesianBenchmarks.hpp" +#include "GenerateInput.hpp" + +namespace { + +template +std::array every_10th_percentile_N(I first, N n) { + N step = n / 10; + std::array res; + + for (size_t i = 0; i < 10; ++i) { + res[i] = first; + std::advance(first, step); + } + + return res; +} + +template +struct TestIntBase { + static std::vector generateInput(size_t size) { + std::vector Res(size); + std::generate(Res.begin(), Res.end(), + [] { return getRandomInteger(); }); + return Res; + } +}; + +struct TestInt32 : TestIntBase { + static constexpr const char* Name = "TestInt32"; +}; + +struct TestInt64 : TestIntBase { + static constexpr const char* Name = "TestInt64"; +}; + +struct TestUint32 : TestIntBase { + static constexpr const char* Name = "TestUint32"; +}; + +struct TestMediumString { + static constexpr const char* Name = "TestMediumString"; + static constexpr size_t StringSize = 32; + + static std::vector generateInput(size_t size) { + std::vector Res(size); + std::generate(Res.begin(), Res.end(), [] { return getRandomString(StringSize); }); + return Res; + } +}; + +using AllTestTypes = std::tuple; + +struct LowerBoundAlg { + template + I operator()(I first, I last, const V& value) const { + return std::lower_bound(first, last, value); + } + + static constexpr const char* Name = "LowerBoundAlg"; +}; + +struct UpperBoundAlg { + template + I operator()(I first, I last, const V& value) const { + return std::upper_bound(first, last, value); + } + + static constexpr const char* Name = "UpperBoundAlg"; +}; + +struct EqualRangeAlg { + template + std::pair operator()(I first, I last, const V& value) const { + return std::equal_range(first, last, value); + } + + static constexpr const char* Name = "EqualRangeAlg"; +}; + +using AllAlgs = std::tuple; + +template +struct PartitionPointBench { + size_t Quantity; + + std::string name() const { + return std::string("PartitionPointBench_") + Alg::Name + "_" + + TestType::Name + '/' + std::to_string(Quantity); + } + + void run(benchmark::State& state) const { + auto Data = TestType::generateInput(Quantity); + std::sort(Data.begin(), Data.end()); + auto Every10Percentile = every_10th_percentile_N(Data.begin(), Data.size()); + + for (auto _ : state) { + for (auto Test : Every10Percentile) + benchmark::DoNotOptimize(Alg{}(Data.begin(), Data.end(), *Test)); + } + } +}; + +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + const std::vector Quantities = {1 << 8, 1 << 10, 1 << 20}; + makeCartesianProductBenchmark( + Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/include/algorithm b/include/algorithm index 9f425cf99..d102899f2 100644 --- a/include/algorithm +++ b/include/algorithm @@ -750,6 +750,32 @@ public: bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);} }; +// Perform division by two quickly for positive integers (llvm.org/PR39129) + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + is_integral<_Integral>::value, + _Integral +>::type +__half_positive(_Integral __value) +{ + return static_cast<_Integral>(static_cast::type>(__value) / 2); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + !is_integral<_Tp>::value, + _Tp +>::type +__half_positive(_Tp __value) +{ + return __value / 2; +} + #ifdef _LIBCPP_DEBUG template @@ -3202,7 +3228,7 @@ partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __ difference_type __len = _VSTD::distance(__first, __last); while (__len != 0) { - difference_type __l2 = __len / 2; + difference_type __l2 = _VSTD::__half_positive(__len); _ForwardIterator __m = __first; _VSTD::advance(__m, __l2); if (__pred(*__m)) @@ -4070,7 +4096,7 @@ __lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va difference_type __len = _VSTD::distance(__first, __last); while (__len != 0) { - difference_type __l2 = __len / 2; + difference_type __l2 = _VSTD::__half_positive(__len); _ForwardIterator __m = __first; _VSTD::advance(__m, __l2); if (__comp(*__m, __value_)) @@ -4112,7 +4138,7 @@ __upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va difference_type __len = _VSTD::distance(__first, __last); while (__len != 0) { - difference_type __l2 = __len / 2; + difference_type __l2 = _VSTD::__half_positive(__len); _ForwardIterator __m = __first; _VSTD::advance(__m, __l2); if (__comp(__value_, *__m)) @@ -4154,7 +4180,7 @@ __equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va difference_type __len = _VSTD::distance(__first, __last); while (__len != 0) { - difference_type __l2 = __len / 2; + difference_type __l2 = _VSTD::__half_positive(__len); _ForwardIterator __m = __first; _VSTD::advance(__m, __l2); if (__comp(*__m, __value_)) diff --git a/test/libcxx/algorithms/half_positive.pass.cpp b/test/libcxx/algorithms/half_positive.pass.cpp new file mode 100644 index 000000000..7dcfc2c92 --- /dev/null +++ b/test/libcxx/algorithms/half_positive.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// __half_positive divides an integer number by 2 as unsigned number for known types. +// It can be an important optimization for lower bound, for example. + +#include +#include +#include +#include + +#include "test_macros.h" +#include "user_defined_integral.hpp" + +namespace { + +template +TEST_CONSTEXPR bool test(IntType max_v = IntType(std::numeric_limits::max())) { + return std::__half_positive(max_v) == max_v / 2; +} + +} // namespace + +int main() +{ + { + assert(test()); + assert(test()); + assert(test()); + assert((test, int>())); + assert(test()); +#if !defined(_LIBCPP_HAS_NO_INT128) + assert(test<__int128_t>()); +#endif // !defined(_LIBCPP_HAS_NO_INT128) + } + +#if TEST_STD_VER >= 11 + { + static_assert(test(), ""); + static_assert(test(), ""); + static_assert(test(), ""); + static_assert(test(), ""); +#if !defined(_LIBCPP_HAS_NO_INT128) + static_assert(test<__int128_t>(), ""); +#endif // !defined(_LIBCPP_HAS_NO_INT128) + } +#endif // TEST_STD_VER >= 11 +} From 2d0643acea179e0a899f23829eb85645bb7b29e9 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Mon, 17 Dec 2018 16:56:24 +0000 Subject: [PATCH 46/94] Expect Clang diagnostics in std::launder test git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349364 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../support.dynamic/ptr.launder/launder.types.fail.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp b/test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp index 71f5e4588..6328ff93a 100644 --- a/test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp +++ b/test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp @@ -29,6 +29,8 @@ int main () (void) std::launder((const void *) nullptr); (void) std::launder(( volatile void *) nullptr); (void) std::launder((const volatile void *) nullptr); // expected-error-re@new:* 4 {{static_assert failed{{.*}} "can't launder cv-void"}} + // expected-error@new:* 4 {{void pointer argument to '__builtin_launder' is not allowed}} (void) std::launder(foo); // expected-error-re@new:* 1 {{static_assert failed{{.*}} "can't launder functions"}} + // expected-error@new:* {{function pointer argument to '__builtin_launder' is not allowed}} } From 50f14e23b572461e779408aab1d64f60bcceb946 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Mon, 17 Dec 2018 18:37:59 +0000 Subject: [PATCH 47/94] Unbreak green dragon bots w/o __builtin_launder git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349373 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../support.dynamic/ptr.launder/launder.types.fail.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp b/test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp index 6328ff93a..034c578bb 100644 --- a/test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp +++ b/test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp @@ -29,8 +29,8 @@ int main () (void) std::launder((const void *) nullptr); (void) std::launder(( volatile void *) nullptr); (void) std::launder((const volatile void *) nullptr); // expected-error-re@new:* 4 {{static_assert failed{{.*}} "can't launder cv-void"}} - // expected-error@new:* 4 {{void pointer argument to '__builtin_launder' is not allowed}} + // expected-error@new:* 0-4 {{void pointer argument to '__builtin_launder' is not allowed}} (void) std::launder(foo); // expected-error-re@new:* 1 {{static_assert failed{{.*}} "can't launder functions"}} - // expected-error@new:* {{function pointer argument to '__builtin_launder' is not allowed}} + // expected-error@new:* 0-1 {{function pointer argument to '__builtin_launder' is not allowed}} } From c88aa7fa752647cb1c2489c713dc9683cef3a070 Mon Sep 17 00:00:00 2001 From: Michal Gorny Date: Mon, 17 Dec 2018 19:13:41 +0000 Subject: [PATCH 48/94] [test] [re.traits] Remove asserts failing due to invalid UTF-8 Remove the two test cases for \xDA and \xFA with UTF-8 locale, as both characters alone are invalid in UTF-8 (short sequences). Upon removing them, the test passes on Linux again (and also on NetBSD, after adding appropriate locale configuration). Differential Revision: https://reviews.llvm.org/D55746 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349378 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/std/re/re.traits/translate_nocase.pass.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/std/re/re.traits/translate_nocase.pass.cpp b/test/std/re/re.traits/translate_nocase.pass.cpp index 33d365a9e..ae757afee 100644 --- a/test/std/re/re.traits/translate_nocase.pass.cpp +++ b/test/std/re/re.traits/translate_nocase.pass.cpp @@ -19,9 +19,6 @@ // XFAIL: with_system_cxx_lib=macosx10.7 // XFAIL: with_system_cxx_lib=macosx10.8 -// TODO: investigation needed -// XFAIL: linux-gnu - #include #include @@ -47,8 +44,6 @@ int main() assert(t.translate_nocase('.') == '.'); assert(t.translate_nocase('a') == 'a'); assert(t.translate_nocase('1') == '1'); - assert(t.translate_nocase('\xDA') == '\xFA'); - assert(t.translate_nocase('\xFA') == '\xFA'); } { std::regex_traits t; From 4b8645f0dc464acbc501bd107907a5267df98bcc Mon Sep 17 00:00:00 2001 From: Michal Gorny Date: Mon, 17 Dec 2018 19:14:08 +0000 Subject: [PATCH 49/94] [test] Add target_info for NetBSD, and XFAIL some of locale tests Add a target_info definition for NetBSD. The definition is based on the one used by FreeBSD, with libcxxrt replaced by libc++abi, and using llvm-libunwind since we need to use its unwinder implementation to build anyway. Additionally, XFAIL the 30 tests that fail because of non-implemented locale features. According to the manual, NetBSD implements only LC_CTYPE part of locale handling. However, there is a locale database in the system and locale specifications are validated against it, so it makes sense to list the common locales as supported. If I'm counting correctly, this change enables additional 43 passing tests. Differential Revision: https://reviews.llvm.org/D55767 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349379 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../locale.collate.byname/transform.pass.cpp | 3 +++ .../get_long_double_fr_FR.pass.cpp | 3 +++ .../get_long_double_ru_RU.pass.cpp | 3 +++ .../get_long_double_zh_CN.pass.cpp | 3 +++ .../put_long_double_fr_FR.pass.cpp | 3 +++ .../put_long_double_ru_RU.pass.cpp | 3 +++ .../put_long_double_zh_CN.pass.cpp | 3 +++ .../locale.moneypunct.byname/curr_symbol.pass.cpp | 3 +++ .../locale.moneypunct.byname/grouping.pass.cpp | 3 +++ .../locale.moneypunct.byname/neg_format.pass.cpp | 3 +++ .../locale.moneypunct.byname/pos_format.pass.cpp | 3 +++ .../locale.moneypunct.byname/thousands_sep.pass.cpp | 3 +++ .../locale.time.get.byname/get_date.pass.cpp | 3 +++ .../locale.time.get.byname/get_date_wide.pass.cpp | 3 +++ .../locale.time.get.byname/get_one.pass.cpp | 3 +++ .../locale.time.get.byname/get_one_wide.pass.cpp | 3 +++ .../locale.time.put.byname/put1.pass.cpp | 3 +++ .../locale.numpunct.byname/grouping.pass.cpp | 3 +++ .../locale.numpunct.byname/thousands_sep.pass.cpp | 3 +++ .../locale/locale.cons/char_pointer.pass.cpp | 3 +++ test/std/re/re.alg/re.alg.match/basic.pass.cpp | 3 +++ test/std/re/re.alg/re.alg.match/ecma.pass.cpp | 3 +++ test/std/re/re.alg/re.alg.match/extended.pass.cpp | 3 +++ test/std/re/re.alg/re.alg.search/awk.pass.cpp | 3 +++ test/std/re/re.alg/re.alg.search/basic.pass.cpp | 3 +++ test/std/re/re.alg/re.alg.search/ecma.pass.cpp | 3 +++ test/std/re/re.alg/re.alg.search/extended.pass.cpp | 3 +++ test/std/re/re.traits/lookup_collatename.pass.cpp | 3 +++ test/std/re/re.traits/transform.pass.cpp | 3 +++ test/std/re/re.traits/transform_primary.pass.cpp | 3 +++ utils/libcxx/test/target_info.py | 13 +++++++++++++ 31 files changed, 103 insertions(+) diff --git a/test/std/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp b/test/std/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp index b39e9ad74..4f738076e 100644 --- a/test/std/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp +++ b/test/std/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_COLLATE at the moment +// XFAIL: netbsd // diff --git a/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp index bebc1f27b..ce046e61e 100644 --- a/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp +++ b/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp @@ -8,6 +8,9 @@ //===----------------------------------------------------------------------===// // // XFAIL: apple-darwin +// +// NetBSD does not support LC_MONETARY at the moment +// XFAIL: netbsd // REQUIRES: locale.fr_FR.UTF-8 diff --git a/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp index 7776c67a6..5b56ab3e7 100644 --- a/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp +++ b/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp @@ -9,6 +9,9 @@ // // This test is passing in an uncontrolled manner in some Apple environment. // UNSUPPORTED: apple-darwin +// +// NetBSD does not support LC_MONETARY at the moment +// XFAIL: netbsd // Failure related to GLIBC's use of U00A0 as mon_thousands_sep // and U002E as mon_decimal_point. diff --git a/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp index 07a33f766..4e62a1bc0 100644 --- a/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp +++ b/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_MONETARY at the moment +// XFAIL: netbsd // REQUIRES: locale.zh_CN.UTF-8 diff --git a/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp index 2b431dc52..2ba29dfff 100644 --- a/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp +++ b/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp @@ -8,6 +8,9 @@ //===----------------------------------------------------------------------===// // // XFAIL: apple-darwin +// +// NetBSD does not support LC_MONETARY at the moment +// XFAIL: netbsd // REQUIRES: locale.fr_FR.UTF-8 diff --git a/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp index 4d805b0f7..56fb85058 100644 --- a/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp +++ b/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp @@ -9,6 +9,9 @@ // // This test is passing in an uncontrolled manner in some Apple environment. // UNSUPPORTED: apple-darwin +// +// NetBSD does not support LC_MONETARY at the moment +// XFAIL: netbsd // Failure related to GLIBC's use of U00A0 as mon_thousands_sep // and U002E as mon_decimal_point. diff --git a/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp index 633e1885e..1036969bb 100644 --- a/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp +++ b/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_MONETARY at the moment +// XFAIL: netbsd // REQUIRES: locale.zh_CN.UTF-8 diff --git a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp index 3a9adc4bb..c6cab19b2 100644 --- a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp +++ b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp @@ -8,6 +8,9 @@ //===----------------------------------------------------------------------===// // // XFAIL: apple-darwin +// +// NetBSD does not support LC_MONETARY at the moment +// XFAIL: netbsd // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.fr_FR.UTF-8 diff --git a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/grouping.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/grouping.pass.cpp index b0b9da0b6..f050164b6 100644 --- a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/grouping.pass.cpp +++ b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/grouping.pass.cpp @@ -8,6 +8,9 @@ //===----------------------------------------------------------------------===// // // XFAIL: apple-darwin +// +// NetBSD does not support LC_MONETARY at the moment +// XFAIL: netbsd // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.fr_FR.UTF-8 diff --git a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/neg_format.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/neg_format.pass.cpp index 3fe9faf84..edbaf8600 100644 --- a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/neg_format.pass.cpp +++ b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/neg_format.pass.cpp @@ -8,6 +8,9 @@ //===----------------------------------------------------------------------===// // // XFAIL: apple-darwin +// +// NetBSD does not support LC_MONETARY at the moment +// XFAIL: netbsd // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.fr_FR.UTF-8 diff --git a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/pos_format.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/pos_format.pass.cpp index 7038ab16e..f401b72d8 100644 --- a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/pos_format.pass.cpp +++ b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/pos_format.pass.cpp @@ -8,6 +8,9 @@ //===----------------------------------------------------------------------===// // // XFAIL: apple-darwin +// +// NetBSD does not support LC_MONETARY at the moment +// XFAIL: netbsd // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.fr_FR.UTF-8 diff --git a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp index ca8abf09b..90fb7193e 100644 --- a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp +++ b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_MONETARY at the moment +// XFAIL: netbsd // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.fr_FR.UTF-8 diff --git a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp index af15b174b..2b6ade5c0 100644 --- a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp +++ b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_TIME at the moment +// XFAIL: netbsd // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.fr_FR.UTF-8 diff --git a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date_wide.pass.cpp b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date_wide.pass.cpp index 1cd9f462e..ec1e3e7c9 100644 --- a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date_wide.pass.cpp +++ b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date_wide.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_TIME at the moment +// XFAIL: netbsd // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.fr_FR.UTF-8 diff --git a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp index 72b63278d..6cf3b6aef 100644 --- a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp +++ b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_TIME at the moment +// XFAIL: netbsd // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.fr_FR.UTF-8 diff --git a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp index 4a2b3819b..1e7c170da 100644 --- a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp +++ b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_TIME at the moment +// XFAIL: netbsd // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.fr_FR.UTF-8 diff --git a/test/std/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp b/test/std/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp index 3e7538d66..8e79357b5 100644 --- a/test/std/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp +++ b/test/std/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_TIME at the moment +// XFAIL: netbsd // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.fr_FR.UTF-8 diff --git a/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp b/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp index f3df52a21..1f2aeeabd 100644 --- a/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp +++ b/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_NUMERIC at the moment +// XFAIL: netbsd // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.fr_FR.UTF-8 diff --git a/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp b/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp index 0dedf78c9..b84f3a1c7 100644 --- a/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp +++ b/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_NUMERIC at the moment +// XFAIL: netbsd // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.fr_FR.UTF-8 diff --git a/test/std/localization/locales/locale/locale.cons/char_pointer.pass.cpp b/test/std/localization/locales/locale/locale.cons/char_pointer.pass.cpp index aef2ea93d..7ba64b051 100644 --- a/test/std/localization/locales/locale/locale.cons/char_pointer.pass.cpp +++ b/test/std/localization/locales/locale/locale.cons/char_pointer.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support most of LC_* at the moment +// XFAIL: netbsd // REQUIRES: locale.ru_RU.UTF-8 // REQUIRES: locale.zh_CN.UTF-8 diff --git a/test/std/re/re.alg/re.alg.match/basic.pass.cpp b/test/std/re/re.alg/re.alg.match/basic.pass.cpp index cb23cfa15..5140ec917 100644 --- a/test/std/re/re.alg/re.alg.match/basic.pass.cpp +++ b/test/std/re/re.alg/re.alg.match/basic.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_COLLATE at the moment +// XFAIL: netbsd // REQUIRES: locale.cs_CZ.ISO8859-2 diff --git a/test/std/re/re.alg/re.alg.match/ecma.pass.cpp b/test/std/re/re.alg/re.alg.match/ecma.pass.cpp index ae42b4666..a676e9e52 100644 --- a/test/std/re/re.alg/re.alg.match/ecma.pass.cpp +++ b/test/std/re/re.alg/re.alg.match/ecma.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_COLLATE at the moment +// XFAIL: netbsd // REQUIRES: locale.cs_CZ.ISO8859-2 diff --git a/test/std/re/re.alg/re.alg.match/extended.pass.cpp b/test/std/re/re.alg/re.alg.match/extended.pass.cpp index aac03839a..8aa71f75d 100644 --- a/test/std/re/re.alg/re.alg.match/extended.pass.cpp +++ b/test/std/re/re.alg/re.alg.match/extended.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_COLLATE at the moment +// XFAIL: netbsd // REQUIRES: locale.cs_CZ.ISO8859-2 diff --git a/test/std/re/re.alg/re.alg.search/awk.pass.cpp b/test/std/re/re.alg/re.alg.search/awk.pass.cpp index be0c74e9c..85f38ec63 100644 --- a/test/std/re/re.alg/re.alg.search/awk.pass.cpp +++ b/test/std/re/re.alg/re.alg.search/awk.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_COLLATE at the moment +// XFAIL: netbsd // REQUIRES: locale.cs_CZ.ISO8859-2 diff --git a/test/std/re/re.alg/re.alg.search/basic.pass.cpp b/test/std/re/re.alg/re.alg.search/basic.pass.cpp index 11982a26d..82f051a07 100644 --- a/test/std/re/re.alg/re.alg.search/basic.pass.cpp +++ b/test/std/re/re.alg/re.alg.search/basic.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_COLLATE at the moment +// XFAIL: netbsd // REQUIRES: locale.cs_CZ.ISO8859-2 diff --git a/test/std/re/re.alg/re.alg.search/ecma.pass.cpp b/test/std/re/re.alg/re.alg.search/ecma.pass.cpp index c41019542..a8ae1f550 100644 --- a/test/std/re/re.alg/re.alg.search/ecma.pass.cpp +++ b/test/std/re/re.alg/re.alg.search/ecma.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_COLLATE at the moment +// XFAIL: netbsd // REQUIRES: locale.cs_CZ.ISO8859-2 diff --git a/test/std/re/re.alg/re.alg.search/extended.pass.cpp b/test/std/re/re.alg/re.alg.search/extended.pass.cpp index 4a2e6647e..6d95ad275 100644 --- a/test/std/re/re.alg/re.alg.search/extended.pass.cpp +++ b/test/std/re/re.alg/re.alg.search/extended.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_COLLATE at the moment +// XFAIL: netbsd // REQUIRES: locale.cs_CZ.ISO8859-2 diff --git a/test/std/re/re.traits/lookup_collatename.pass.cpp b/test/std/re/re.traits/lookup_collatename.pass.cpp index 3aeed7bdd..ef5c14257 100644 --- a/test/std/re/re.traits/lookup_collatename.pass.cpp +++ b/test/std/re/re.traits/lookup_collatename.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_COLLATE at the moment +// XFAIL: netbsd // REQUIRES: locale.cs_CZ.ISO8859-2 diff --git a/test/std/re/re.traits/transform.pass.cpp b/test/std/re/re.traits/transform.pass.cpp index 57e6b753a..7563b3952 100644 --- a/test/std/re/re.traits/transform.pass.cpp +++ b/test/std/re/re.traits/transform.pass.cpp @@ -7,6 +7,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_COLLATE at the moment +// XFAIL: netbsd // REQUIRES: locale.cs_CZ.ISO8859-2 diff --git a/test/std/re/re.traits/transform_primary.pass.cpp b/test/std/re/re.traits/transform_primary.pass.cpp index 03b4f3985..2dd8ed247 100644 --- a/test/std/re/re.traits/transform_primary.pass.cpp +++ b/test/std/re/re.traits/transform_primary.pass.cpp @@ -7,6 +7,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// NetBSD does not support LC_COLLATE at the moment +// XFAIL: netbsd // REQUIRES: locale.cs_CZ.ISO8859-2 diff --git a/utils/libcxx/test/target_info.py b/utils/libcxx/test/target_info.py index 3181d4bd3..32bbb2e11 100644 --- a/utils/libcxx/test/target_info.py +++ b/utils/libcxx/test/target_info.py @@ -182,6 +182,18 @@ class FreeBSDLocalTI(DefaultTargetInfo): flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt'] +class NetBSDLocalTI(DefaultTargetInfo): + def __init__(self, full_config): + super(NetBSDLocalTI, self).__init__(full_config) + + def add_locale_features(self, features): + add_common_locales(features, self.full_config.lit_config) + + def add_cxx_link_flags(self, flags): + flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lc++abi', + '-lunwind'] + + class LinuxLocalTI(DefaultTargetInfo): def __init__(self, full_config): super(LinuxLocalTI, self).__init__(full_config) @@ -280,6 +292,7 @@ def make_target_info(full_config): target_system = platform.system() if target_system == 'Darwin': return DarwinLocalTI(full_config) if target_system == 'FreeBSD': return FreeBSDLocalTI(full_config) + if target_system == 'NetBSD': return NetBSDLocalTI(full_config) if target_system == 'Linux': return LinuxLocalTI(full_config) if target_system == 'Windows': return WindowsLocalTI(full_config) return DefaultTargetInfo(full_config) From dfa283e2cf5122d0e51a6f6cc2037114dfbd9bd7 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Mon, 17 Dec 2018 20:17:43 +0000 Subject: [PATCH 50/94] Fix FP comparisons when SSE isn't available git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349387 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/std/depr/depr.c.headers/math_h.pass.cpp | 39 ++++++++++++------- test/std/numerics/c.math/cmath.pass.cpp | 3 +- .../generate_canonical.pass.cpp | 28 ++++++------- .../op_divide_duration.pass.cpp | 3 +- test/support/truncate_fp.h | 23 +++++++++++ 5 files changed, 66 insertions(+), 30 deletions(-) create mode 100644 test/support/truncate_fp.h diff --git a/test/std/depr/depr.c.headers/math_h.pass.cpp b/test/std/depr/depr.c.headers/math_h.pass.cpp index 7e1b2d110..e8341a07f 100644 --- a/test/std/depr/depr.c.headers/math_h.pass.cpp +++ b/test/std/depr/depr.c.headers/math_h.pass.cpp @@ -14,6 +14,7 @@ #include #include "hexfloat.h" +#include "truncate_fp.h" // convertible to int/float/double/etc template @@ -807,23 +808,31 @@ void test_atanh() assert(atanh(0) == 0); } -void test_cbrt() -{ - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); +void test_cbrt() { + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - assert(cbrt(1) == 1); + static_assert((std::is_same::value), + ""); + assert(truncate_fp(cbrt(1)) == 1); + } void test_copysign() diff --git a/test/std/numerics/c.math/cmath.pass.cpp b/test/std/numerics/c.math/cmath.pass.cpp index cc535e374..b02bdbe64 100644 --- a/test/std/numerics/c.math/cmath.pass.cpp +++ b/test/std/numerics/c.math/cmath.pass.cpp @@ -16,6 +16,7 @@ #include "test_macros.h" #include "hexfloat.h" +#include "truncate_fp.h" // convertible to int/float/double/etc template @@ -860,7 +861,7 @@ void test_cbrt() static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); - assert(std::cbrt(1) == 1); + assert(truncate_fp(std::cbrt(1)) == 1); } void test_copysign() diff --git a/test/std/numerics/rand/rand.util/rand.util.canonical/generate_canonical.pass.cpp b/test/std/numerics/rand/rand.util/rand.util.canonical/generate_canonical.pass.cpp index 7433e28e4..df2acbe9e 100644 --- a/test/std/numerics/rand/rand.util/rand.util.canonical/generate_canonical.pass.cpp +++ b/test/std/numerics/rand/rand.util/rand.util.canonical/generate_canonical.pass.cpp @@ -15,6 +15,8 @@ #include #include +#include "truncate_fp.h" + int main() { { @@ -22,35 +24,35 @@ int main() typedef float F; E r; F f = std::generate_canonical(r); - assert(f == (16807 - E::min()) / (E::max() - E::min() + F(1))); + assert(f == truncate_fp((16807 - E::min()) / (E::max() - E::min() + F(1)))); } { typedef std::minstd_rand0 E; typedef float F; E r; F f = std::generate_canonical(r); - assert(f == (16807 - E::min()) / (E::max() - E::min() + F(1))); + assert(f == truncate_fp((16807 - E::min()) / (E::max() - E::min() + F(1)))); } { typedef std::minstd_rand0 E; typedef float F; E r; F f = std::generate_canonical::digits - 1>(r); - assert(f == (16807 - E::min()) / (E::max() - E::min() + F(1))); + assert(f == truncate_fp((16807 - E::min()) / (E::max() - E::min() + F(1)))); } { typedef std::minstd_rand0 E; typedef float F; E r; F f = std::generate_canonical::digits>(r); - assert(f == (16807 - E::min()) / (E::max() - E::min() + F(1))); + assert(f == truncate_fp((16807 - E::min()) / (E::max() - E::min() + F(1)))); } { typedef std::minstd_rand0 E; typedef float F; E r; F f = std::generate_canonical::digits + 1>(r); - assert(f == (16807 - E::min()) / (E::max() - E::min() + F(1))); + assert(f == truncate_fp((16807 - E::min()) / (E::max() - E::min() + F(1)))); } { @@ -58,43 +60,43 @@ int main() typedef double F; E r; F f = std::generate_canonical(r); - assert(f == (16807 - E::min()) / (E::max() - E::min() + F(1))); + assert(f == truncate_fp((16807 - E::min()) / (E::max() - E::min() + F(1)))); } { typedef std::minstd_rand0 E; typedef double F; E r; F f = std::generate_canonical(r); - assert(f == (16807 - E::min()) / (E::max() - E::min() + F(1))); + assert(f == truncate_fp((16807 - E::min()) / (E::max() - E::min() + F(1)))); } { typedef std::minstd_rand0 E; typedef double F; E r; F f = std::generate_canonical::digits - 1>(r); - assert(f == + assert(f == truncate_fp( (16807 - E::min() + (282475249 - E::min()) * (E::max() - E::min() + F(1))) / - ((E::max() - E::min() + F(1)) * (E::max() - E::min() + F(1)))); + ((E::max() - E::min() + F(1)) * (E::max() - E::min() + F(1))))); } { typedef std::minstd_rand0 E; typedef double F; E r; F f = std::generate_canonical::digits>(r); - assert(f == + assert(f == truncate_fp( (16807 - E::min() + (282475249 - E::min()) * (E::max() - E::min() + F(1))) / - ((E::max() - E::min() + F(1)) * (E::max() - E::min() + F(1)))); + ((E::max() - E::min() + F(1)) * (E::max() - E::min() + F(1))))); } { typedef std::minstd_rand0 E; typedef double F; E r; F f = std::generate_canonical::digits + 1>(r); - assert(f == + assert(f == truncate_fp( (16807 - E::min() + (282475249 - E::min()) * (E::max() - E::min() + F(1))) / - ((E::max() - E::min() + F(1)) * (E::max() - E::min() + F(1)))); + ((E::max() - E::min() + F(1)) * (E::max() - E::min() + F(1))))); } } diff --git a/test/std/utilities/time/time.duration/time.duration.nonmember/op_divide_duration.pass.cpp b/test/std/utilities/time/time.duration/time.duration.nonmember/op_divide_duration.pass.cpp index 561516b66..4c4895b2a 100644 --- a/test/std/utilities/time/time.duration/time.duration.nonmember/op_divide_duration.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.nonmember/op_divide_duration.pass.cpp @@ -20,6 +20,7 @@ #include #include "test_macros.h" +#include "truncate_fp.h" int main() { @@ -41,7 +42,7 @@ int main() { std::chrono::duration > s1(30); std::chrono::duration > s2(5); - assert(s1 / s2 == 20./3); + assert(s1 / s2 == truncate_fp(20./3)); } #if TEST_STD_VER >= 11 { diff --git a/test/support/truncate_fp.h b/test/support/truncate_fp.h new file mode 100644 index 000000000..83b2b2cff --- /dev/null +++ b/test/support/truncate_fp.h @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +inline long double truncate_fp(long double val) { + volatile long double sink = val; + return sink; +} + +inline double truncate_fp(double val) { + volatile double sink = val; + return sink; +} + +inline float truncate_fp(float val) { + volatile float sink = val; + return sink; +} From ae5d5c854568f1c9f98a784715a862d5fb4330ac Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Mon, 17 Dec 2018 22:22:44 +0000 Subject: [PATCH 51/94] [libcxx][NFC] Properly indent nested #ifdefs and #defines I just realized I had always been reading this wrong because of the lack of indentation, so I'm re-indenting this properly. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349408 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/__config | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/__config b/include/__config index b5e7b7632..728387642 100644 --- a/include/__config +++ b/include/__config @@ -977,14 +977,14 @@ template struct __static_assert_check {}; // If we are getting operator new from the MSVC CRT, then allocation overloads // for align_val_t were added in 19.12, aka VS 2017 version 15.3. #if defined(_LIBCPP_MSVCRT) && defined(_MSC_VER) && _MSC_VER < 1912 -#define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION +# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION #elif defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME) -#define _LIBCPP_DEFER_NEW_TO_VCRUNTIME -#if !defined(__cpp_aligned_new) -// We're defering to Microsoft's STL to provide aligned new et al. We don't -// have it unless the language feature test macro is defined. -#define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION -#endif +# define _LIBCPP_DEFER_NEW_TO_VCRUNTIME +# if !defined(__cpp_aligned_new) + // We're defering to Microsoft's STL to provide aligned new et al. We don't + // have it unless the language feature test macro is defined. +# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION +# endif #endif #if defined(__APPLE__) From 3d4bcc1de64bdd0c5b9161b62b18ca74be851033 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Tue, 18 Dec 2018 00:30:15 +0000 Subject: [PATCH 52/94] [libcxx] Properly mark aligned allocation macro test as XFAIL on OS X This test was initially marked as XFAIL using `XFAIL: macosx10.YY`, and was then moved to `UNSUPPORTED: macosx10.YY`. The intent is to mark the test as XFAILing when a deployment target older than macosx10.14 is used, and the right way to do this is `XFAIL: availability=macosx10.YY`. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349426 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/libcxx/memory/aligned_allocation_macro.pass.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/libcxx/memory/aligned_allocation_macro.pass.cpp b/test/libcxx/memory/aligned_allocation_macro.pass.cpp index 0e13b15f2..2f38262cd 100644 --- a/test/libcxx/memory/aligned_allocation_macro.pass.cpp +++ b/test/libcxx/memory/aligned_allocation_macro.pass.cpp @@ -10,12 +10,12 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 // aligned allocation functions are not provided prior to macosx10.13 -// UNSUPPORTED: macosx10.12 -// UNSUPPORTED: macosx10.11 -// UNSUPPORTED: macosx10.10 -// UNSUPPORTED: macosx10.9 -// UNSUPPORTED: macosx10.8 -// UNSUPPORTED: macosx10.7 +// XFAIL: availability=macosx10.12 +// XFAIL: availability=macosx10.11 +// XFAIL: availability=macosx10.10 +// XFAIL: availability=macosx10.9 +// XFAIL: availability=macosx10.8 +// XFAIL: availability=macosx10.7 #include From b8811ad2ca62f1cbd907751c5e7154848cf9f831 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Tue, 18 Dec 2018 00:42:09 +0000 Subject: [PATCH 53/94] [libcxx] Handle AppleClang 9 and 10 in XFAILs for aligned allocation tests I forgot that those don't behave like Clang trunk, again. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349427 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../memory/aligned_allocation_macro.pass.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/test/libcxx/memory/aligned_allocation_macro.pass.cpp b/test/libcxx/memory/aligned_allocation_macro.pass.cpp index 2f38262cd..5390bef3e 100644 --- a/test/libcxx/memory/aligned_allocation_macro.pass.cpp +++ b/test/libcxx/memory/aligned_allocation_macro.pass.cpp @@ -9,13 +9,14 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 -// aligned allocation functions are not provided prior to macosx10.13 -// XFAIL: availability=macosx10.12 -// XFAIL: availability=macosx10.11 -// XFAIL: availability=macosx10.10 -// XFAIL: availability=macosx10.9 -// XFAIL: availability=macosx10.8 -// XFAIL: availability=macosx10.7 +// Aligned allocation functions are not provided prior to macosx10.13, but +// AppleClang <= 10 does not know about this restriction and always enables them. +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8 +// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7 #include From 6ad953652d6adb076435430080e8581c9ab3e585 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Tue, 18 Dec 2018 13:46:28 +0000 Subject: [PATCH 54/94] [libcxx] Remove XFAILs for older macOS versions That test doesn't fail anymore since r349378, since the assertions that r349378 removed must have been bugs in the dylib at some point. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349484 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/std/re/re.traits/translate_nocase.pass.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/std/re/re.traits/translate_nocase.pass.cpp b/test/std/re/re.traits/translate_nocase.pass.cpp index ae757afee..601da6b86 100644 --- a/test/std/re/re.traits/translate_nocase.pass.cpp +++ b/test/std/re/re.traits/translate_nocase.pass.cpp @@ -16,9 +16,6 @@ // REQUIRES: locale.en_US.UTF-8 -// XFAIL: with_system_cxx_lib=macosx10.7 -// XFAIL: with_system_cxx_lib=macosx10.8 - #include #include From 3af9c5fa77d22ceb28d0573aac4b199f34601055 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Tue, 18 Dec 2018 19:07:30 +0000 Subject: [PATCH 55/94] Rework the C strings tests to use ASSERT_SAME_TYPE. NFC there. Also change cwchar.pass.cpp to avoid constructing a couple things from zero - since apparently they can be enums in some weird C library. NFC there, either, since the values were never used. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349522 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/std/strings/c.strings/cctype.pass.cpp | 49 ++++---- test/std/strings/c.strings/cstring.pass.cpp | 57 +++++---- test/std/strings/c.strings/cuchar.pass.cpp | 2 + test/std/strings/c.strings/cwchar.pass.cpp | 130 ++++++++++---------- test/std/strings/c.strings/cwctype.pass.cpp | 43 ++++--- 5 files changed, 147 insertions(+), 134 deletions(-) diff --git a/test/std/strings/c.strings/cctype.pass.cpp b/test/std/strings/c.strings/cctype.pass.cpp index 027fbcd46..695c5e40d 100644 --- a/test/std/strings/c.strings/cctype.pass.cpp +++ b/test/std/strings/c.strings/cctype.pass.cpp @@ -13,6 +13,8 @@ #include #include +#include "test_macros.h" + #ifdef isalnum #error isalnum defined #endif @@ -71,33 +73,34 @@ int main() { - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - assert(std::isalnum('a')); - assert(std::isalpha('a')); - assert(std::isblank(' ')); + ASSERT_SAME_TYPE(int, decltype(std::isalnum(0))); + ASSERT_SAME_TYPE(int, decltype(std::isalpha(0))); + ASSERT_SAME_TYPE(int, decltype(std::isblank(0))); + ASSERT_SAME_TYPE(int, decltype(std::iscntrl(0))); + ASSERT_SAME_TYPE(int, decltype(std::isdigit(0))); + ASSERT_SAME_TYPE(int, decltype(std::isgraph(0))); + ASSERT_SAME_TYPE(int, decltype(std::islower(0))); + ASSERT_SAME_TYPE(int, decltype(std::isprint(0))); + ASSERT_SAME_TYPE(int, decltype(std::ispunct(0))); + ASSERT_SAME_TYPE(int, decltype(std::isspace(0))); + ASSERT_SAME_TYPE(int, decltype(std::isupper(0))); + ASSERT_SAME_TYPE(int, decltype(std::isxdigit(0))); + ASSERT_SAME_TYPE(int, decltype(std::tolower(0))); + ASSERT_SAME_TYPE(int, decltype(std::toupper(0))); + + assert( std::isalnum('a')); + assert( std::isalpha('a')); + assert( std::isblank(' ')); assert(!std::iscntrl(' ')); assert(!std::isdigit('a')); - assert(std::isgraph('a')); - assert(std::islower('a')); - assert(std::isprint('a')); + assert( std::isgraph('a')); + assert( std::islower('a')); + assert( std::isprint('a')); assert(!std::ispunct('a')); assert(!std::isspace('a')); assert(!std::isupper('a')); - assert(std::isxdigit('a')); - assert(std::tolower('A') == 'a'); - assert(std::toupper('a') == 'A'); + assert( std::isxdigit('a')); + assert( std::tolower('A') == 'a'); + assert( std::toupper('a') == 'A'); } diff --git a/test/std/strings/c.strings/cstring.pass.cpp b/test/std/strings/c.strings/cstring.pass.cpp index 63f86d350..22952e0f2 100644 --- a/test/std/strings/c.strings/cstring.pass.cpp +++ b/test/std/strings/c.strings/cstring.pass.cpp @@ -12,6 +12,8 @@ #include #include +#include "test_macros.h" + #ifndef NULL #error NULL not defined #endif @@ -23,39 +25,40 @@ int main() const void* vpc = 0; char* cp = 0; const char* cpc = 0; - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); + + ASSERT_SAME_TYPE(void*, decltype(std::memcpy(vp, vpc, s))); + ASSERT_SAME_TYPE(void*, decltype(std::memmove(vp, vpc, s))); + ASSERT_SAME_TYPE(char*, decltype(std::strcpy(cp, cpc))); + ASSERT_SAME_TYPE(char*, decltype(std::strncpy(cp, cpc, s))); + ASSERT_SAME_TYPE(char*, decltype(std::strcat(cp, cpc))); + ASSERT_SAME_TYPE(char*, decltype(std::strncat(cp, cpc, s))); + ASSERT_SAME_TYPE(int, decltype(std::memcmp(vpc, vpc, s))); + ASSERT_SAME_TYPE(int, decltype(std::strcmp(cpc, cpc))); + ASSERT_SAME_TYPE(int, decltype(std::strncmp(cpc, cpc, s))); + ASSERT_SAME_TYPE(int, decltype(std::strcoll(cpc, cpc))); + ASSERT_SAME_TYPE(std::size_t, decltype(std::strxfrm(cp, cpc, s))); + ASSERT_SAME_TYPE(void*, decltype(std::memchr(vp, 0, s))); + ASSERT_SAME_TYPE(char*, decltype(std::strchr(cp, 0))); + ASSERT_SAME_TYPE(std::size_t, decltype(std::strcspn(cpc, cpc))); + ASSERT_SAME_TYPE(char*, decltype(std::strpbrk(cp, cpc))); + ASSERT_SAME_TYPE(char*, decltype(std::strrchr(cp, 0))); + ASSERT_SAME_TYPE(std::size_t, decltype(std::strspn(cpc, cpc))); + ASSERT_SAME_TYPE(char*, decltype(std::strstr(cp, cpc))); #ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS - static_assert((std::is_same::value), ""); + ASSERT_SAME_TYPE(char*, decltype(std::strtok(cp, cpc))); #endif - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); + ASSERT_SAME_TYPE(void*, decltype(std::memset(vp, 0, s))); + ASSERT_SAME_TYPE(char*, decltype(std::strerror(0))); + ASSERT_SAME_TYPE(std::size_t, decltype(std::strlen(cpc))); // These tests fail on systems whose C library doesn't provide a correct overload // set for strchr, strpbrk, strrchr, strstr, and memchr, unless the compiler is // a suitably recent version of Clang. #if !defined(__APPLE__) || defined(_LIBCPP_PREFERRED_OVERLOAD) - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); + ASSERT_SAME_TYPE(const void*, decltype(std::memchr(vpc, 0, s))); + ASSERT_SAME_TYPE(const char*, decltype(std::strchr(cpc, 0))); + ASSERT_SAME_TYPE(const char*, decltype(std::strpbrk(cpc, cpc))); + ASSERT_SAME_TYPE(const char*, decltype(std::strrchr(cpc, 0))); + ASSERT_SAME_TYPE(const char*, decltype(std::strstr(cpc, cpc))); #endif } diff --git a/test/std/strings/c.strings/cuchar.pass.cpp b/test/std/strings/c.strings/cuchar.pass.cpp index 022c656e8..f14eda511 100644 --- a/test/std/strings/c.strings/cuchar.pass.cpp +++ b/test/std/strings/c.strings/cuchar.pass.cpp @@ -13,6 +13,8 @@ #include +#include "test_macros.h" + int main() { } diff --git a/test/std/strings/c.strings/cwchar.pass.cpp b/test/std/strings/c.strings/cwchar.pass.cpp index 2b7c3c465..b70dcc52b 100644 --- a/test/std/strings/c.strings/cwchar.pass.cpp +++ b/test/std/strings/c.strings/cwchar.pass.cpp @@ -13,6 +13,8 @@ #include #include +#include "test_macros.h" + #ifndef NULL #error NULL not defined #endif @@ -50,80 +52,80 @@ int main() ((void)ns); // Prevent unused warning ((void)ws); // Prevent unused warning - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); + ASSERT_SAME_TYPE(int, decltype(std::fwprintf(fp, L""))); + ASSERT_SAME_TYPE(int, decltype(std::fwscanf(fp, L""))); + ASSERT_SAME_TYPE(int, decltype(std::swprintf(ws, s, L""))); + ASSERT_SAME_TYPE(int, decltype(std::swscanf(L"", L""))); + ASSERT_SAME_TYPE(int, decltype(std::vfwprintf(fp, L"", va))); + ASSERT_SAME_TYPE(int, decltype(std::vfwscanf(fp, L"", va))); + ASSERT_SAME_TYPE(int, decltype(std::vswprintf(ws, s, L"", va))); + ASSERT_SAME_TYPE(int, decltype(std::vswscanf(L"", L"", va))); + ASSERT_SAME_TYPE(std::wint_t, decltype(std::fgetwc(fp))); + ASSERT_SAME_TYPE(wchar_t*, decltype(std::fgetws(ws, 0, fp))); + ASSERT_SAME_TYPE(std::wint_t, decltype(std::fputwc(L' ', fp))); + ASSERT_SAME_TYPE(int, decltype(std::fputws(L"", fp))); + ASSERT_SAME_TYPE(int, decltype(std::fwide(fp, 0))); + ASSERT_SAME_TYPE(std::wint_t, decltype(std::getwc(fp))); + ASSERT_SAME_TYPE(std::wint_t, decltype(std::putwc(L' ', fp))); + ASSERT_SAME_TYPE(std::wint_t, decltype(std::ungetwc(L' ', fp))); + ASSERT_SAME_TYPE(double, decltype(std::wcstod(L"", (wchar_t**)0))); + ASSERT_SAME_TYPE(float, decltype(std::wcstof(L"", (wchar_t**)0))); + ASSERT_SAME_TYPE(long double, decltype(std::wcstold(L"", (wchar_t**)0))); + ASSERT_SAME_TYPE(long, decltype(std::wcstol(L"", (wchar_t**)0, 0))); + ASSERT_SAME_TYPE(long long, decltype(std::wcstoll(L"", (wchar_t**)0, 0))); + ASSERT_SAME_TYPE(unsigned long, decltype(std::wcstoul(L"", (wchar_t**)0, 0))); + ASSERT_SAME_TYPE(unsigned long long, decltype(std::wcstoull(L"", (wchar_t**)0, 0))); + ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcscpy(ws, L""))); + ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcsncpy(ws, L"", s))); + ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcscat(ws, L""))); + ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcsncat(ws, L"", s))); + ASSERT_SAME_TYPE(int, decltype(std::wcscmp(L"", L""))); + ASSERT_SAME_TYPE(int, decltype(std::wcscoll(L"", L""))); + ASSERT_SAME_TYPE(int, decltype(std::wcsncmp(L"", L"", s))); + ASSERT_SAME_TYPE(std::size_t, decltype(std::wcsxfrm(ws, L"", s))); + ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcschr((wchar_t*)0, L' '))); + ASSERT_SAME_TYPE(std::size_t, decltype(std::wcscspn(L"", L""))); + ASSERT_SAME_TYPE(std::size_t, decltype(std::wcslen(L""))); + ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcspbrk((wchar_t*)0, L""))); + ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcsrchr((wchar_t*)0, L' '))); + ASSERT_SAME_TYPE(std::size_t, decltype(std::wcsspn(L"", L""))); + ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcsstr((wchar_t*)0, L""))); + ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcstok(ws, L"", (wchar_t**)0))); + ASSERT_SAME_TYPE(wchar_t*, decltype(std::wmemchr((wchar_t*)0, L' ', s))); + ASSERT_SAME_TYPE(int, decltype(std::wmemcmp(L"", L"", s))); + ASSERT_SAME_TYPE(wchar_t*, decltype(std::wmemcpy(ws, L"", s))); + ASSERT_SAME_TYPE(wchar_t*, decltype(std::wmemmove(ws, L"", s))); + ASSERT_SAME_TYPE(wchar_t*, decltype(std::wmemset(ws, L' ', s))); + ASSERT_SAME_TYPE(std::size_t, decltype(std::wcsftime(ws, s, L"", tm))); + ASSERT_SAME_TYPE(wint_t, decltype(std::btowc(0))); + ASSERT_SAME_TYPE(int, decltype(std::wctob(w))); + ASSERT_SAME_TYPE(int, decltype(std::mbsinit(&mb))); + ASSERT_SAME_TYPE(std::size_t, decltype(std::mbrlen("", s, &mb))); + ASSERT_SAME_TYPE(std::size_t, decltype(std::mbrtowc(ws, "", s, &mb))); + ASSERT_SAME_TYPE(std::size_t, decltype(std::wcrtomb(ns, L' ', &mb))); + ASSERT_SAME_TYPE(std::size_t, decltype(std::mbsrtowcs(ws, (const char**)0, s, &mb))); + ASSERT_SAME_TYPE(std::size_t, decltype(std::wcsrtombs(ns, (const wchar_t**)0, s, &mb))); // These tests fail on systems whose C library doesn't provide a correct overload // set for wcschr, wcspbrk, wcsrchr, wcsstr, and wmemchr, unless the compiler is // a suitably recent version of Clang. #if !defined(__APPLE__) || defined(_LIBCPP_PREFERRED_OVERLOAD) - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); + ASSERT_SAME_TYPE(const wchar_t*, decltype(std::wcschr((const wchar_t*)0, L' '))); + ASSERT_SAME_TYPE(const wchar_t*, decltype(std::wcspbrk((const wchar_t*)0, L""))); + ASSERT_SAME_TYPE(const wchar_t*, decltype(std::wcsrchr((const wchar_t*)0, L' '))); + ASSERT_SAME_TYPE(const wchar_t*, decltype(std::wcsstr((const wchar_t*)0, L""))); + ASSERT_SAME_TYPE(const wchar_t*, decltype(std::wmemchr((const wchar_t*)0, L' ', s))); #endif #ifndef _LIBCPP_HAS_NO_STDIN - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); + ASSERT_SAME_TYPE(std::wint_t, decltype(std::getwchar())); + ASSERT_SAME_TYPE(int, decltype(std::vwscanf(L"", va))); + ASSERT_SAME_TYPE(int, decltype(std::wscanf(L""))); #endif #ifndef _LIBCPP_HAS_NO_STDOUT - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); + ASSERT_SAME_TYPE(std::wint_t, decltype(std::putwchar(L' '))); + ASSERT_SAME_TYPE(int, decltype(std::vwprintf(L"", va))); + ASSERT_SAME_TYPE(int, decltype(std::wprintf(L""))); #endif } diff --git a/test/std/strings/c.strings/cwctype.pass.cpp b/test/std/strings/c.strings/cwctype.pass.cpp index 6d66415ab..14f730b15 100644 --- a/test/std/strings/c.strings/cwctype.pass.cpp +++ b/test/std/strings/c.strings/cwctype.pass.cpp @@ -12,6 +12,9 @@ #include #include +#include "test_macros.h" + + #ifndef WEOF #error WEOF not defined #endif @@ -91,24 +94,24 @@ int main() { std::wint_t w = 0; - std::wctrans_t wctr = 0; - std::wctype_t wct = 0; - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); + ASSERT_SAME_TYPE(int, decltype(std::iswalnum(w))); + ASSERT_SAME_TYPE(int, decltype(std::iswalpha(w))); + ASSERT_SAME_TYPE(int, decltype(std::iswblank(w))); + ASSERT_SAME_TYPE(int, decltype(std::iswcntrl(w))); + ASSERT_SAME_TYPE(int, decltype(std::iswdigit(w))); + ASSERT_SAME_TYPE(int, decltype(std::iswgraph(w))); + ASSERT_SAME_TYPE(int, decltype(std::iswlower(w))); + ASSERT_SAME_TYPE(int, decltype(std::iswprint(w))); + ASSERT_SAME_TYPE(int, decltype(std::iswpunct(w))); + ASSERT_SAME_TYPE(int, decltype(std::iswspace(w))); + ASSERT_SAME_TYPE(int, decltype(std::iswupper(w))); + ASSERT_SAME_TYPE(int, decltype(std::iswxdigit(w))); + + ASSERT_SAME_TYPE(int, decltype(std::iswctype(w, std::wctype_t()))); + + ASSERT_SAME_TYPE(std::wctype_t, decltype(std::wctype(""))); + ASSERT_SAME_TYPE(std::wint_t, decltype(std::towlower(w))); + ASSERT_SAME_TYPE(std::wint_t, decltype(std::towupper(w))); + ASSERT_SAME_TYPE(std::wint_t, decltype(std::towctrans(w, std::wctrans_t()))); + ASSERT_SAME_TYPE(std::wctrans_t, decltype(std::wctrans(""))); } From 9ff404deecb2b3d02b219f3e841aa8837a1f654e Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Tue, 18 Dec 2018 23:19:00 +0000 Subject: [PATCH 56/94] Portability fix: add missing includes and static_casts. Reviewed as https://reviews.llvm.org/D55777. Thanks to Andrey Maksimov for the patch. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349566 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../unord.map/unord.map.cnstr/assign_copy.pass.cpp | 2 ++ .../iostream.format/ext.manip/get_money.pass.cpp | 1 + .../iostream.format/ext.manip/get_time.pass.cpp | 1 + .../iostream.format/ext.manip/put_money.pass.cpp | 1 + .../iostream.format/ext.manip/put_time.pass.cpp | 1 + .../istream.formatted.arithmetic/int.pass.cpp | 1 + .../istream.formatted.arithmetic/short.pass.cpp | 1 + .../iostream.format/std.manip/resetiosflags.pass.cpp | 2 ++ .../iostream.format/std.manip/setbase.pass.cpp | 2 ++ .../iostream.format/std.manip/setfill.pass.cpp | 1 + .../iostream.format/std.manip/setiosflags.pass.cpp | 2 ++ .../iostream.format/std.manip/setprecision.pass.cpp | 2 ++ .../iostream.format/std.manip/setw.pass.cpp | 2 ++ .../locale.codecvt.members/wchar_t_out.pass.cpp | 1 + .../facet.num.get.members/get_long.pass.cpp | 10 ++++++---- .../facet.num.get.members/test_neg_one.pass.cpp | 1 + test/std/strings/c.strings/cwchar.pass.cpp | 1 + test/std/strings/string.conversions/to_string.pass.cpp | 1 + .../std/strings/string.conversions/to_wstring.pass.cpp | 1 + .../allocator.traits.members/max_size.pass.cpp | 1 + .../tuple/tuple.tuple/tuple.assign/move.pass.cpp | 1 + .../PR20855_tuple_ref_binding_diagnostics.pass.cpp | 1 + .../utilities/type.index/type.index.hash/hash.pass.cpp | 1 + 23 files changed, 34 insertions(+), 4 deletions(-) diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp index b793f0934..c6b92744e 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp @@ -15,10 +15,12 @@ // unordered_map& operator=(const unordered_map& u); +#include #include #include #include #include +#include #include #include "test_macros.h" diff --git a/test/std/input.output/iostream.format/ext.manip/get_money.pass.cpp b/test/std/input.output/iostream.format/ext.manip/get_money.pass.cpp index 1ea1d780c..34b65f52d 100644 --- a/test/std/input.output/iostream.format/ext.manip/get_money.pass.cpp +++ b/test/std/input.output/iostream.format/ext.manip/get_money.pass.cpp @@ -14,6 +14,7 @@ // REQUIRES: locale.en_US.UTF-8 #include +#include #include #include "platform_support.h" // locale name macros diff --git a/test/std/input.output/iostream.format/ext.manip/get_time.pass.cpp b/test/std/input.output/iostream.format/ext.manip/get_time.pass.cpp index 553c2b2eb..7c653f348 100644 --- a/test/std/input.output/iostream.format/ext.manip/get_time.pass.cpp +++ b/test/std/input.output/iostream.format/ext.manip/get_time.pass.cpp @@ -14,6 +14,7 @@ // template T9 get_time(struct tm* tmb, const charT* fmt); #include +#include #include #include "platform_support.h" // locale name macros diff --git a/test/std/input.output/iostream.format/ext.manip/put_money.pass.cpp b/test/std/input.output/iostream.format/ext.manip/put_money.pass.cpp index 342e33724..92b6c726e 100644 --- a/test/std/input.output/iostream.format/ext.manip/put_money.pass.cpp +++ b/test/std/input.output/iostream.format/ext.manip/put_money.pass.cpp @@ -14,6 +14,7 @@ // REQUIRES: locale.en_US.UTF-8 #include +#include #include #include "platform_support.h" // locale name macros diff --git a/test/std/input.output/iostream.format/ext.manip/put_time.pass.cpp b/test/std/input.output/iostream.format/ext.manip/put_time.pass.cpp index dae74f040..915efd081 100644 --- a/test/std/input.output/iostream.format/ext.manip/put_time.pass.cpp +++ b/test/std/input.output/iostream.format/ext.manip/put_time.pass.cpp @@ -14,6 +14,7 @@ // template T10 put_time(const struct tm* tmb, const charT* fmt); #include +#include #include #include "platform_support.h" // locale name macros diff --git a/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/int.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/int.pass.cpp index 25687db16..8d1261137 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/int.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/int.pass.cpp @@ -15,6 +15,7 @@ // operator>>(int& val); #include +#include #include template diff --git a/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/short.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/short.pass.cpp index 62e44f542..22a760da6 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/short.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/short.pass.cpp @@ -15,6 +15,7 @@ // operator>>(short& val); #include +#include #include template diff --git a/test/std/input.output/iostream.format/std.manip/resetiosflags.pass.cpp b/test/std/input.output/iostream.format/std.manip/resetiosflags.pass.cpp index 6c01fc057..b0b3c31f7 100644 --- a/test/std/input.output/iostream.format/std.manip/resetiosflags.pass.cpp +++ b/test/std/input.output/iostream.format/std.manip/resetiosflags.pass.cpp @@ -12,6 +12,8 @@ // T1 resetiosflags(ios_base::fmtflags mask); #include +#include +#include #include template diff --git a/test/std/input.output/iostream.format/std.manip/setbase.pass.cpp b/test/std/input.output/iostream.format/std.manip/setbase.pass.cpp index e2776a5d1..0a2fb36ec 100644 --- a/test/std/input.output/iostream.format/std.manip/setbase.pass.cpp +++ b/test/std/input.output/iostream.format/std.manip/setbase.pass.cpp @@ -12,6 +12,8 @@ // T3 setbase(int base); #include +#include +#include #include template diff --git a/test/std/input.output/iostream.format/std.manip/setfill.pass.cpp b/test/std/input.output/iostream.format/std.manip/setfill.pass.cpp index a4d923d70..e8600972d 100644 --- a/test/std/input.output/iostream.format/std.manip/setfill.pass.cpp +++ b/test/std/input.output/iostream.format/std.manip/setfill.pass.cpp @@ -12,6 +12,7 @@ // template T4 setfill(charT c); #include +#include #include template diff --git a/test/std/input.output/iostream.format/std.manip/setiosflags.pass.cpp b/test/std/input.output/iostream.format/std.manip/setiosflags.pass.cpp index 5aaf38444..11532711a 100644 --- a/test/std/input.output/iostream.format/std.manip/setiosflags.pass.cpp +++ b/test/std/input.output/iostream.format/std.manip/setiosflags.pass.cpp @@ -12,6 +12,8 @@ // T2 setiosflags (ios_base::fmtflags mask); #include +#include +#include #include template diff --git a/test/std/input.output/iostream.format/std.manip/setprecision.pass.cpp b/test/std/input.output/iostream.format/std.manip/setprecision.pass.cpp index 0bea4b986..e04677fa3 100644 --- a/test/std/input.output/iostream.format/std.manip/setprecision.pass.cpp +++ b/test/std/input.output/iostream.format/std.manip/setprecision.pass.cpp @@ -12,6 +12,8 @@ // T5 setprecision(int n); #include +#include +#include #include template diff --git a/test/std/input.output/iostream.format/std.manip/setw.pass.cpp b/test/std/input.output/iostream.format/std.manip/setw.pass.cpp index 9bd96984e..3242bcc94 100644 --- a/test/std/input.output/iostream.format/std.manip/setw.pass.cpp +++ b/test/std/input.output/iostream.format/std.manip/setw.pass.cpp @@ -12,6 +12,8 @@ // T6 setw(int n); #include +#include +#include #include template diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_out.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_out.pass.cpp index d7bcb2908..e4cabf6ef 100644 --- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_out.pass.cpp +++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_out.pass.cpp @@ -20,6 +20,7 @@ #include #include #include +#include typedef std::codecvt F; diff --git a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp index d900c3764..570b8306c 100644 --- a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp +++ b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "test_iterators.h" @@ -46,6 +47,7 @@ int main() const my_facet f(1); std::ios ios(0); long v = -1; + const std::ios_base::fmtflags zf = static_cast(0); { const char str[] = "123"; assert((ios.flags() & ios.basefield) == ios.dec); @@ -110,7 +112,7 @@ int main() } { const char str[] = "123"; - ios.setf(0, ios.basefield); + ios.setf(zf, ios.basefield); std::ios_base::iostate err = ios.goodbit; input_iterator iter = f.get(input_iterator(str), @@ -122,7 +124,7 @@ int main() } { const char str[] = "0x123"; - ios.setf(0, ios.basefield); + ios.setf(zf, ios.basefield); std::ios_base::iostate err = ios.goodbit; input_iterator iter = f.get(input_iterator(str), @@ -134,7 +136,7 @@ int main() } { const char str[] = "0123"; - ios.setf(0, ios.basefield); + ios.setf(zf, ios.basefield); std::ios_base::iostate err = ios.goodbit; input_iterator iter = f.get(input_iterator(str), @@ -146,7 +148,7 @@ int main() } { const char str[] = "2-"; - ios.setf(0, ios.basefield); + ios.setf(zf, ios.basefield); std::ios_base::iostate err = ios.goodbit; input_iterator iter = f.get(input_iterator(str), diff --git a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_neg_one.pass.cpp b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_neg_one.pass.cpp index bd9b3f05d..712d2897d 100644 --- a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_neg_one.pass.cpp +++ b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_neg_one.pass.cpp @@ -14,6 +14,7 @@ // iter_type get(iter_type in, iter_type end, ios_base&, // ios_base::iostate& err, unsigned int& v) const; +#include #include #include #include diff --git a/test/std/strings/c.strings/cwchar.pass.cpp b/test/std/strings/c.strings/cwchar.pass.cpp index b70dcc52b..116da936e 100644 --- a/test/std/strings/c.strings/cwchar.pass.cpp +++ b/test/std/strings/c.strings/cwchar.pass.cpp @@ -10,6 +10,7 @@ // #include +#include #include #include diff --git a/test/std/strings/string.conversions/to_string.pass.cpp b/test/std/strings/string.conversions/to_string.pass.cpp index 05e5e4b92..fdc682ce1 100644 --- a/test/std/strings/string.conversions/to_string.pass.cpp +++ b/test/std/strings/string.conversions/to_string.pass.cpp @@ -19,6 +19,7 @@ // string to_string(double val); // string to_string(long double val); +#include #include #include #include diff --git a/test/std/strings/string.conversions/to_wstring.pass.cpp b/test/std/strings/string.conversions/to_wstring.pass.cpp index 281aa1a5e..2208ec5a3 100644 --- a/test/std/strings/string.conversions/to_wstring.pass.cpp +++ b/test/std/strings/string.conversions/to_wstring.pass.cpp @@ -19,6 +19,7 @@ // wstring to_wstring(double val); // wstring to_wstring(long double val); +#include #include #include #include diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp index 12c0d0222..7a2d76c6d 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp @@ -16,6 +16,7 @@ // ... // }; +#include #include #include #include diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp index 210f14be3..9bc0ef501 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp @@ -15,6 +15,7 @@ // UNSUPPORTED: c++98, c++03 +#include #include #include #include diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp index 457df5602..bfa7c0d23 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp @@ -14,6 +14,7 @@ // See llvm.org/PR20855 +#include #include #include #include diff --git a/test/std/utilities/type.index/type.index.hash/hash.pass.cpp b/test/std/utilities/type.index/type.index.hash/hash.pass.cpp index c5ffacfa3..14bf08412 100644 --- a/test/std/utilities/type.index/type.index.hash/hash.pass.cpp +++ b/test/std/utilities/type.index/type.index.hash/hash.pass.cpp @@ -19,6 +19,7 @@ // }; #include +#include #include int main() From ff04a5678cc1b72bfb5eb9269c80889d36e7ad04 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Wed, 19 Dec 2018 16:39:04 +0000 Subject: [PATCH 57/94] Add missing include to test. NFC git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349639 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../alg.nonmodifying/alg.find.end/find_end_pred.pass.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/std/algorithms/alg.nonmodifying/alg.find.end/find_end_pred.pass.cpp b/test/std/algorithms/alg.nonmodifying/alg.find.end/find_end_pred.pass.cpp index 76ac99165..ac3b95fbe 100644 --- a/test/std/algorithms/alg.nonmodifying/alg.find.end/find_end_pred.pass.cpp +++ b/test/std/algorithms/alg.nonmodifying/alg.find.end/find_end_pred.pass.cpp @@ -16,6 +16,7 @@ // find_end(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2, Pred pred); #include +#include #include #include "test_macros.h" From 1e048a3c695f166840af3e57b84e868e7e2f3d88 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Wed, 19 Dec 2018 18:58:22 +0000 Subject: [PATCH 58/94] Work around GCC 9.0 regression git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349663 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../utilities/variant/variant.variant/variant_size.pass.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/libcxx/utilities/variant/variant.variant/variant_size.pass.cpp b/test/libcxx/utilities/variant/variant.variant/variant_size.pass.cpp index a836ef516..c309aaaae 100644 --- a/test/libcxx/utilities/variant/variant.variant/variant_size.pass.cpp +++ b/test/libcxx/utilities/variant/variant.variant/variant_size.pass.cpp @@ -24,7 +24,8 @@ struct make_variant_imp; template struct make_variant_imp> { - using type = std::variant; + template using AlwaysChar = char; + using type = std::variant...>; }; template From d805c8746ac1b5c8f5f9d69a88a57b4d46763a76 Mon Sep 17 00:00:00 2001 From: Volodymyr Sapsai Date: Wed, 19 Dec 2018 20:08:43 +0000 Subject: [PATCH 59/94] [libcxx] Use custom allocator's `construct` in C++03 when available. Makes libc++ behavior consistent between C++03 and C++11. Can use `decltype` in C++03 because `include/__config` defines a macro when `decltype` is not available. Reviewers: mclow.lists, EricWF, erik.pilkington, ldionne Reviewed By: ldionne Subscribers: dexonsmith, cfe-commits, howard.hinnant, ldionne, christof, jkorous, Quuxplusone Differential Revision: https://reviews.llvm.org/D48753 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349676 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/memory | 48 +++++++++------- .../vector.cons/construct_iter_iter.pass.cpp | 54 ++++++++++++++++++ .../construct_iter_iter_alloc.pass.cpp | 57 +++++++++++++++++++ .../allocator.traits.members/destroy.pass.cpp | 2 +- test/support/min_allocator.h | 54 ++++++++++++++++++ 5 files changed, 193 insertions(+), 22 deletions(-) create mode 100644 test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp diff --git a/include/memory b/include/memory index 3e8f5936e..b012f5bce 100644 --- a/include/memory +++ b/include/memory @@ -1460,29 +1460,21 @@ struct __has_select_on_container_copy_construction #else // _LIBCPP_CXX03_LANG -#ifndef _LIBCPP_HAS_NO_VARIADICS +template +struct __has_construct : std::false_type {}; -template -struct __has_construct - : false_type -{ -}; +template +struct __has_construct<_Alloc, _Pointer, _Tp, typename __void_t< + decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Pointer>(), _VSTD::declval<_Tp>())) +>::type> : std::true_type {}; -#else // _LIBCPP_HAS_NO_VARIADICS - -template -struct __has_construct - : false_type -{ -}; - -#endif // _LIBCPP_HAS_NO_VARIADICS +template +struct __has_destroy : false_type {}; template -struct __has_destroy - : false_type -{ -}; +struct __has_destroy<_Alloc, _Pointer, typename __void_t< + decltype(_VSTD::declval<_Alloc>().destroy(_VSTD::declval<_Pointer>())) +>::type> : std::true_type {}; template struct __has_max_size @@ -1571,9 +1563,10 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits } template _LIBCPP_INLINE_VISIBILITY - static void construct(allocator_type&, _Tp* __p, const _A0& __a0) + static void construct(allocator_type& __a, _Tp* __p, const _A0& __a0) { - ::new ((void*)__p) _Tp(__a0); + __construct(__has_construct(), + __a, __p, __a0); } template _LIBCPP_INLINE_VISIBILITY @@ -1721,6 +1714,19 @@ private: { ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...); } +#else // _LIBCPP_HAS_NO_VARIADICS + template + _LIBCPP_INLINE_VISIBILITY + static void __construct(true_type, allocator_type& __a, _Tp* __p, + const _A0& __a0) + {__a.construct(__p, __a0);} + template + _LIBCPP_INLINE_VISIBILITY + static void __construct(false_type, allocator_type&, _Tp* __p, + const _A0& __a0) + { + ::new ((void*)__p) _Tp(__a0); + } #endif // _LIBCPP_HAS_NO_VARIADICS template diff --git a/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp b/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp new file mode 100644 index 000000000..998d0b74e --- /dev/null +++ b/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template vector(InputIter first, InputIter last); + +#include +#include + +#include "min_allocator.h" + +void test_ctor_under_alloc() { + int arr1[] = {42}; + int arr2[] = {1, 101, 42}; + { + typedef std::vector > C; + typedef C::allocator_type Alloc; + { + Alloc::construct_called = false; + C v(arr1, arr1 + 1); + assert(Alloc::construct_called); + } + { + Alloc::construct_called = false; + C v(arr2, arr2 + 3); + assert(Alloc::construct_called); + } + } + { + typedef std::vector > C; + typedef C::allocator_type Alloc; + { + Alloc::construct_called = false; + C v(arr1, arr1 + 1); + assert(Alloc::construct_called); + } + { + Alloc::construct_called = false; + C v(arr2, arr2 + 3); + assert(Alloc::construct_called); + } + } +} + +int main() { + test_ctor_under_alloc(); +} diff --git a/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp b/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp new file mode 100644 index 000000000..c4950fbe6 --- /dev/null +++ b/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template vector(InputIter first, InputIter last, +// const allocator_type& a); + +#include +#include + +#include "min_allocator.h" + +void test_ctor_under_alloc() { + int arr1[] = {42}; + int arr2[] = {1, 101, 42}; + { + typedef std::vector > C; + typedef C::allocator_type Alloc; + Alloc a; + { + Alloc::construct_called = false; + C v(arr1, arr1 + 1, a); + assert(Alloc::construct_called); + } + { + Alloc::construct_called = false; + C v(arr2, arr2 + 3, a); + assert(Alloc::construct_called); + } + } + { + typedef std::vector > C; + typedef C::allocator_type Alloc; + Alloc a; + { + Alloc::construct_called = false; + C v(arr1, arr1 + 1, a); + assert(Alloc::construct_called); + } + { + Alloc::construct_called = false; + C v(arr2, arr2 + 3, a); + assert(Alloc::construct_called); + } + } +} + +int main() { + test_ctor_under_alloc(); +} diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp index 1a812876b..1060b7343 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp @@ -73,7 +73,7 @@ int main() std::aligned_storage::type store; std::allocator_traits::destroy(a, (VT*)&store); } -#if TEST_STD_VER >= 11 +#if defined(_LIBCPP_VERSION) || TEST_STD_VER >= 11 { A0::count = 0; b_destroy = 0; diff --git a/test/support/min_allocator.h b/test/support/min_allocator.h index a3af9e1db..454749397 100644 --- a/test/support/min_allocator.h +++ b/test/support/min_allocator.h @@ -14,6 +14,7 @@ #include #include #include +#include #include "test_macros.h" @@ -131,6 +132,59 @@ public: friend bool operator!=(malloc_allocator x, malloc_allocator y) {return !(x == y);} }; +template +struct cpp03_allocator : bare_allocator +{ + typedef T value_type; + typedef value_type* pointer; + + static bool construct_called; + + // Returned value is not used but it's not prohibited. + pointer construct(pointer p, const value_type& val) + { + ::new(p) value_type(val); + construct_called = true; + return p; + } + + std::size_t max_size() const + { + return UINT_MAX / sizeof(T); + } +}; +template bool cpp03_allocator::construct_called = false; + +template +struct cpp03_overload_allocator : bare_allocator +{ + typedef T value_type; + typedef value_type* pointer; + + static bool construct_called; + + void construct(pointer p, const value_type& val) + { + construct(p, val, std::is_class()); + } + void construct(pointer p, const value_type& val, std::true_type) + { + ::new(p) value_type(val); + construct_called = true; + } + void construct(pointer p, const value_type& val, std::false_type) + { + ::new(p) value_type(val); + construct_called = true; + } + + std::size_t max_size() const + { + return UINT_MAX / sizeof(T); + } +}; +template bool cpp03_overload_allocator::construct_called = false; + #if TEST_STD_VER >= 11 From 8daffdabc50c469f08cfe06fbd075044f6466e37 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Thu, 20 Dec 2018 17:55:31 +0000 Subject: [PATCH 60/94] [libcxx] Fix order checking in unordered_multimap tests. Some tests assume that iteration through an unordered multimap elements will return them in the same order as at the container creation. This assumption is not true since the container is unordered, so that no specific order of elements is ever guaranteed for such container. This patch introduces checks verifying that any iteration will return elements exactly from a set of valid values and without repetition, but in no particular order. Reviewed as https://reviews.llvm.org/D54838. Thanks to Andrey Maksimov for the patch. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349780 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../unord.multimap/equal_range_const.pass.cpp | 39 ++- .../equal_range_non_const.pass.cpp | 39 ++- .../unord.multimap/local_iterators.pass.cpp | 273 +++++++++++++----- .../unord/unord.multimap/rehash.pass.cpp | 36 ++- .../unord/unord.multimap/reserve.pass.cpp | 23 +- .../unord/unord.multimap/swap_member.pass.cpp | 121 ++++++-- 6 files changed, 379 insertions(+), 152 deletions(-) diff --git a/test/std/containers/unord/unord.multimap/equal_range_const.pass.cpp b/test/std/containers/unord/unord.multimap/equal_range_const.pass.cpp index 382ed7c98..65c9f8c12 100644 --- a/test/std/containers/unord/unord.multimap/equal_range_const.pass.cpp +++ b/test/std/containers/unord/unord.multimap/equal_range_const.pass.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include "min_allocator.h" @@ -48,14 +49,17 @@ int main() r = c.equal_range(5); assert(std::distance(r.first, r.second) == 0); r = c.equal_range(50); - assert(r.first->first == 50); - assert(r.first->second == "fifty"); - ++r.first; - assert(r.first->first == 50); - assert(r.first->second == "fiftyA"); - ++r.first; - assert(r.first->first == 50); - assert(r.first->second == "fiftyB"); + std::set s; + s.insert("fifty"); + s.insert("fiftyA"); + s.insert("fiftyB"); + for ( int i = 0; i < 3; ++i ) + { + assert(r.first->first == 50); + assert(s.find(r.first->second) != s.end()); + s.erase(s.find(r.first->second)); + ++r.first; + } } #if TEST_STD_VER >= 11 { @@ -84,14 +88,17 @@ int main() r = c.equal_range(5); assert(std::distance(r.first, r.second) == 0); r = c.equal_range(50); - assert(r.first->first == 50); - assert(r.first->second == "fifty"); - ++r.first; - assert(r.first->first == 50); - assert(r.first->second == "fiftyA"); - ++r.first; - assert(r.first->first == 50); - assert(r.first->second == "fiftyB"); + std::set s; + s.insert("fifty"); + s.insert("fiftyA"); + s.insert("fiftyB"); + for ( int i = 0; i < 3; ++i ) + { + assert(r.first->first == 50); + assert(s.find(r.first->second) != s.end()); + s.erase(s.find(r.first->second)); + ++r.first; + } } #endif } diff --git a/test/std/containers/unord/unord.multimap/equal_range_non_const.pass.cpp b/test/std/containers/unord/unord.multimap/equal_range_non_const.pass.cpp index 17eb14e44..10fafee80 100644 --- a/test/std/containers/unord/unord.multimap/equal_range_non_const.pass.cpp +++ b/test/std/containers/unord/unord.multimap/equal_range_non_const.pass.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include "min_allocator.h" @@ -48,14 +49,17 @@ int main() r = c.equal_range(5); assert(std::distance(r.first, r.second) == 0); r = c.equal_range(50); - assert(r.first->first == 50); - assert(r.first->second == "fifty"); - ++r.first; - assert(r.first->first == 50); - assert(r.first->second == "fiftyA"); - ++r.first; - assert(r.first->first == 50); - assert(r.first->second == "fiftyB"); + std::set s; + s.insert("fifty"); + s.insert("fiftyA"); + s.insert("fiftyB"); + for ( int i = 0; i < 3; ++i ) + { + assert(r.first->first == 50); + assert(s.find(r.first->second) != s.end()); + s.erase(s.find(r.first->second)); + ++r.first; + } } #if TEST_STD_VER >= 11 { @@ -84,14 +88,17 @@ int main() r = c.equal_range(5); assert(std::distance(r.first, r.second) == 0); r = c.equal_range(50); - assert(r.first->first == 50); - assert(r.first->second == "fifty"); - ++r.first; - assert(r.first->first == 50); - assert(r.first->second == "fiftyA"); - ++r.first; - assert(r.first->first == 50); - assert(r.first->second == "fiftyB"); + std::set s; + s.insert("fifty"); + s.insert("fiftyA"); + s.insert("fiftyB"); + for ( int i = 0; i < 3; ++i ) + { + assert(r.first->first == 50); + assert(s.find(r.first->second) != s.end()); + s.erase(s.find(r.first->second)); + ++r.first; + } } #endif } diff --git a/test/std/containers/unord/unord.multimap/local_iterators.pass.cpp b/test/std/containers/unord/unord.multimap/local_iterators.pass.cpp index 504fe54de..2976d2c3c 100644 --- a/test/std/containers/unord/unord.multimap/local_iterators.pass.cpp +++ b/test/std/containers/unord/unord.multimap/local_iterators.pass.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include "min_allocator.h" @@ -52,21 +53,35 @@ int main() i = c.begin(b); j = c.end(b); assert(std::distance(i, j) == 2); - assert(i->first == 1); - assert(i->second == "one"); - ++i; - assert(i->first == 1); - assert(i->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 1); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(2); i = c.begin(b); j = c.end(b); assert(std::distance(i, j) == 2); - assert(i->first == 2); - assert(i->second == "two"); - ++i; - assert(i->first == 2); - assert(i->second == "four"); + { + std::set s; + s.insert("two"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 2); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(3); i = c.begin(b); @@ -116,21 +131,35 @@ int main() i = c.begin(b); j = c.end(b); assert(std::distance(i, j) == 2); - assert(i->first == 1); - assert(i->second == "one"); - ++i; - assert(i->first == 1); - assert(i->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 1); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(2); i = c.begin(b); j = c.end(b); assert(std::distance(i, j) == 2); - assert(i->first == 2); - assert(i->second == "two"); - ++i; - assert(i->first == 2); - assert(i->second == "four"); + { + std::set s; + s.insert("two"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 2); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(3); i = c.begin(b); @@ -180,21 +209,35 @@ int main() i = c.cbegin(b); j = c.cend(b); assert(std::distance(i, j) == 2); - assert(i->first == 1); - assert(i->second == "one"); - ++i; - assert(i->first == 1); - assert(i->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 1); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(2); i = c.cbegin(b); j = c.cend(b); assert(std::distance(i, j) == 2); - assert(i->first == 2); - assert(i->second == "two"); - ++i; - assert(i->first == 2); - assert(i->second == "four"); + { + std::set s; + s.insert("two"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 2); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(3); i = c.cbegin(b); @@ -244,21 +287,35 @@ int main() i = c.cbegin(b); j = c.cend(b); assert(std::distance(i, j) == 2); - assert(i->first == 1); - assert(i->second == "one"); - ++i; - assert(i->first == 1); - assert(i->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 1); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(2); i = c.cbegin(b); j = c.cend(b); assert(std::distance(i, j) == 2); - assert(i->first == 2); - assert(i->second == "two"); - ++i; - assert(i->first == 2); - assert(i->second == "four"); + { + std::set s; + s.insert("two"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 2); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(3); i = c.cbegin(b); @@ -310,21 +367,35 @@ int main() i = c.begin(b); j = c.end(b); assert(std::distance(i, j) == 2); - assert(i->first == 1); - assert(i->second == "one"); - ++i; - assert(i->first == 1); - assert(i->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 1); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(2); i = c.begin(b); j = c.end(b); assert(std::distance(i, j) == 2); - assert(i->first == 2); - assert(i->second == "two"); - ++i; - assert(i->first == 2); - assert(i->second == "four"); + { + std::set s; + s.insert("two"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 2); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(3); i = c.begin(b); @@ -375,21 +446,35 @@ int main() i = c.begin(b); j = c.end(b); assert(std::distance(i, j) == 2); - assert(i->first == 1); - assert(i->second == "one"); - ++i; - assert(i->first == 1); - assert(i->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 1); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(2); i = c.begin(b); j = c.end(b); assert(std::distance(i, j) == 2); - assert(i->first == 2); - assert(i->second == "two"); - ++i; - assert(i->first == 2); - assert(i->second == "four"); + { + std::set s; + s.insert("two"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 2); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(3); i = c.begin(b); @@ -440,21 +525,35 @@ int main() i = c.cbegin(b); j = c.cend(b); assert(std::distance(i, j) == 2); - assert(i->first == 1); - assert(i->second == "one"); - ++i; - assert(i->first == 1); - assert(i->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 1); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(2); i = c.cbegin(b); j = c.cend(b); assert(std::distance(i, j) == 2); - assert(i->first == 2); - assert(i->second == "two"); - ++i; - assert(i->first == 2); - assert(i->second == "four"); + { + std::set s; + s.insert("two"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 2); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(3); i = c.cbegin(b); @@ -505,21 +604,35 @@ int main() i = c.cbegin(b); j = c.cend(b); assert(std::distance(i, j) == 2); - assert(i->first == 1); - assert(i->second == "one"); - ++i; - assert(i->first == 1); - assert(i->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 1); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(2); i = c.cbegin(b); j = c.cend(b); assert(std::distance(i, j) == 2); - assert(i->first == 2); - assert(i->second == "two"); - ++i; - assert(i->first == 2); - assert(i->second == "four"); + { + std::set s; + s.insert("two"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 2); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } b = c.bucket(3); i = c.cbegin(b); diff --git a/test/std/containers/unord/unord.multimap/rehash.pass.cpp b/test/std/containers/unord/unord.multimap/rehash.pass.cpp index 22202ccb6..e8394d7f7 100644 --- a/test/std/containers/unord/unord.multimap/rehash.pass.cpp +++ b/test/std/containers/unord/unord.multimap/rehash.pass.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -39,20 +40,33 @@ void test(const C& c) Eq eq = c.equal_range(1); assert(std::distance(eq.first, eq.second) == 2); typename C::const_iterator i = eq.first; - assert(i->first == 1); - assert(i->second == "one"); - ++i; - assert(i->first == 1); - assert(i->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 1); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } eq = c.equal_range(2); assert(std::distance(eq.first, eq.second) == 2); i = eq.first; - assert(i->first == 2); - assert(i->second == "two"); - ++i; - assert(i->first == 2); - assert(i->second == "four"); - + { + std::set s; + s.insert("two"); + s.insert("four"); + for ( int n = 0; n < 2; ++n ) + { + assert(i->first == 2); + assert(s.find(i->second) != s.end()); + s.erase(s.find(i->second)); + ++i; + } + } eq = c.equal_range(3); assert(std::distance(eq.first, eq.second) == 1); i = eq.first; diff --git a/test/std/containers/unord/unord.multimap/reserve.pass.cpp b/test/std/containers/unord/unord.multimap/reserve.pass.cpp index d86c69c88..003337774 100644 --- a/test/std/containers/unord/unord.multimap/reserve.pass.cpp +++ b/test/std/containers/unord/unord.multimap/reserve.pass.cpp @@ -13,10 +13,11 @@ // class Alloc = allocator>> // class unordered_multimap -// void rehash(size_type n); +// void reserve(size_type n); #include #include +#include #include #include "test_macros.h" @@ -26,10 +27,22 @@ template void test(const C& c) { assert(c.size() == 6); - assert(c.find(1)->second == "one"); - assert(next(c.find(1))->second == "four"); - assert(c.find(2)->second == "two"); - assert(next(c.find(2))->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + assert(s.find(c.find(1)->second) != s.end()); + s.erase(s.find(c.find(1)->second)); + assert(s.find(next(c.find(1))->second) != s.end()); + } + { + std::set s; + s.insert("two"); + s.insert("four"); + assert(s.find(c.find(2)->second) != s.end()); + s.erase(s.find(c.find(2)->second)); + assert(s.find(next(c.find(2))->second) != s.end()); + } assert(c.find(3)->second == "three"); assert(c.find(4)->second == "four"); } diff --git a/test/std/containers/unord/unord.multimap/swap_member.pass.cpp b/test/std/containers/unord/unord.multimap/swap_member.pass.cpp index 8c5ddab05..3f0259794 100644 --- a/test/std/containers/unord/unord.multimap/swap_member.pass.cpp +++ b/test/std/containers/unord/unord.multimap/swap_member.pass.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -136,10 +137,22 @@ int main() assert(c2.bucket_count() >= 6); assert(c2.size() == 6); - assert(c2.find(1)->second == "one"); - assert(next(c2.find(1))->second == "four"); - assert(c2.find(2)->second == "two"); - assert(next(c2.find(2))->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + assert(s.find(c2.find(1)->second) != s.end()); + s.erase(s.find(c2.find(1)->second)); + assert(s.find(next(c2.find(1))->second) != s.end()); + } + { + std::set s; + s.insert("two"); + s.insert("four"); + assert(s.find(c2.find(2)->second) != s.end()); + s.erase(s.find(c2.find(2)->second)); + assert(s.find(next(c2.find(2))->second) != s.end()); + } assert(c2.find(3)->second == "three"); assert(c2.find(4)->second == "four"); assert(c2.hash_function() == Hash(1)); @@ -199,10 +212,22 @@ int main() assert(c2.bucket_count() >= 6); assert(c2.size() == 6); - assert(c2.find(1)->second == "one"); - assert(next(c2.find(1))->second == "four"); - assert(c2.find(2)->second == "two"); - assert(next(c2.find(2))->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + assert(s.find(c2.find(1)->second) != s.end()); + s.erase(s.find(c2.find(1)->second)); + assert(s.find(next(c2.find(1))->second) != s.end()); + } + { + std::set s; + s.insert("two"); + s.insert("four"); + assert(s.find(c2.find(2)->second) != s.end()); + s.erase(s.find(c2.find(2)->second)); + assert(s.find(next(c2.find(2))->second) != s.end()); + } assert(c2.find(3)->second == "three"); assert(c2.find(4)->second == "four"); assert(c2.hash_function() == Hash(1)); @@ -320,10 +345,22 @@ int main() assert(c2.bucket_count() >= 6); assert(c2.size() == 6); - assert(c2.find(1)->second == "one"); - assert(next(c2.find(1))->second == "four"); - assert(c2.find(2)->second == "two"); - assert(next(c2.find(2))->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + assert(s.find(c2.find(1)->second) != s.end()); + s.erase(s.find(c2.find(1)->second)); + assert(s.find(next(c2.find(1))->second) != s.end()); + } + { + std::set s; + s.insert("two"); + s.insert("four"); + assert(s.find(c2.find(2)->second) != s.end()); + s.erase(s.find(c2.find(2)->second)); + assert(s.find(next(c2.find(2))->second) != s.end()); + } assert(c2.find(3)->second == "three"); assert(c2.find(4)->second == "four"); assert(c2.hash_function() == Hash(1)); @@ -383,10 +420,22 @@ int main() assert(c2.bucket_count() >= 6); assert(c2.size() == 6); - assert(c2.find(1)->second == "one"); - assert(next(c2.find(1))->second == "four"); - assert(c2.find(2)->second == "two"); - assert(next(c2.find(2))->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + assert(s.find(c2.find(1)->second) != s.end()); + s.erase(s.find(c2.find(1)->second)); + assert(s.find(next(c2.find(1))->second) != s.end()); + } + { + std::set s; + s.insert("two"); + s.insert("four"); + assert(s.find(c2.find(2)->second) != s.end()); + s.erase(s.find(c2.find(2)->second)); + assert(s.find(next(c2.find(2))->second) != s.end()); + } assert(c2.find(3)->second == "three"); assert(c2.find(4)->second == "four"); assert(c2.hash_function() == Hash(1)); @@ -504,10 +553,22 @@ int main() assert(c2.bucket_count() >= 6); assert(c2.size() == 6); - assert(c2.find(1)->second == "one"); - assert(next(c2.find(1))->second == "four"); - assert(c2.find(2)->second == "two"); - assert(next(c2.find(2))->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + assert(s.find(c2.find(1)->second) != s.end()); + s.erase(s.find(c2.find(1)->second)); + assert(s.find(next(c2.find(1))->second) != s.end()); + } + { + std::set s; + s.insert("two"); + s.insert("four"); + assert(s.find(c2.find(2)->second) != s.end()); + s.erase(s.find(c2.find(2)->second)); + assert(s.find(next(c2.find(2))->second) != s.end()); + } assert(c2.find(3)->second == "three"); assert(c2.find(4)->second == "four"); assert(c2.hash_function() == Hash(1)); @@ -567,10 +628,22 @@ int main() assert(c2.bucket_count() >= 6); assert(c2.size() == 6); - assert(c2.find(1)->second == "one"); - assert(next(c2.find(1))->second == "four"); - assert(c2.find(2)->second == "two"); - assert(next(c2.find(2))->second == "four"); + { + std::set s; + s.insert("one"); + s.insert("four"); + assert(s.find(c2.find(1)->second) != s.end()); + s.erase(s.find(c2.find(1)->second)); + assert(s.find(next(c2.find(1))->second) != s.end()); + } + { + std::set s; + s.insert("two"); + s.insert("four"); + assert(s.find(c2.find(2)->second) != s.end()); + s.erase(s.find(c2.find(2)->second)); + assert(s.find(next(c2.find(2))->second) != s.end()); + } assert(c2.find(3)->second == "three"); assert(c2.find(4)->second == "four"); assert(c2.hash_function() == Hash(1)); From 545d0b950d2cdcfcdbb5e02f68cae72c079b619d Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Fri, 21 Dec 2018 02:17:00 +0000 Subject: [PATCH 61/94] Mark two filesystem LWG issues as complete - nothing to do git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349877 91177308-0d34-0410-b5e6-96231b3b80d8 --- www/cxx2a_status.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/cxx2a_status.html b/www/cxx2a_status.html index 581191c76..f8a5a831f 100644 --- a/www/cxx2a_status.html +++ b/www/cxx2a_status.html @@ -255,11 +255,11 @@ 2184Muddled allocator requirements for match_results assignmentsSan DiegoComplete 2412promise::set_value() and promise::get_future() should not raceSan Diego 2499operator>>(basic_istream&, CharT*) makes it hard to avoid buffer overflowsSan DiegoResolved by P0487R1 - 2682filesystem::copy() won't create a symlink to a directorySan Diego + 2682filesystem::copy() won't create a symlink to a directorySan DiegoNothing to do 2697[concurr.ts] Behavior of future/shared_future unwrapping constructor when given an invalid futureSan Diego 2797Trait precondition violationsSan DiegoResolved by 1285R0 2936Path comparison is defined in terms of the generic formatSan Diego - 2943Problematic specification of the wide version of basic_filebuf::openSan Diego + 2943Problematic specification of the wide version of basic_filebuf::openSan DiegoNothing to do 2960[fund.ts.v3] nonesuch is insufficiently uselessSan Diego 2995basic_stringbuf default constructor forbids it from using SSO capacitySan Diego 2996Missing rvalue overloads for shared_ptr operationsSan Diego From a2037284d41905968965638957ea29f9a7e3220e Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Fri, 21 Dec 2018 03:16:30 +0000 Subject: [PATCH 62/94] Implement LWG 2936: Path comparison is defined in terms of the generic format This patch implements path::compare according to the current spec. The only observable change is the ordering of "/foo" and "foo", which orders the two paths based on having or not having a root directory (instead of lexically comparing "/" to "foo"). git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349881 91177308-0d34-0410-b5e6-96231b3b80d8 --- src/filesystem/operations.cpp | 99 ++++++++++++++++--- .../path.member/path.compare.pass.cpp | 55 ++++++++++- www/cxx2a_status.html | 2 +- 3 files changed, 140 insertions(+), 16 deletions(-) diff --git a/src/filesystem/operations.cpp b/src/filesystem/operations.cpp index c9396b59c..0b79ef1cd 100644 --- a/src/filesystem/operations.cpp +++ b/src/filesystem/operations.cpp @@ -206,8 +206,20 @@ public: return *this; } + bool atEnd() const noexcept { + return State == PS_AtEnd; + } + + bool inRootDir() const noexcept { + return State == PS_InRootDir; + } + + bool inRootName() const noexcept { + return State == PS_InRootName; + } + bool inRootPath() const noexcept { - return State == PS_InRootDir || State == PS_InRootName; + return inRootName() || inRootDir(); } private: @@ -1294,7 +1306,19 @@ string_view_t path::__root_path_raw() const { return {}; } +static bool ConsumeRootName(PathParser *PP) { + static_assert(PathParser::PS_BeforeBegin == 1 && + PathParser::PS_InRootName == 2, + "Values for enums are incorrect"); + while (PP->State <= PathParser::PS_InRootName) + ++(*PP); + return PP->State == PathParser::PS_AtEnd; +} + static bool ConsumeRootDir(PathParser* PP) { + static_assert(PathParser::PS_BeforeBegin == 1 && + PathParser::PS_InRootName == 2 && + PathParser::PS_InRootDir == 3, "Values for enums are incorrect"); while (PP->State <= PathParser::PS_InRootDir) ++(*PP); return PP->State == PathParser::PS_AtEnd; @@ -1514,21 +1538,68 @@ path path::lexically_relative(const path& base) const { //////////////////////////////////////////////////////////////////////////// // path.comparisons -int path::__compare(string_view_t __s) const { - auto PP = PathParser::CreateBegin(__pn_); - auto PP2 = PathParser::CreateBegin(__s); - while (PP && PP2) { - int res = (*PP).compare(*PP2); - if (res != 0) - return res; - ++PP; - ++PP2; - } - if (PP.State == PP2.State && !PP) +static int CompareRootName(PathParser *LHS, PathParser *RHS) { + if (!LHS->inRootName() && !RHS->inRootName()) return 0; - if (!PP) + + auto GetRootName = [](PathParser *Parser) -> string_view_t { + return Parser->inRootName() ? **Parser : ""; + }; + int res = GetRootName(LHS).compare(GetRootName(RHS)); + ConsumeRootName(LHS); + ConsumeRootName(RHS); + return res; +} + +static int CompareRootDir(PathParser *LHS, PathParser *RHS) { + if (!LHS->inRootDir() && RHS->inRootDir()) return -1; - return 1; + else if (LHS->inRootDir() && !RHS->inRootDir()) + return 1; + else { + ConsumeRootDir(LHS); + ConsumeRootDir(RHS); + return 0; + } +} + +static int CompareRelative(PathParser *LHSPtr, PathParser *RHSPtr) { + auto &LHS = *LHSPtr; + auto &RHS = *RHSPtr; + + int res; + while (LHS && RHS) { + if ((res = (*LHS).compare(*RHS)) != 0) + return res; + ++LHS; + ++RHS; + } + return 0; +} + +static int CompareEndState(PathParser *LHS, PathParser *RHS) { + if (LHS->atEnd() && !RHS->atEnd()) + return -1; + else if (!LHS->atEnd() && RHS->atEnd()) + return 1; + return 0; +} + +int path::__compare(string_view_t __s) const { + auto LHS = PathParser::CreateBegin(__pn_); + auto RHS = PathParser::CreateBegin(__s); + int res; + + if ((res = CompareRootName(&LHS, &RHS)) != 0) + return res; + + if ((res = CompareRootDir(&LHS, &RHS)) != 0) + return res; + + if ((res = CompareRelative(&LHS, &RHS)) != 0) + return res; + + return CompareEndState(&LHS, &RHS); } //////////////////////////////////////////////////////////////////////////// diff --git a/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp b/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp index 7791097dc..2be6122a0 100644 --- a/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp +++ b/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp @@ -65,6 +65,8 @@ const PathCompareTest CompareTestCases[] = {"//foo//bar///baz////", "//foo/bar/baz/", 0}, // duplicate separators {"///foo/bar", "/foo/bar", 0}, // "///" is not a root directory {"/foo/bar/", "/foo/bar", 1}, // trailing separator + {"foo", "/foo", -1}, // if !this->has_root_directory() and p.has_root_directory(), a value less than 0. + {"/foo", "foo", 1}, // if this->has_root_directory() and !p.has_root_directory(), a value greater than 0. {"//" LONGA "////" LONGB "/" LONGC "///" LONGD, "//" LONGA "/" LONGB "/" LONGC "/" LONGD, 0}, { LONGA "/" LONGB "/" LONGC, LONGA "/" LONGB "/" LONGB, 1} @@ -79,7 +81,7 @@ static inline int normalize_ret(int ret) return ret < 0 ? -1 : (ret > 0 ? 1 : 0); } -int main() +void test_compare_basic() { using namespace fs; for (auto const & TC : CompareTestCases) { @@ -136,3 +138,54 @@ int main() } } } + +int CompareElements(std::vector const& LHS, std::vector const& RHS) { + bool IsLess = std::lexicographical_compare(LHS.begin(), LHS.end(), RHS.begin(), RHS.end()); + if (IsLess) + return -1; + + bool IsGreater = std::lexicographical_compare(RHS.begin(), RHS.end(), LHS.begin(), LHS.end()); + if (IsGreater) + return 1; + + return 0; +} + +void test_compare_elements() { + struct { + std::vector LHSElements; + std::vector RHSElements; + int Expect; + } TestCases[] = { + {{"a"}, {"a"}, 0}, + {{"a"}, {"b"}, -1}, + {{"b"}, {"a"}, 1}, + {{"a", "b", "c"}, {"a", "b", "c"}, 0}, + {{"a", "b", "c"}, {"a", "b", "d"}, -1}, + {{"a", "b", "d"}, {"a", "b", "c"}, 1}, + {{"a", "b"}, {"a", "b", "c"}, -1}, + {{"a", "b", "c"}, {"a", "b"}, 1}, + + }; + + auto BuildPath = [](std::vector const& Elems) { + fs::path p; + for (auto &E : Elems) + p /= E; + return p; + }; + + for (auto &TC : TestCases) { + fs::path LHS = BuildPath(TC.LHSElements); + fs::path RHS = BuildPath(TC.RHSElements); + const int ExpectCmp = CompareElements(TC.LHSElements, TC.RHSElements); + assert(ExpectCmp == TC.Expect); + const int GotCmp = normalize_ret(LHS.compare(RHS)); + assert(GotCmp == TC.Expect); + } +} + +int main() { + test_compare_basic(); + test_compare_elements(); +} diff --git a/www/cxx2a_status.html b/www/cxx2a_status.html index f8a5a831f..25e6cdfe4 100644 --- a/www/cxx2a_status.html +++ b/www/cxx2a_status.html @@ -258,7 +258,7 @@ 2682filesystem::copy() won't create a symlink to a directorySan DiegoNothing to do 2697[concurr.ts] Behavior of future/shared_future unwrapping constructor when given an invalid futureSan Diego 2797Trait precondition violationsSan DiegoResolved by 1285R0 - 2936Path comparison is defined in terms of the generic formatSan Diego + 2936Path comparison is defined in terms of the generic formatSan DiegoComplete 2943Problematic specification of the wide version of basic_filebuf::openSan DiegoNothing to do 2960[fund.ts.v3] nonesuch is insufficiently uselessSan Diego 2995basic_stringbuf default constructor forbids it from using SSO capacitySan Diego From 874280d14da2949282566327f951d856a2b549d9 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Fri, 21 Dec 2018 03:54:57 +0000 Subject: [PATCH 63/94] Implement LWG 3145: file_clock breaks ABI for C++17 implementations. This patch adds std::chrono::file_clock, but without breaking the existing ABI for std::filesystem. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349883 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/chrono | 43 ++++++++++++++++++- include/filesystem | 30 ------------- .../time.clock.file/consistency.pass.cpp | 35 +++++++++++++++ .../time.clock.file/file_time.pass.cpp | 29 +++++++++++++ .../time.clock/time.clock.file/now.pass.cpp | 35 +++++++++++++++ .../time.clock.file/rep_signed.pass.cpp | 29 +++++++++++++ www/cxx2a_status.html | 2 +- 7 files changed, 171 insertions(+), 32 deletions(-) create mode 100644 test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp create mode 100644 test/std/utilities/time/time.clock/time.clock.file/file_time.pass.cpp create mode 100644 test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp create mode 100644 test/std/utilities/time/time.clock/time.clock.file/rep_signed.pass.cpp diff --git a/include/chrono b/include/chrono index e99e3c74c..a5bb9afa8 100644 --- a/include/chrono +++ b/include/chrono @@ -808,6 +808,9 @@ constexpr chrono::year operator ""y(unsigned lo _LIBCPP_PUSH_MACROS #include <__undef_macros> +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM +struct _FilesystemClock; +_LIBCPP_END_NAMESPACE_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_STD @@ -1581,10 +1584,14 @@ typedef system_clock high_resolution_clock; #endif #if _LIBCPP_STD_VER > 17 +// [time.clock.file], type file_clock +using file_clock = _VSTD_FS::_FilesystemClock; + +template +using file_time = time_point; struct _LIBCPP_TYPE_VIS last_spec { explicit last_spec() = default; }; - class _LIBCPP_TYPE_VIS day { private: unsigned char __d; @@ -2689,6 +2696,40 @@ namespace chrono { // hoist the literals into namespace std::chrono _LIBCPP_END_NAMESPACE_STD +#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM +struct _FilesystemClock { +#if !defined(_LIBCPP_HAS_NO_INT128) + typedef __int128_t rep; + typedef nano period; +#else + typedef long long rep; + typedef nano period; +#endif + + typedef chrono::duration duration; + typedef chrono::time_point<_FilesystemClock> time_point; + + static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; + + _LIBCPP_FUNC_VIS static time_point now() noexcept; + + _LIBCPP_INLINE_VISIBILITY + static time_t to_time_t(const time_point& __t) noexcept { + typedef chrono::duration __secs; + return time_t( + chrono::duration_cast<__secs>(__t.time_since_epoch()).count()); + } + + _LIBCPP_INLINE_VISIBILITY + static time_point from_time_t(time_t __t) noexcept { + typedef chrono::duration __secs; + return time_point(__secs(__t)); + } +}; +_LIBCPP_END_NAMESPACE_FILESYSTEM +#endif // !_LIBCPP_CXX03_LANG + _LIBCPP_POP_MACROS #endif // _LIBCPP_CHRONO diff --git a/include/filesystem b/include/filesystem index 339bb252f..06a0eb33c 100644 --- a/include/filesystem +++ b/include/filesystem @@ -259,36 +259,6 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -struct _FilesystemClock { -#if !defined(_LIBCPP_HAS_NO_INT128) - typedef __int128_t rep; - typedef nano period; -#else - typedef long long rep; - typedef nano period; -#endif - - typedef chrono::duration duration; - typedef chrono::time_point<_FilesystemClock> time_point; - - static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; - - _LIBCPP_FUNC_VIS static time_point now() noexcept; - - _LIBCPP_INLINE_VISIBILITY - static time_t to_time_t(const time_point& __t) noexcept { - typedef chrono::duration __secs; - return time_t( - chrono::duration_cast<__secs>(__t.time_since_epoch()).count()); - } - - _LIBCPP_INLINE_VISIBILITY - static time_point from_time_t(time_t __t) noexcept { - typedef chrono::duration __secs; - return time_point(__secs(__t)); - } -}; - typedef chrono::time_point<_FilesystemClock> file_time_type; struct _LIBCPP_TYPE_VIS space_info { diff --git a/test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp new file mode 100644 index 000000000..275faa628 --- /dev/null +++ b/test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 +// +// TODO: Remove this when filesystem gets integrated into the dylib +// REQUIRES: c++filesystem + +// + +// file_clock + +// check clock invariants + +#include + +template +void test(const T &) {} + +int main() +{ + typedef std::chrono::system_clock C; + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((C::is_steady || !C::is_steady), ""); + test(std::chrono::system_clock::is_steady); +} diff --git a/test/std/utilities/time/time.clock/time.clock.file/file_time.pass.cpp b/test/std/utilities/time/time.clock/time.clock.file/file_time.pass.cpp new file mode 100644 index 000000000..955e3ebe9 --- /dev/null +++ b/test/std/utilities/time/time.clock/time.clock.file/file_time.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// file_time + +#include + +#include "test_macros.h" + +template +void test() { + ASSERT_SAME_TYPE(std::chrono::file_time, std::chrono::time_point); +} + +int main() { + test(); + test(); + test(); +} \ No newline at end of file diff --git a/test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp b/test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp new file mode 100644 index 000000000..69dfa9180 --- /dev/null +++ b/test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// TODO: Remove this when filesystem gets integrated into the dylib +// REQUIRES: c++filesystem + +// + +// file_clock + +// static time_point now() noexcept; + +#include +#include + +#include "test_macros.h" + +int main() +{ + typedef std::chrono::file_clock C; + ASSERT_NOEXCEPT(C::now()); + + C::time_point t1 = C::now(); + assert(t1.time_since_epoch().count() != 0); + assert(C::time_point::min() < t1); + assert(C::time_point::max() > t1); +} diff --git a/test/std/utilities/time/time.clock/time.clock.file/rep_signed.pass.cpp b/test/std/utilities/time/time.clock/time.clock.file/rep_signed.pass.cpp new file mode 100644 index 000000000..c0fa0b5be --- /dev/null +++ b/test/std/utilities/time/time.clock/time.clock.file/rep_signed.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// TODO: Remove this when filesystem gets integrated into the dylib +// REQUIRES: c++filesystem + +// + +// file_clock + +// rep should be signed + +#include +#include + +int main() +{ + static_assert(std::is_signed::value, ""); + assert(std::chrono::file_clock::duration::min() < + std::chrono::file_clock::duration::zero()); +} diff --git a/www/cxx2a_status.html b/www/cxx2a_status.html index 25e6cdfe4..88aa56e38 100644 --- a/www/cxx2a_status.html +++ b/www/cxx2a_status.html @@ -282,7 +282,7 @@ 3132Library needs to ban macros named expects or ensuresSan DiegoNothing to do 3134[fund.ts.v3] LFTSv3 contains extraneous [meta] variable templates that should have been deleted by P09961San DiegoResolved by P1210R0 3137Header for __cpp_lib_to_charsSan DiegoWe've already made the update; but we don't support all the test macros. When we do, this will be closed - 3145file_clock breaks ABI for C++17 implementationsSan Diego + 3145file_clock breaks ABI for C++17 implementationsSan DiegoComplete 3147Definitions of "likely" and "unlikely" are likely to cause problemsSan Diego 3148<concepts> should be freestandingSan Diego 3153Common and common_type have too little in commonSan Diego From 3cf34d1caf53a2c286e7b5f869599be94c4ec559 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Fri, 21 Dec 2018 04:09:01 +0000 Subject: [PATCH 64/94] Implement LWG 3065: Make path operators friends. This prevents things like: using namespace std::filesystem; auto x = L"a/b" == std::string("a/b"); git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349884 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/filesystem | 62 ++++++++----------- .../path.nonmember/append_op.fail.cpp | 27 ++++++++ .../path.nonmember/append_op.pass.cpp | 4 +- .../path.nonmember/comparison_ops.fail.cpp | 33 ++++++++++ www/cxx2a_status.html | 2 +- 5 files changed, 89 insertions(+), 39 deletions(-) create mode 100644 test/std/input.output/filesystems/class.path/path.nonmember/append_op.fail.cpp create mode 100644 test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops.fail.cpp diff --git a/include/filesystem b/include/filesystem index 06a0eb33c..af713a063 100644 --- a/include/filesystem +++ b/include/filesystem @@ -1151,6 +1151,31 @@ public: return __is; } + friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) == 0; + } + friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) != 0; + } + friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) < 0; + } + friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) <= 0; + } + friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) > 0; + } + friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) >= 0; + } + + friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs, + const path& __rhs) { + path __result(__lhs); + __result /= __rhs; + return __result; + } private: inline _LIBCPP_INLINE_VISIBILITY path& __assign_view(__string_view const& __s) noexcept { @@ -1167,43 +1192,6 @@ inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept { _LIBCPP_FUNC_VIS size_t hash_value(const path& __p) noexcept; -inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, - const path& __rhs) noexcept { - return __lhs.compare(__rhs) == 0; -} - -inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, - const path& __rhs) noexcept { - return __lhs.compare(__rhs) != 0; -} - -inline _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, - const path& __rhs) noexcept { - return __lhs.compare(__rhs) < 0; -} - -inline _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, - const path& __rhs) noexcept { - return __lhs.compare(__rhs) <= 0; -} - -inline _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, - const path& __rhs) noexcept { - return __lhs.compare(__rhs) > 0; -} - -inline _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, - const path& __rhs) noexcept { - return __lhs.compare(__rhs) >= 0; -} - -inline _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs, - const path& __rhs) { - path __result(__lhs); - __result /= __rhs; - return __result; -} - template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_pathable<_Source>::value, path>::type diff --git a/test/std/input.output/filesystems/class.path/path.nonmember/append_op.fail.cpp b/test/std/input.output/filesystems/class.path/path.nonmember/append_op.fail.cpp new file mode 100644 index 000000000..e0b3a959c --- /dev/null +++ b/test/std/input.output/filesystems/class.path/path.nonmember/append_op.fail.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +#include "filesystem_include.hpp" + +using namespace fs; + +struct ConvToPath { + operator fs::path() const { + return ""; + } +}; + +int main() { + ConvToPath LHS, RHS; + (void)(LHS / RHS); // expected-error {{invalid operands to binary expression}} +} \ No newline at end of file diff --git a/test/std/input.output/filesystems/class.path/path.nonmember/append_op.pass.cpp b/test/std/input.output/filesystems/class.path/path.nonmember/append_op.pass.cpp index 09498bf21..2a291d61d 100644 --- a/test/std/input.output/filesystems/class.path/path.nonmember/append_op.pass.cpp +++ b/test/std/input.output/filesystems/class.path/path.nonmember/append_op.pass.cpp @@ -20,7 +20,6 @@ #include "test_macros.h" #include "filesystem_test_helper.hpp" - // This is mainly tested via the member append functions. int main() { @@ -29,4 +28,7 @@ int main() path p2("def"); path p3 = p1 / p2; assert(p3 == "abc/def"); + + path p4 = p1 / "def"; + assert(p4 == "abc/def"); } diff --git a/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops.fail.cpp b/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops.fail.cpp new file mode 100644 index 000000000..00eafe532 --- /dev/null +++ b/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops.fail.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + + +#include "filesystem_include.hpp" + +using namespace fs; + +struct ConvToPath { + operator fs::path() const { + return ""; + } +}; + +int main() { + ConvToPath LHS, RHS; + (void)(LHS == RHS); // expected-error {{invalid operands to binary expression}} + (void)(LHS != RHS); // expected-error {{invalid operands to binary expression}} + (void)(LHS < RHS); // expected-error {{invalid operands to binary expression}} + (void)(LHS <= RHS); // expected-error {{invalid operands to binary expression}} + (void)(LHS > RHS); // expected-error {{invalid operands to binary expression}} + (void)(LHS >= RHS); // expected-error {{invalid operands to binary expression}} +} \ No newline at end of file diff --git a/www/cxx2a_status.html b/www/cxx2a_status.html index 88aa56e38..1a072c9b0 100644 --- a/www/cxx2a_status.html +++ b/www/cxx2a_status.html @@ -270,7 +270,7 @@ 3037polymorphic_allocator and incomplete typesSan Diego 3038polymorphic_allocator::allocate should not allow integer overflow to create vulnerabilitiesSan Diego 3054uninitialized_copy appears to not be able to meet its exception-safety guaranteeSan Diego - 3065LWG 2989 missed that all path's other operators should be hidden friends as wellSan Diego + 3065LWG 2989 missed that all path's other operators should be hidden friends as wellSan DiegoComplete 3096path::lexically_relative is confused by trailing slashesSan Diego 3116OUTERMOST_ALLOC_TRAITS needs remove_reference_tSan Diego 3122__cpp_lib_chrono_udls was accidentally droppedSan DiegoWe've already made the update; but we don't support all the test macros. When we do, this will be closed From da05bdc85c1b8ef6e14f95a74d426256132eba81 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Fri, 21 Dec 2018 04:25:40 +0000 Subject: [PATCH 65/94] Implement LWG 3096: path::lexically_relative is confused by trailing slashes path("/dir/").lexically_relative("/dir"); now returns "." instead of "" git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349885 91177308-0d34-0410-b5e6-96231b3b80d8 --- src/filesystem/operations.cpp | 9 ++++++--- .../path.gen/lexically_relative_and_proximate.pass.cpp | 4 ++-- www/cxx2a_status.html | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/filesystem/operations.cpp b/src/filesystem/operations.cpp index 0b79ef1cd..e3bbc7b64 100644 --- a/src/filesystem/operations.cpp +++ b/src/filesystem/operations.cpp @@ -1478,7 +1478,7 @@ static int DetermineLexicalElementCount(PathParser PP) { auto Elem = *PP; if (Elem == "..") --Count; - else if (Elem != ".") + else if (Elem != "." && Elem != "") ++Count; } return Count; @@ -1492,8 +1492,7 @@ path path::lexically_relative(const path& base) const { return PP.State != PPBase.State && (PP.inRootPath() || PPBase.inRootPath()); }; - if (PP.State == PathParser::PS_InRootName && - PPBase.State == PathParser::PS_InRootName) { + if (PP.inRootName() && PPBase.inRootName()) { if (*PP != *PPBase) return {}; } else if (CheckIterMismatchAtBase()) @@ -1525,6 +1524,10 @@ path path::lexically_relative(const path& base) const { if (ElemCount < 0) return {}; + // if n == 0 and (a == end() || a->empty()), returns path("."); otherwise + if (ElemCount == 0 && (PP.atEnd() || *PP == "")) + return "."; + // return a path constructed with 'n' dot-dot elements, followed by the the // elements of '*this' after the mismatch. path Result; diff --git a/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp b/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp index 52c577bc8..f4e1d2f74 100644 --- a/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp +++ b/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp @@ -40,8 +40,8 @@ int main() { {"a", "/", ""}, {"//net", "a", ""}, {"a", "//net", ""}, - {"//net/", "//net", ""}, - {"//net", "//net/", ".."}, + {"//net/", "//net", "."}, + {"//net", "//net/", "."}, {"//base", "a", ""}, {"a", "a", "."}, {"a/b", "a/b", "."}, diff --git a/www/cxx2a_status.html b/www/cxx2a_status.html index 1a072c9b0..63ae029ed 100644 --- a/www/cxx2a_status.html +++ b/www/cxx2a_status.html @@ -271,7 +271,7 @@ 3038polymorphic_allocator::allocate should not allow integer overflow to create vulnerabilitiesSan Diego 3054uninitialized_copy appears to not be able to meet its exception-safety guaranteeSan Diego 3065LWG 2989 missed that all path's other operators should be hidden friends as wellSan DiegoComplete - 3096path::lexically_relative is confused by trailing slashesSan Diego + 3096path::lexically_relative is confused by trailing slashesSan DiegoComplete 3116OUTERMOST_ALLOC_TRAITS needs remove_reference_tSan Diego 3122__cpp_lib_chrono_udls was accidentally droppedSan DiegoWe've already made the update; but we don't support all the test macros. When we do, this will be closed 3127basic_osyncstream::rdbuf needs a const_castSan Diego From fdb4802a742b4ad1201a8d55ca13e407d8df3c73 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Fri, 21 Dec 2018 04:27:45 +0000 Subject: [PATCH 66/94] Fix copy paste error in file_clock tests git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349886 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../time/time.clock/time.clock.file/consistency.pass.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp index 275faa628..0b5757f67 100644 --- a/test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp +++ b/test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp @@ -25,11 +25,11 @@ void test(const T &) {} int main() { - typedef std::chrono::system_clock C; + typedef std::chrono::file_clock C; static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); - static_assert((C::is_steady || !C::is_steady), ""); - test(std::chrono::system_clock::is_steady); + static_assert(!C::is_steady, ""); + test(std::chrono::file_clock::is_steady); } From 1c5aabc9b7bc3c2a9c45f63b76d0b24684433da0 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Fri, 21 Dec 2018 04:30:04 +0000 Subject: [PATCH 67/94] Don't forward declare _FilesystemClock in C++03 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349887 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/chrono | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/chrono b/include/chrono index a5bb9afa8..cabf18c03 100644 --- a/include/chrono +++ b/include/chrono @@ -808,9 +808,11 @@ constexpr chrono::year operator ""y(unsigned lo _LIBCPP_PUSH_MACROS #include <__undef_macros> +#ifndef _LIBCPP_CXX03_LANG _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM struct _FilesystemClock; _LIBCPP_END_NAMESPACE_FILESYSTEM +#endif // !_LIBCPP_CXX03_LANG _LIBCPP_BEGIN_NAMESPACE_STD From 5f14fb5f341d0e1f47fc4ca2b048b2047476d501 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Fri, 21 Dec 2018 04:38:22 +0000 Subject: [PATCH 68/94] Fix test case breakages caused by lexically_relative change git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349888 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../fs.op.funcs/fs.op.proximate/proximate.pass.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp b/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp index 5f7b30dd6..ec4fc6d91 100644 --- a/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp +++ b/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp @@ -75,12 +75,12 @@ TEST_CASE(basic_test) { {"a", parent_cwd, "fs.op.proximate/a"}, {"/", "a", dot_dot_to_root / ".."}, {"/", "a/b", dot_dot_to_root / "../.."}, - {"/", "a/b/", dot_dot_to_root / "../../.."}, + {"/", "a/b/", dot_dot_to_root / "../.."}, {"a", "/", relative_cwd / "a"}, {"a/b", "/", relative_cwd / "a/b"}, {"a", "/net", ".." / relative_cwd / "a"}, - {"//foo/", "//foo", "/foo/"}, - {"//foo", "//foo/", ".."}, + {"//foo/", "//foo", "."}, + {"//foo", "//foo/", "."}, {"//foo", "//foo", "."}, {"//foo/", "//foo/", "."}, {"//base", "a", dot_dot_to_root / "../base"}, From 5de5c1197f034e032838228f357c444ce5cda1df Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Fri, 21 Dec 2018 17:32:23 +0000 Subject: [PATCH 69/94] [NFC] Fix typo in comment git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349932 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/variant | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/variant b/include/variant index b33b1c40a..4a771dc63 100644 --- a/include/variant +++ b/include/variant @@ -1066,7 +1066,7 @@ public: #ifndef _LIBCPP_NO_EXCEPTIONS // EXTENSION: When the move construction of `__lhs` into `__rhs` throws // and `__tmp` is nothrow move constructible then we move `__tmp` back - // into `__rhs` and provide the strong exception safety guarentee. + // into `__rhs` and provide the strong exception safety guarantee. try { this->__generic_construct(*__rhs, _VSTD::move(*__lhs)); } catch (...) { From 8c8f0e1933a2cd12c6a07bbd63457d048efdac55 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Fri, 21 Dec 2018 20:14:43 +0000 Subject: [PATCH 70/94] [libcxx] Remove unused macro _LIBCPP_HAS_UNIQUE_TYPEINFO Summary: We already have the negation of that as _LIBCPP_HAS_NONUNIQUE_TYPEINFO. Having both defined is confusing, since only one of them is used. Reviewers: EricWF, mclow.lists Subscribers: christof, jkorous, dexonsmith, libcxx-commits Differential Revision: https://reviews.llvm.org/D54537 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@349947 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/typeinfo | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/include/typeinfo b/include/typeinfo index 92f1e2255..841153286 100644 --- a/include/typeinfo +++ b/include/typeinfo @@ -73,12 +73,8 @@ public: #include #else -#if !defined(_LIBCPP_ABI_MICROSOFT) -#if defined(_LIBCPP_NONUNIQUE_RTTI_BIT) -#define _LIBCPP_HAS_NONUNIQUE_TYPEINFO -#else -#define _LIBCPP_HAS_UNIQUE_TYPEINFO -#endif +#if defined(_LIBCPP_NONUNIQUE_RTTI_BIT) && !defined(_LIBCPP_ABI_MICROSOFT) +# define _LIBCPP_HAS_NONUNIQUE_TYPEINFO #endif namespace std // purposefully not using versioning namespace From 51895bf735478464eaf17643e1235921594927f6 Mon Sep 17 00:00:00 2001 From: Kamil Rytarowski Date: Sun, 30 Dec 2018 23:05:14 +0000 Subject: [PATCH 71/94] More tolerance for flaky tests in libc++ on NetBSD Summary: Tests marked with the flaky attribute ("FLAKY_TEST.") can still report false positives in local tests and on the NetBSD buildbot. Additionally a number of tests (probably all threaded ones) unmarked with the flaky attribute is flaky on NetBSD. An ideal solution on the libcxx side would be to raise max retries for NetBSD and mark failing tests with the flaky flag, however this adds more maintenance burden and constant monitoring of flaky tests. Reduce the work and handle flaky tests as more flaky on NetBSD and allow flakiness of other tests on NetBSD. Reviewers: mgorny, EricWF Reviewed By: mgorny Subscribers: christof, llvm-commits, libcxx-commits Differential Revision: https://reviews.llvm.org/D56064 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350170 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/libcxx/test/format.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/utils/libcxx/test/format.py b/utils/libcxx/test/format.py index 6a334ac31..46b2e46ac 100644 --- a/utils/libcxx/test/format.py +++ b/utils/libcxx/test/format.py @@ -12,6 +12,7 @@ import errno import os import time import random +import platform import lit.Test # pylint: disable=import-error import lit.TestRunner # pylint: disable=import-error @@ -202,6 +203,12 @@ class LibcxxTestFormat(object): for f in os.listdir(local_cwd) if f.endswith('.dat')] is_flaky = self._get_parser('FLAKY_TEST.', parsers).getValue() max_retry = 3 if is_flaky else 1 + + # LIBC++ tests tend to be more flaky on NetBSD, so add more retries. + # We don't do this on other platforms because it's slower. + if platform.system() in ['NetBSD']: + max_retry = max_retry * 3 + for retry_count in range(max_retry): cmd, out, err, rc = self.executor.run(exec_path, [exec_path], local_cwd, data_files, From 7de83dce417ad2f8d3f9aa2293b9b37fb90b3990 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Thu, 3 Jan 2019 17:18:40 +0000 Subject: [PATCH 72/94] De-tab a couple tests. NFC git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350330 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../time/time.duration/time.duration.special/max.pass.cpp | 4 ++-- .../time/time.duration/time.duration.special/zero.pass.cpp | 4 ++-- .../utilities/time/time.point/time.point.special/max.pass.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/std/utilities/time/time.duration/time.duration.special/max.pass.cpp b/test/std/utilities/time/time.duration/time.duration.special/max.pass.cpp index 29b0e04c2..275f87760 100644 --- a/test/std/utilities/time/time.duration/time.duration.special/max.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.special/max.pass.cpp @@ -23,9 +23,9 @@ template void test() { - LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values::max()); + LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values::max()); #if TEST_STD_VER > 17 - ASSERT_NOEXCEPT( std::chrono::duration_values::max()); + ASSERT_NOEXCEPT( std::chrono::duration_values::max()); #endif { typedef typename D::rep Rep; diff --git a/test/std/utilities/time/time.duration/time.duration.special/zero.pass.cpp b/test/std/utilities/time/time.duration/time.duration.special/zero.pass.cpp index f9a4673db..a43bb099f 100644 --- a/test/std/utilities/time/time.duration/time.duration.special/zero.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.special/zero.pass.cpp @@ -22,9 +22,9 @@ template void test() { - LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values::zero()); + LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values::zero()); #if TEST_STD_VER > 17 - ASSERT_NOEXCEPT( std::chrono::duration_values::zero()); + ASSERT_NOEXCEPT( std::chrono::duration_values::zero()); #endif { typedef typename D::rep Rep; diff --git a/test/std/utilities/time/time.point/time.point.special/max.pass.cpp b/test/std/utilities/time/time.point/time.point.special/max.pass.cpp index 1d8d07964..85447ea41 100644 --- a/test/std/utilities/time/time.point/time.point.special/max.pass.cpp +++ b/test/std/utilities/time/time.point/time.point.special/max.pass.cpp @@ -23,9 +23,9 @@ int main() typedef std::chrono::system_clock Clock; typedef std::chrono::milliseconds Duration; typedef std::chrono::time_point TP; - LIBCPP_ASSERT_NOEXCEPT(TP::max()); + LIBCPP_ASSERT_NOEXCEPT(TP::max()); #if TEST_STD_VER > 17 - ASSERT_NOEXCEPT( TP::max()); + ASSERT_NOEXCEPT( TP::max()); #endif assert(TP::max() == TP(Duration::max())); } From 73aa3a89364fe300d1ce0e708fff88514e9da561 Mon Sep 17 00:00:00 2001 From: Kamil Rytarowski Date: Sat, 5 Jan 2019 20:11:54 +0000 Subject: [PATCH 73/94] Revert "D56064: More tolerance for flaky tests in libc++ on NetBSD" Requested by EricWF. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350477 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/libcxx/test/format.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/utils/libcxx/test/format.py b/utils/libcxx/test/format.py index 46b2e46ac..6a334ac31 100644 --- a/utils/libcxx/test/format.py +++ b/utils/libcxx/test/format.py @@ -12,7 +12,6 @@ import errno import os import time import random -import platform import lit.Test # pylint: disable=import-error import lit.TestRunner # pylint: disable=import-error @@ -203,12 +202,6 @@ class LibcxxTestFormat(object): for f in os.listdir(local_cwd) if f.endswith('.dat')] is_flaky = self._get_parser('FLAKY_TEST.', parsers).getValue() max_retry = 3 if is_flaky else 1 - - # LIBC++ tests tend to be more flaky on NetBSD, so add more retries. - # We don't do this on other platforms because it's slower. - if platform.system() in ['NetBSD']: - max_retry = max_retry * 3 - for retry_count in range(max_retry): cmd, out, err, rc = self.executor.run(exec_path, [exec_path], local_cwd, data_files, From 936dd3d1fffaa6464d05d5cce70800448c276e09 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Sat, 5 Jan 2019 21:18:10 +0000 Subject: [PATCH 74/94] Fix flaky symlink access time test. last_write_time(sym, new_time) changes the modification time of the file referenced by the symlink. But reading through the symlink may change the symlinks's access time. This meant the previous test that checked that the symlinks access time was unchanged was incorrect and made the test flaky. This patch removes this test (there really is no non-flaky way to test that the new access time coorisponds to the time at which the symlink was last dereferenced). This should unflake the test. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350478 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../fs.op.last_write_time/last_write_time.pass.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp b/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp index 11152e6ab..bf0096acf 100644 --- a/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp +++ b/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp @@ -125,7 +125,7 @@ TimeSpec LastAccessTime(path const& p) { return GetTimes(p).access; } TimeSpec LastWriteTime(path const& p) { return GetTimes(p).write; } -std::pair GetSymlinkTimes(path const& p) { +Times GetSymlinkTimes(path const& p) { StatT st; if (::lstat(p.c_str(), &st) == -1) { std::error_code ec(errno, std::generic_category()); @@ -136,7 +136,10 @@ std::pair GetSymlinkTimes(path const& p) { std::exit(EXIT_FAILURE); #endif } - return {extract_atime(st), extract_mtime(st)}; + Times res; + res.access = extract_atime(st); + res.write = extract_mtime(st); + return res; } namespace { @@ -500,9 +503,8 @@ TEST_CASE(last_write_time_symlink_test) TEST_CHECK(CompareTime(LastWriteTime(file), new_time)); TEST_CHECK(CompareTime(LastAccessTime(sym), old_times.access)); - std::pair sym_times = GetSymlinkTimes(sym); - TEST_CHECK(CompareTime(sym_times.first, old_sym_times.first)); - TEST_CHECK(CompareTime(sym_times.second, old_sym_times.second)); + Times sym_times = GetSymlinkTimes(sym); + TEST_CHECK(CompareTime(sym_times.write, old_sym_times.write)); } From 642080354947e0606992aa091ce5e1b4e1e4179d Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Sun, 6 Jan 2019 00:37:31 +0000 Subject: [PATCH 75/94] Fix PR39749 - Headers containing just #error harm __has_include. This patch changes to use #warning instead of is harmful to common feature detection idioms. We should also consider only emitting the warning when __DEPRECATED is defined, like we do in the headers. Users may want to specify "-Werror=-W#warnings" while still ignoring the libc++ warnings. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350485 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/experimental/any | 18 ++++++++++++---- include/experimental/chrono | 18 ++++++++++++---- include/experimental/numeric | 12 ++++++++++- include/experimental/optional | 12 ++++++++++- include/experimental/ratio | 18 ++++++++++++---- include/experimental/string_view | 16 +++++++++++--- include/experimental/system_error | 12 ++++++++++- include/experimental/tuple | 12 ++++++++++- .../syserr/use_header_warning.fail.cpp | 18 ++++++++++++++++ .../diagnostics/syserr/version.pass.cpp | 21 +++++++++++++++++++ .../numeric.ops/use_header_warning.fail.cpp | 18 ++++++++++++++++ .../numerics/numeric.ops/version.pass.cpp | 21 +++++++++++++++++++ .../string.view/use_header_warning.fail.cpp | 18 ++++++++++++++++ .../strings/string.view/version.pass.cpp | 21 +++++++++++++++++++ .../utilities/any/use_header_warning.fail.cpp | 18 ++++++++++++++++ .../utilities/any/version.pass.cpp | 21 +++++++++++++++++++ .../optional/use_header_warning.fail.cpp | 18 ++++++++++++++++ .../utilities/optional/version.pass.cpp | 21 +++++++++++++++++++ .../ratio/use_header_warning.fail.cpp | 18 ++++++++++++++++ .../utilities/ratio/version.pass.cpp | 21 +++++++++++++++++++ .../time/use_header_warning.fail.cpp | 18 ++++++++++++++++ .../utilities/time/version.pass.cpp | 21 +++++++++++++++++++ .../tuple/use_header_warning.fail.cpp | 18 ++++++++++++++++ .../utilities/tuple/version.pass.cpp | 21 +++++++++++++++++++ 24 files changed, 411 insertions(+), 19 deletions(-) create mode 100644 test/libcxx/experimental/diagnostics/syserr/use_header_warning.fail.cpp create mode 100644 test/libcxx/experimental/diagnostics/syserr/version.pass.cpp create mode 100644 test/libcxx/experimental/numerics/numeric.ops/use_header_warning.fail.cpp create mode 100644 test/libcxx/experimental/numerics/numeric.ops/version.pass.cpp create mode 100644 test/libcxx/experimental/strings/string.view/use_header_warning.fail.cpp create mode 100644 test/libcxx/experimental/strings/string.view/version.pass.cpp create mode 100644 test/libcxx/experimental/utilities/any/use_header_warning.fail.cpp create mode 100644 test/libcxx/experimental/utilities/any/version.pass.cpp create mode 100644 test/libcxx/experimental/utilities/optional/use_header_warning.fail.cpp create mode 100644 test/libcxx/experimental/utilities/optional/version.pass.cpp create mode 100644 test/libcxx/experimental/utilities/ratio/use_header_warning.fail.cpp create mode 100644 test/libcxx/experimental/utilities/ratio/version.pass.cpp create mode 100644 test/libcxx/experimental/utilities/time/use_header_warning.fail.cpp create mode 100644 test/libcxx/experimental/utilities/time/version.pass.cpp create mode 100644 test/libcxx/experimental/utilities/tuple/use_header_warning.fail.cpp create mode 100644 test/libcxx/experimental/utilities/tuple/version.pass.cpp diff --git a/include/experimental/any b/include/experimental/any index 1dcdd0f25..d9c953425 100644 --- a/include/experimental/any +++ b/include/experimental/any @@ -1,11 +1,21 @@ // -*- C++ -*- -//===------------------------------ any -----------------------------------===// +//===------------------------------- any ----------------------------------===// // // The LLVM Compiler Infrastructure // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_ANY +#define _LIBCPP_EXPERIMENTAL_ANY -#error " has been removed. Use instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING(" has been removed. Use instead.") +#else +# warning " has been removed. Use instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_ANY diff --git a/include/experimental/chrono b/include/experimental/chrono index 591cf7160..30c7e4a9d 100644 --- a/include/experimental/chrono +++ b/include/experimental/chrono @@ -1,11 +1,21 @@ // -*- C++ -*- -//===------------------------------ chrono ---------------------------------===// +//===---------------------------- chrono ----------------------------------===// // // The LLVM Compiler Infrastructure // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_CHRONO +#define _LIBCPP_EXPERIMENTAL_CHRONO -#error " has been removed. Use instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING(" has been removed. Use instead.") +#else +# warning " has been removed. Use instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_CHRONO diff --git a/include/experimental/numeric b/include/experimental/numeric index 14a664011..19c65313f 100644 --- a/include/experimental/numeric +++ b/include/experimental/numeric @@ -7,5 +7,15 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_NUMERIC +#define _LIBCPP_EXPERIMENTAL_NUMERIC -#error " has been removed. Use instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING(" has been removed. Use instead.") +#else +# warning " has been removed. Use instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_NUMERIC diff --git a/include/experimental/optional b/include/experimental/optional index d68cefdf6..6eb4a2618 100644 --- a/include/experimental/optional +++ b/include/experimental/optional @@ -7,5 +7,15 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_OPTIONAL +#define _LIBCPP_EXPERIMENTAL_OPTIONAL -#error " has been removed. Use instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING(" has been removed. Use instead.") +#else +# warning " has been removed. Use instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_OPTIONAL diff --git a/include/experimental/ratio b/include/experimental/ratio index 9c2bf2e46..52c12004d 100644 --- a/include/experimental/ratio +++ b/include/experimental/ratio @@ -1,11 +1,21 @@ // -*- C++ -*- -//===------------------------------ ratio ---------------------------------===// +//===----------------------------- ratio ----------------------------------===// // // The LLVM Compiler Infrastructure // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_RATIO +#define _LIBCPP_EXPERIMENTAL_RATIO -#error " has been removed. Use instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING(" has been removed. Use instead.") +#else +# warning " has been removed. Use instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_RATIO diff --git a/include/experimental/string_view b/include/experimental/string_view index f13bff54d..100bdfe72 100644 --- a/include/experimental/string_view +++ b/include/experimental/string_view @@ -3,9 +3,19 @@ // // The LLVM Compiler Infrastructure // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_STRING_VIEW +#define _LIBCPP_EXPERIMENTAL_STRING_VIEW -#error " has been removed. Use instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING(" has been removed. Use instead.") +#else +# warning " has been removed. Use instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_STRING_VIEW diff --git a/include/experimental/system_error b/include/experimental/system_error index 7937357fa..1cf84ee01 100644 --- a/include/experimental/system_error +++ b/include/experimental/system_error @@ -7,5 +7,15 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR +#define _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR -#error " has been removed. Use instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING(" has been removed. Use instead.") +#else +# warning " has been removed. Use instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR diff --git a/include/experimental/tuple b/include/experimental/tuple index 1f37a6293..6d71bb559 100644 --- a/include/experimental/tuple +++ b/include/experimental/tuple @@ -7,5 +7,15 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_TUPLE +#define _LIBCPP_EXPERIMENTAL_TUPLE -#error " has been removed. Use instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING(" has been removed. Use instead.") +#else +# warning " has been removed. Use instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_TUPLE diff --git a/test/libcxx/experimental/diagnostics/syserr/use_header_warning.fail.cpp b/test/libcxx/experimental/diagnostics/syserr/use_header_warning.fail.cpp new file mode 100644 index 000000000..074a9c58c --- /dev/null +++ b/test/libcxx/experimental/diagnostics/syserr/use_header_warning.fail.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: verify-support + +// + +#include + +// expected-error@experimental/system_error:* {{" has been removed. Use instead."}} + +int main() {} diff --git a/test/libcxx/experimental/diagnostics/syserr/version.pass.cpp b/test/libcxx/experimental/diagnostics/syserr/version.pass.cpp new file mode 100644 index 000000000..c4fb9593a --- /dev/null +++ b/test/libcxx/experimental/diagnostics/syserr/version.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() {} diff --git a/test/libcxx/experimental/numerics/numeric.ops/use_header_warning.fail.cpp b/test/libcxx/experimental/numerics/numeric.ops/use_header_warning.fail.cpp new file mode 100644 index 000000000..32fd0527d --- /dev/null +++ b/test/libcxx/experimental/numerics/numeric.ops/use_header_warning.fail.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: verify-support + +// + +#include + +// expected-error@experimental/numeric:* {{" has been removed. Use instead."}} + +int main() {} diff --git a/test/libcxx/experimental/numerics/numeric.ops/version.pass.cpp b/test/libcxx/experimental/numerics/numeric.ops/version.pass.cpp new file mode 100644 index 000000000..37ac584a7 --- /dev/null +++ b/test/libcxx/experimental/numerics/numeric.ops/version.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() {} diff --git a/test/libcxx/experimental/strings/string.view/use_header_warning.fail.cpp b/test/libcxx/experimental/strings/string.view/use_header_warning.fail.cpp new file mode 100644 index 000000000..64f737420 --- /dev/null +++ b/test/libcxx/experimental/strings/string.view/use_header_warning.fail.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: verify-support + +// + +#include + +// expected-error@experimental/string_view:* {{" has been removed. Use instead."}} + +int main() {} diff --git a/test/libcxx/experimental/strings/string.view/version.pass.cpp b/test/libcxx/experimental/strings/string.view/version.pass.cpp new file mode 100644 index 000000000..417982e36 --- /dev/null +++ b/test/libcxx/experimental/strings/string.view/version.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() {} diff --git a/test/libcxx/experimental/utilities/any/use_header_warning.fail.cpp b/test/libcxx/experimental/utilities/any/use_header_warning.fail.cpp new file mode 100644 index 000000000..0bcda7056 --- /dev/null +++ b/test/libcxx/experimental/utilities/any/use_header_warning.fail.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: verify-support + +// + +#include + +// expected-error@experimental/any:* {{" has been removed. Use instead."}} + +int main() {} diff --git a/test/libcxx/experimental/utilities/any/version.pass.cpp b/test/libcxx/experimental/utilities/any/version.pass.cpp new file mode 100644 index 000000000..bc37d8b4d --- /dev/null +++ b/test/libcxx/experimental/utilities/any/version.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() {} diff --git a/test/libcxx/experimental/utilities/optional/use_header_warning.fail.cpp b/test/libcxx/experimental/utilities/optional/use_header_warning.fail.cpp new file mode 100644 index 000000000..1711d2f03 --- /dev/null +++ b/test/libcxx/experimental/utilities/optional/use_header_warning.fail.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: verify-support + +// + +#include + +// expected-error@experimental/optional:* {{" has been removed. Use instead."}} + +int main() {} diff --git a/test/libcxx/experimental/utilities/optional/version.pass.cpp b/test/libcxx/experimental/utilities/optional/version.pass.cpp new file mode 100644 index 000000000..ef011bbe4 --- /dev/null +++ b/test/libcxx/experimental/utilities/optional/version.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() {} diff --git a/test/libcxx/experimental/utilities/ratio/use_header_warning.fail.cpp b/test/libcxx/experimental/utilities/ratio/use_header_warning.fail.cpp new file mode 100644 index 000000000..d9a01337a --- /dev/null +++ b/test/libcxx/experimental/utilities/ratio/use_header_warning.fail.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: verify-support + +// + +#include + +// expected-error@experimental/ratio:* {{" has been removed. Use instead."}} + +int main() {} diff --git a/test/libcxx/experimental/utilities/ratio/version.pass.cpp b/test/libcxx/experimental/utilities/ratio/version.pass.cpp new file mode 100644 index 000000000..8ebb347a4 --- /dev/null +++ b/test/libcxx/experimental/utilities/ratio/version.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() {} diff --git a/test/libcxx/experimental/utilities/time/use_header_warning.fail.cpp b/test/libcxx/experimental/utilities/time/use_header_warning.fail.cpp new file mode 100644 index 000000000..9f3d679fc --- /dev/null +++ b/test/libcxx/experimental/utilities/time/use_header_warning.fail.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: verify-support + +// + +#include + +// expected-error@experimental/chrono:* {{" has been removed. Use instead."}} + +int main() {} diff --git a/test/libcxx/experimental/utilities/time/version.pass.cpp b/test/libcxx/experimental/utilities/time/version.pass.cpp new file mode 100644 index 000000000..5544a3f0e --- /dev/null +++ b/test/libcxx/experimental/utilities/time/version.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() {} diff --git a/test/libcxx/experimental/utilities/tuple/use_header_warning.fail.cpp b/test/libcxx/experimental/utilities/tuple/use_header_warning.fail.cpp new file mode 100644 index 000000000..520e9fbb4 --- /dev/null +++ b/test/libcxx/experimental/utilities/tuple/use_header_warning.fail.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: verify-support + +// + +#include + +// expected-error@experimental/tuple:* {{" has been removed. Use instead."}} + +int main() {} diff --git a/test/libcxx/experimental/utilities/tuple/version.pass.cpp b/test/libcxx/experimental/utilities/tuple/version.pass.cpp new file mode 100644 index 000000000..c7c9e5728 --- /dev/null +++ b/test/libcxx/experimental/utilities/tuple/version.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() {} From 9e444eb82d34fd56af3875a6971dead607e20b9e Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Sun, 6 Jan 2019 06:14:31 +0000 Subject: [PATCH 76/94] [libcxx] Support building hermetic static library This is useful when static libc++ library is being linked into shared libraries that may be used in combination with libraries. We want to avoid we exporting libc++ symbols in those cases where this option is useful. This is provided as a CMake option and can be enabled by libc++ vendors as needed. Differential Revision: https://reviews.llvm.org/D55404 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350489 91177308-0d34-0410-b5e6-96231b3b80d8 --- CMakeLists.txt | 3 ++ docs/BuildingLibcxx.rst | 9 ++++ lib/CMakeLists.txt | 93 ++++++++++++++++++++++++++--------------- 3 files changed, 72 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d090860e4..a57e36fdd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -283,6 +283,9 @@ endif() option(LIBCXX_CONFIGURE_IDE "Configure libcxx for use within an IDE" ${LIBCXX_CONFIGURE_IDE_DEFAULT}) +option(LIBCXX_HERMETIC_STATIC_LIBRARY + "Do not export any symbols from the static library." OFF) + #=============================================================================== # Check option configurations #=============================================================================== diff --git a/docs/BuildingLibcxx.rst b/docs/BuildingLibcxx.rst index c40e5fbcc..a498c0027 100644 --- a/docs/BuildingLibcxx.rst +++ b/docs/BuildingLibcxx.rst @@ -222,6 +222,15 @@ libc++ specific options Define libc++ destination prefix. +.. option:: LIBCXX_HERMETIC_STATIC_LIBRARY:BOOL + + **Default**: ``OFF`` + + Do not export any symbols from the static libc++ library. This is useful when + This is useful when the static libc++ library is being linked into shared + libraries that may be used in with other shared libraries that use different + C++ library. We want to avoid avoid exporting any libc++ symbols in that case. + .. _libc++experimental options: libc++experimental Specific Options diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 354da21a5..24489e8fb 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -175,42 +175,69 @@ endif() split_list(LIBCXX_COMPILE_FLAGS) split_list(LIBCXX_LINK_FLAGS) -# Add an object library that contains the compiled source files. -add_library(cxx_objects OBJECT ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS}) -if(LIBCXX_CXX_ABI_HEADER_TARGET) - add_dependencies(cxx_objects ${LIBCXX_CXX_ABI_HEADER_TARGET}) -endif() -if(WIN32 AND NOT MINGW) - target_compile_definitions(cxx_objects - PRIVATE - # Ignore the -MSC_VER mismatch, as we may build - # with a different compatibility version. - _ALLOW_MSC_VER_MISMATCH - # Don't check the msvcprt iterator debug levels - # as we will define the iterator types; libc++ - # uses a different macro to identify the debug - # level. - _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH - # We are building the c++ runtime, don't pull in - # msvcprt. - _CRTBLD - # Don't warn on the use of "deprecated" - # "insecure" functions which are standards - # specified. - _CRT_SECURE_NO_WARNINGS - # Use the ISO conforming behaviour for conversion - # in printf, scanf. - _CRT_STDIO_ISO_WIDE_SPECIFIERS) -endif() +macro(cxx_object_library name) + cmake_parse_arguments(ARGS "" "" "DEFINES;FLAGS" ${ARGN}) -set_target_properties(cxx_objects - PROPERTIES - COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}" -) + # Add an object library that contains the compiled source files. + add_library(${name} OBJECT ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS}) + if(LIBCXX_CXX_ABI_HEADER_TARGET) + add_dependencies(${name} ${LIBCXX_CXX_ABI_HEADER_TARGET}) + endif() + if(WIN32 AND NOT MINGW) + target_compile_definitions(${name} + PRIVATE + # Ignore the -MSC_VER mismatch, as we may build + # with a different compatibility version. + _ALLOW_MSC_VER_MISMATCH + # Don't check the msvcprt iterator debug levels + # as we will define the iterator types; libc++ + # uses a different macro to identify the debug + # level. + _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH + # We are building the c++ runtime, don't pull in + # msvcprt. + _CRTBLD + # Don't warn on the use of "deprecated" + # "insecure" functions which are standards + # specified. + _CRT_SECURE_NO_WARNINGS + # Use the ISO conforming behaviour for conversion + # in printf, scanf. + _CRT_STDIO_ISO_WIDE_SPECIFIERS) + endif() + + if(ARGS_DEFINES) + target_compile_definitions(${name} PRIVATE ${ARGS_DEFINES}) + endif() + + set_target_properties(${name} + PROPERTIES + COMPILE_FLAGS ${LIBCXX_COMPILE_FLAGS} + ) + + if(ARGS_FLAGS) + target_compile_options(${name} PRIVATE ${ARGS_FLAGS}) + endif() +endmacro() + +if(LIBCXX_HERMETIC_STATIC_LIBRARY) + append_flags_if_supported(CXX_STATIC_OBJECTS_FLAGS -fvisibility=hidden) + append_flags_if_supported(CXX_STATIC_OBJECTS_FLAGS -fvisibility-global-new-delete-hidden) + cxx_object_library(cxx_static_objects + DEFINES _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS + FLAGS ${CXX_STATIC_OBJECTS_FLAGS}) + cxx_object_library(cxx_shared_objects) + set(cxx_static_sources $) + set(cxx_shared_sources $) +else() + cxx_object_library(cxx_objects) + set(cxx_static_sources $) + set(cxx_shared_sources $) +endif() # Build the shared library. if (LIBCXX_ENABLE_SHARED) - add_library(cxx_shared SHARED $) + add_library(cxx_shared SHARED ${cxx_shared_sources}) if(COMMAND llvm_setup_rpath) llvm_setup_rpath(cxx_shared) endif() @@ -237,7 +264,7 @@ endif() # Build the static library. if (LIBCXX_ENABLE_STATIC) - add_library(cxx_static STATIC $) + add_library(cxx_static STATIC ${cxx_static_sources}) target_link_libraries(cxx_static ${LIBCXX_LIBRARIES}) set(CMAKE_STATIC_LIBRARY_PREFIX "lib") set_target_properties(cxx_static From a9c67b27fa54485b6e63fb5a8d3d14d74c2b5479 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Mon, 7 Jan 2019 16:17:52 +0000 Subject: [PATCH 77/94] Add the feature test macros that were defined in p1353r0 to the headers of the appropriate tests. No actual tests yet, so NFC. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350535 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../compare.version.pass.cpp | 32 +++++++++++++++++++ .../new.version.pass.cpp | 2 +- .../version.version.pass.cpp | 2 ++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 test/std/language.support/support.limits/support.limits.general/compare.version.pass.cpp diff --git a/test/std/language.support/support.limits/support.limits.general/compare.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/compare.version.pass.cpp new file mode 100644 index 000000000..eff2cb293 --- /dev/null +++ b/test/std/language.support/support.limits/support.limits.general/compare.version.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// feature macros + +/* Constant Value + __cpp_lib_three_way_comparison 201711L + +*/ + +#include +#include +#include "test_macros.h" + +int main() +{ +// ensure that the macros that are supposed to be defined in are defined. + +/* +#if !defined(__cpp_lib_fooby) +# error "__cpp_lib_fooby is not defined" +#elif __cpp_lib_fooby < 201606L +# error "__cpp_lib_fooby has an invalid value" +#endif +*/ +} diff --git a/test/std/language.support/support.limits/support.limits.general/new.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/new.version.pass.cpp index 856bd8b01..6bcd242d1 100644 --- a/test/std/language.support/support.limits/support.limits.general/new.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/new.version.pass.cpp @@ -1,4 +1,3 @@ - //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure @@ -11,6 +10,7 @@ // feature macros /* Constant Value + __cpp_lib_destroying_delete 201806L __cpp_lib_hardware_interference_size 201703L __cpp_lib_launder 201606L diff --git a/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp index e2179e08a..29fe4b298 100644 --- a/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp +++ b/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp @@ -29,6 +29,7 @@ __cpp_lib_complex_udls 201309L __cpp_lib_concepts 201806L __cpp_lib_constexpr_swap_algorithms 201806L + __cpp_lib_destroying_delete 201806L __cpp_lib_enable_shared_from_this 201603L __cpp_lib_exchange_function 201304L __cpp_lib_execution 201603L @@ -75,6 +76,7 @@ __cpp_lib_string_udls 201304L __cpp_lib_string_view 201606L __cpp_lib_to_chars 201611L + __cpp_lib_three_way_comparison 201711L __cpp_lib_transformation_trait_aliases 201304L __cpp_lib_transparent_operators 201510L __cpp_lib_tuple_element_t 201402L From 4626eac620fdf0297d04152335fe6970974b82ea Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Mon, 7 Jan 2019 18:21:18 +0000 Subject: [PATCH 78/94] Mark more tests as flaky git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350550 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../thread.condition/thread.condition.condvar/wait_for.pass.cpp | 2 ++ .../thread.condition.condvarany/notify_one.pass.cpp | 2 ++ .../thread.lock.shared.cons/mutex_try_to_lock.pass.cpp | 2 ++ .../thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp | 2 ++ .../thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp | 2 ++ 5 files changed, 10 insertions(+) diff --git a/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp index ca48eee19..8aa233f66 100644 --- a/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp +++ b/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp @@ -9,6 +9,8 @@ // // UNSUPPORTED: libcpp-has-no-threads +// FLAKY_TEST + // // class condition_variable; diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp index 98f6c432c..16e6ff9f1 100644 --- a/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp +++ b/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp @@ -9,6 +9,8 @@ // // UNSUPPORTED: libcpp-has-no-threads +// FLAKY_TEST + // // class condition_variable_any; diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp index 7f89f0af8..694e311b7 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp @@ -10,6 +10,8 @@ // UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: c++98, c++03, c++11 +// FLAKY_TEST + // // template class shared_lock; diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp index dcfdfd11a..f63256373 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp @@ -9,6 +9,8 @@ // // UNSUPPORTED: libcpp-has-no-threads +// FLAKY_TEST + // // template class unique_lock; diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp index cb5c55925..ebaf3e6de 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp @@ -9,6 +9,8 @@ // // UNSUPPORTED: libcpp-has-no-threads +// FLAKY_TEST + // // template class unique_lock; From 354589c472c3f14136aa1f915d6e6dae82c1f4d8 Mon Sep 17 00:00:00 2001 From: Volodymyr Sapsai Date: Tue, 8 Jan 2019 00:03:16 +0000 Subject: [PATCH 79/94] [libcxx] Optimize vectors construction of trivial types from an iterator range with const-ness mismatch. We already have a specialization that will use memcpy for construction of trivial types from an iterator range like std::vector(int *, int *); But if we have const-ness mismatch like std::vector(const int *, const int *); we would use a slow path that copies each element individually. This change enables the optimal specialization for const-ness mismatch. Fixes PR37574. Contributions to the patch are made by Arthur O'Dwyer, Louis Dionne. rdar://problem/40485845 Reviewers: mclow.lists, EricWF, ldionne, scanon Reviewed By: ldionne Subscribers: christof, ldionne, howard.hinnant, cfe-commits Differential Revision: https://reviews.llvm.org/D48342 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350583 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/memory | 26 ++++++++++------ .../vector.cons/construct_iter_iter.pass.cpp | 31 +++++++++++++++++++ 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/include/memory b/include/memory index b012f5bce..93f04c6fa 100644 --- a/include/memory +++ b/include/memory @@ -1502,6 +1502,12 @@ struct __alloc_traits_difference_type<_Alloc, _Ptr, true> typedef typename _Alloc::difference_type type; }; +template +struct __is_default_allocator : false_type {}; + +template +struct __is_default_allocator<_VSTD::allocator<_Tp> > : true_type {}; + template struct _LIBCPP_TEMPLATE_VIS allocator_traits { @@ -1615,7 +1621,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits static typename enable_if < - (is_same >::value + (__is_default_allocator::value || !__has_construct::value) && is_trivially_move_constructible<_Tp>::value, void @@ -1640,23 +1646,25 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits construct(__a, _VSTD::__to_raw_pointer(__begin2), *__begin1); } - template + template ::type, + class _RawDestTp = typename remove_const<_DestTp>::type> _LIBCPP_INLINE_VISIBILITY static typename enable_if < - (is_same >::value - || !__has_construct::value) && - is_trivially_move_constructible<_Tp>::value, + is_trivially_move_constructible<_DestTp>::value && + is_same<_RawSourceTp, _RawDestTp>::value && + (__is_default_allocator::value || + !__has_construct::value), void >::type - __construct_range_forward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) + __construct_range_forward(allocator_type&, _SourceTp* __begin1, _SourceTp* __end1, _DestTp*& __begin2) { - typedef typename remove_const<_Tp>::type _Vp; ptrdiff_t _Np = __end1 - __begin1; if (_Np > 0) { - _VSTD::memcpy(const_cast<_Vp*>(__begin2), __begin1, _Np * sizeof(_Tp)); + _VSTD::memcpy(const_cast<_RawDestTp*>(__begin2), __begin1, _Np * sizeof(_DestTp)); __begin2 += _Np; } } @@ -1679,7 +1687,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits static typename enable_if < - (is_same >::value + (__is_default_allocator::value || !__has_construct::value) && is_trivially_move_constructible<_Tp>::value, void diff --git a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp index 21a7df4a7..60fe2899a 100644 --- a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp @@ -146,9 +146,40 @@ void test_ctor_under_alloc() { #endif } +// Initialize a vector with a different value type. +void test_ctor_with_different_value_type() { + { + // Make sure initialization is performed with each element value, not with + // a memory blob. + float array[3] = {0.0f, 1.0f, 2.0f}; + std::vector v(array, array + 3); + assert(v[0] == 0); + assert(v[1] == 1); + assert(v[2] == 2); + } + struct X { int x; }; + struct Y { int y; }; + struct Z : X, Y { int z; }; + { + Z z; + Z *array[1] = { &z }; + // Though the types Z* and Y* are very similar, initialization still cannot + // be done with `memcpy`. + std::vector v(array, array + 1); + assert(v[0] == &z); + } + { + // Though the types are different, initialization can be done with `memcpy`. + int32_t array[1] = { -1 }; + std::vector v(array, array + 1); + assert(v[0] == 4294967295); + } +} + int main() { basic_test_cases(); emplaceable_concept_tests(); // See PR34898 test_ctor_under_alloc(); + test_ctor_with_different_value_type(); } From 11a8815e5aedc2706a3244cfd4d470253a619ac4 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Tue, 8 Jan 2019 02:48:45 +0000 Subject: [PATCH 80/94] Set the buffer of an fstream to empty when the underlying file is closed. This 'fixes' PR#38052 - std::fstream still good after closing and updating content. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350603 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/fstream | 1 + .../fstreams/fstream.close.pass.cpp | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 test/libcxx/input.output/file.streams/fstreams/fstream.close.pass.cpp diff --git a/include/fstream b/include/fstream index 332b4747c..711e484e2 100644 --- a/include/fstream +++ b/include/fstream @@ -702,6 +702,7 @@ basic_filebuf<_CharT, _Traits>::close() __file_ = 0; else __rt = 0; + setbuf(0, 0); } return __rt; } diff --git a/test/libcxx/input.output/file.streams/fstreams/fstream.close.pass.cpp b/test/libcxx/input.output/file.streams/fstreams/fstream.close.pass.cpp new file mode 100644 index 000000000..0f8defcbd --- /dev/null +++ b/test/libcxx/input.output/file.streams/fstreams/fstream.close.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// + +// template > +// class basic_fstream + +// close(); + +// Inspired by PR#38052 - std::fstream still good after closing and updating content + +#include +#include +#include "platform_support.h" + +int main() +{ + std::string temp = get_temp_file_name(); + + std::fstream ofs(temp, std::ios::out | std::ios::trunc); + ofs << "Hello, World!\n"; + assert( ofs.good()); + ofs.close(); + assert( ofs.good()); + ofs << "Hello, World!\n"; + assert(!ofs.good()); + + std::remove(temp.c_str()); +} From ed1d77ad35412febe364bbee6d5aeeee8e4eb981 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Tue, 8 Jan 2019 20:26:56 +0000 Subject: [PATCH 81/94] [Sema] Teach Clang that aligned allocation is not supported with macosx10.13 Summary: r306722 added diagnostics when aligned allocation is used with deployment targets that do not support it, but the first macosx supporting aligned allocation was incorrectly set to 10.13. In reality, the dylib shipped with macosx10.13 does not support aligned allocation, but the dylib shipped with macosx10.14 does. Reviewers: ahatanak Subscribers: christof, jkorous, dexonsmith, cfe-commits Differential Revision: https://reviews.llvm.org/D56445 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350649 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../support.dynamic/libcpp_deallocate.sh.cpp | 8 +++++++- .../memory/aligned_allocation_macro.pass.cpp | 19 +++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp b/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp index 0e28d61ef..414a75b33 100644 --- a/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp +++ b/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp @@ -14,9 +14,15 @@ // definitions, which does not yet provide aligned allocation // XFAIL: LIBCXX-WINDOWS-FIXME -// Clang 10 (and older) will trigger an availability error when the deployment +// AppleClang 10 (and older) will trigger an availability error when the deployment // target does not support aligned allocation, even if we pass `-faligned-allocation`. +// XFAIL: apple-clang-10 && availability=macosx10.13 // XFAIL: apple-clang-10 && availability=macosx10.12 +// XFAIL: apple-clang-10 && availability=macosx10.11 +// XFAIL: apple-clang-10 && availability=macosx10.10 +// XFAIL: apple-clang-10 && availability=macosx10.9 +// XFAIL: apple-clang-10 && availability=macosx10.8 +// XFAIL: apple-clang-10 && availability=macosx10.7 // The dylibs shipped before macosx10.14 do not contain the aligned allocation // functions, so trying to force using those with -faligned-allocation results diff --git a/test/libcxx/memory/aligned_allocation_macro.pass.cpp b/test/libcxx/memory/aligned_allocation_macro.pass.cpp index 5390bef3e..368076dee 100644 --- a/test/libcxx/memory/aligned_allocation_macro.pass.cpp +++ b/test/libcxx/memory/aligned_allocation_macro.pass.cpp @@ -9,14 +9,17 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 -// Aligned allocation functions are not provided prior to macosx10.13, but -// AppleClang <= 10 does not know about this restriction and always enables them. -// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 -// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 -// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 -// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9 -// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8 -// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7 +// AppleClang <= 10 enables aligned allocation regardless of the deployment +// target, so this test would fail. +// UNSUPPORTED: apple-clang-9, apple-clang-10 + +// XFAIL: availability=macosx10.13 +// XFAIL: availability=macosx10.12 +// XFAIL: availability=macosx10.11 +// XFAIL: availability=macosx10.10 +// XFAIL: availability=macosx10.9 +// XFAIL: availability=macosx10.8 +// XFAIL: availability=macosx10.7 #include From cd72c529808c18ac620c86705b92b6006a6d4780 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Wed, 9 Jan 2019 05:48:54 +0000 Subject: [PATCH 82/94] Mark two more tests as FLAKY git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350692 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../thread.lock/thread.lock.guard/adopt_lock.pass.cpp | 2 ++ .../thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp index 83271009a..79c639eb6 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp @@ -9,6 +9,8 @@ // // UNSUPPORTED: libcpp-has-no-threads +// FLAKY_TEST + // // template class lock_guard; diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp index 97f9d07c1..4a2db39e8 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp @@ -9,6 +9,8 @@ // // UNSUPPORTED: libcpp-has-no-threads +// FLAKY_TEST + // // template class lock_guard; From ee53ced93ec7c333c350207efd45db6bfd92a65f Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Wed, 9 Jan 2019 16:13:04 +0000 Subject: [PATCH 83/94] [libcxx] Remove outdated XFAILs for aligned deallocation AppleClang 10 has been fixed and so these tests don't fail anymore. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350736 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../support.dynamic/libcpp_deallocate.sh.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp b/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp index 414a75b33..f62e82d8e 100644 --- a/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp +++ b/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp @@ -14,16 +14,6 @@ // definitions, which does not yet provide aligned allocation // XFAIL: LIBCXX-WINDOWS-FIXME -// AppleClang 10 (and older) will trigger an availability error when the deployment -// target does not support aligned allocation, even if we pass `-faligned-allocation`. -// XFAIL: apple-clang-10 && availability=macosx10.13 -// XFAIL: apple-clang-10 && availability=macosx10.12 -// XFAIL: apple-clang-10 && availability=macosx10.11 -// XFAIL: apple-clang-10 && availability=macosx10.10 -// XFAIL: apple-clang-10 && availability=macosx10.9 -// XFAIL: apple-clang-10 && availability=macosx10.8 -// XFAIL: apple-clang-10 && availability=macosx10.7 - // The dylibs shipped before macosx10.14 do not contain the aligned allocation // functions, so trying to force using those with -faligned-allocation results // in a link error. From 350f501ab770d7f1dffcb7a125abd7f9e1396a7d Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Wed, 9 Jan 2019 16:34:17 +0000 Subject: [PATCH 84/94] Mark two UDL tests as being unsupported with Clang 7 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350739 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../time.cal.day/time.cal.day.nonmembers/literals.pass.cpp | 2 +- .../time.cal.year/time.cal.year.nonmembers/literals.pass.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/literals.pass.cpp b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/literals.pass.cpp index 765b0e8dc..405200e47 100644 --- a/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/literals.pass.cpp +++ b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/literals.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 -// UNSUPPORTED: clang-5, clang-6 +// UNSUPPORTED: clang-5, clang-6, clang-7 // UNSUPPORTED: apple-clang-6, apple-clang-7, apple-clang-8, apple-clang-9, apple-clang-10 // diff --git a/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/literals.pass.cpp b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/literals.pass.cpp index 7972e4e94..0661567d8 100644 --- a/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/literals.pass.cpp +++ b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/literals.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 -// UNSUPPORTED: clang-5, clang-6 +// UNSUPPORTED: clang-5, clang-6, clang-7 // UNSUPPORTED: apple-clang-6, apple-clang-7, apple-clang-8, apple-clang-9, apple-clang-10 // From 504008e535dbb8ed4aa72ccacb524a7288cd5633 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Wed, 9 Jan 2019 16:35:55 +0000 Subject: [PATCH 85/94] [libcxx] Add a script to run CI on MacOS CI systems like Green Dragon should use this script so as to make reproducing errors easy locally. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350740 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/ci/macos-trunk.sh | 153 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100755 utils/ci/macos-trunk.sh diff --git a/utils/ci/macos-trunk.sh b/utils/ci/macos-trunk.sh new file mode 100755 index 000000000..b365cc6d8 --- /dev/null +++ b/utils/ci/macos-trunk.sh @@ -0,0 +1,153 @@ +#!/usr/bin/env bash + +set -ue + +function usage() { + cat < --libcxxabi-root --std --arch [--lit-args ] + +This script is used to continually test libc++ and libc++abi trunk on MacOS. + + --libcxx-root Full path to the root of the libc++ repository to test. + --libcxxabi-root Full path to the root of the libc++abi repository to test. + --std Version of the C++ Standard to run the tests under (c++03, c++11, etc..). + --arch Architecture to build the tests for (32, 64). + [--lit-args] Additional arguments to pass to lit (optional). If there are multiple arguments, quote them to pass them as a single argument to this script. + [--no-cleanup] Do not cleanup the temporary directory that was used for testing at the end. This can be useful to debug failures. Make sure to clean up manually after. + [-h, --help] Print this help. +EOM +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --libcxx-root) + LIBCXX_ROOT="${2}" + if [[ ! -e "${LIBCXX_ROOT}" ]]; then + echo "--libcxx-root '${LIBCXX_ROOT}' is not a valid directory" + usage + exit 1 + fi + shift; shift + ;; + --libcxxabi-root) + LIBCXXABI_ROOT="${2}" + if [[ ! -e "${LIBCXXABI_ROOT}" ]]; then + echo "--libcxxabi-root '${LIBCXXABI_ROOT}' is not a valid directory" + usage + exit 1 + fi + shift; shift + ;; + --std) + STD="${2}" + shift; shift + ;; + --arch) + ARCH="${2}" + shift; shift + ;; + --lit-args) + ADDITIONAL_LIT_ARGS="${2}" + shift; shift + ;; + --no-cleanup) + NO_CLEANUP="" + shift + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "${1} is not a supported argument" + usage + exit 1 + ;; + esac +done + +if [[ -z ${LIBCXX_ROOT+x} ]]; then echo "--libcxx-root is a required parameter"; usage; exit 1; fi +if [[ -z ${LIBCXXABI_ROOT+x} ]]; then echo "--libcxxabi-root is a required parameter"; usage; exit 1; fi +if [[ -z ${STD+x} ]]; then echo "--std is a required parameter"; usage; exit 1; fi +if [[ -z ${ARCH+x} ]]; then echo "--arch is a required parameter"; usage; exit 1; fi +if [[ -z ${ADDITIONAL_LIT_ARGS+x} ]]; then ADDITIONAL_LIT_ARGS=""; fi + + +TEMP_DIR="$(mktemp -d)" +echo "Created temporary directory ${TEMP_DIR}" +function cleanup { + if [[ -z ${NO_CLEANUP+x} ]]; then + echo "Removing temporary directory ${TEMP_DIR}" + rm -rf "${TEMP_DIR}" + else + echo "Temporary directory is at '${TEMP_DIR}', make sure to clean it up yourself" + fi +} +trap cleanup EXIT + + +LLVM_ROOT="${TEMP_DIR}/llvm" +LIBCXX_BUILD_DIR="${TEMP_DIR}/libcxx-build" +LIBCXX_INSTALL_DIR="${TEMP_DIR}/libcxx-install" +LIBCXXABI_BUILD_DIR="${TEMP_DIR}/libcxxabi-build" +LIBCXXABI_INSTALL_DIR="${TEMP_DIR}/libcxxabi-install" + +LLVM_TARBALL_URL="https://github.com/llvm-mirror/llvm/archive/master.tar.gz" +export CC="$(xcrun --find clang)" +export CXX="$(xcrun --find clang++)" + + +echo "@@@ Downloading LLVM tarball of master (only used for CMake configuration) @@@" +mkdir "${LLVM_ROOT}" +curl -L "${LLVM_TARBALL_URL}" | tar -xz --strip-components=1 -C "${LLVM_ROOT}" +echo "@@@@@@" + + +echo "@@@ Setting up LIT flags @@@" +LIT_FLAGS="-sv --param=std=${STD} ${ADDITIONAL_LIT_ARGS}" +if [[ "${ARCH}" == "32" ]]; then + LIT_FLAGS+=" --param=enable_32bit=true" +fi +echo "@@@@@@" + + +echo "@@@ Configuring CMake for libc++ @@@" +mkdir -p "${LIBCXX_BUILD_DIR}" +(cd "${LIBCXX_BUILD_DIR}" && + xcrun cmake "${LIBCXX_ROOT}" -GNinja \ + -DLLVM_PATH="${LLVM_ROOT}" \ + -DCMAKE_INSTALL_PREFIX="${LIBCXX_INSTALL_DIR}" \ + -DLLVM_LIT_ARGS="${LIT_FLAGS}" \ + -DCMAKE_OSX_ARCHITECTURES="i386;x86_64" # Build a universal dylib +) +echo "@@@@@@" + + +echo "@@@ Configuring CMake for libc++abi @@@" +mkdir -p "${LIBCXXABI_BUILD_DIR}" +(cd "${LIBCXXABI_BUILD_DIR}" && + xcrun cmake "${LIBCXXABI_ROOT}" -GNinja \ + -DLIBCXXABI_LIBCXX_PATH="${LIBCXX_ROOT}" \ + -DLLVM_PATH="${LLVM_ROOT}" \ + -DCMAKE_INSTALL_PREFIX="${LIBCXXABI_INSTALL_DIR}" \ + -DLLVM_LIT_ARGS="${LIT_FLAGS}" \ + -DCMAKE_OSX_ARCHITECTURES="i386;x86_64" # Build a universal dylib +) +echo "@@@@@@" + + +echo "@@@ Building libc++.dylib and libc++abi.dylib from sources (just to make sure it works) @@@" +ninja -C "${LIBCXX_BUILD_DIR}" install-cxx +ninja -C "${LIBCXXABI_BUILD_DIR}" install-cxxabi +echo "@@@@@@" + + +echo "@@@ Running tests for libc++ @@@" +# TODO: We should run check-cxx-abilist too +ninja -C "${LIBCXX_BUILD_DIR}" check-cxx +echo "@@@@@@" + + +echo "@@@ Running tests for libc++abi @@@" +ninja -C "${LIBCXXABI_BUILD_DIR}" check-cxxabi +echo "@@@@@@" From 0ef5c2979234d362cb8c1d3f2052f9dc01d4ee96 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Wed, 9 Jan 2019 19:40:20 +0000 Subject: [PATCH 86/94] [libcxx] Add a script to run CI on older MacOS versions This script can be used by CI systems to test things like availability markup and binary compatibility on older MacOS versions. This is still a bit rough on the edges, for example we don't test libc++abi yet. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350752 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/ci/macos-backdeployment.sh | 180 +++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100755 utils/ci/macos-backdeployment.sh diff --git a/utils/ci/macos-backdeployment.sh b/utils/ci/macos-backdeployment.sh new file mode 100755 index 000000000..1f01fa397 --- /dev/null +++ b/utils/ci/macos-backdeployment.sh @@ -0,0 +1,180 @@ +#!/usr/bin/env bash + +set -ue + +function usage() { + cat < --libcxxabi-root --std --arch --deployment-target --sdk-version [--lit-args ] + +This script is used to continually test the back-deployment use case of libc++ and libc++abi on MacOS. + + --libcxx-root Full path to the root of the libc++ repository to test. + --libcxxabi-root Full path to the root of the libc++abi repository to test. + --std Version of the C++ Standard to run the tests under (c++03, c++11, etc..). + --arch Architecture to build the tests for (32, 64). + --deployment-target The deployment target to run the tests for. This should be a version number of MacOS (e.g. 10.12). All MacOS versions until and including 10.7 are supported. + --sdk-version The version of the SDK to test with. This should be a version number of MacOS (e.g. 10.12). We'll link against the libc++ dylib in that SDK, but we'll run against the one on the given deployment target. + [--lit-args] Additional arguments to pass to lit (optional). If there are multiple arguments, quote them to pass them as a single argument to this script. + [--no-cleanup] Do not cleanup the temporary directory that was used for testing at the end. This can be useful to debug failures. Make sure to clean up manually after. + [-h, --help] Print this help. +EOM +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --libcxx-root) + LIBCXX_ROOT="${2}" + if [[ ! -d "${LIBCXX_ROOT}" ]]; then + echo "--libcxx-root '${LIBCXX_ROOT}' is not a valid directory" + usage + exit 1 + fi + shift; shift + ;; + --libcxxabi-root) + LIBCXXABI_ROOT="${2}" + if [[ ! -d "${LIBCXXABI_ROOT}" ]]; then + echo "--libcxxabi-root '${LIBCXXABI_ROOT}' is not a valid directory" + usage + exit 1 + fi + shift; shift + ;; + --std) + STD="${2}" + shift; shift + ;; + --arch) + ARCH="${2}" + shift; shift + ;; + --deployment-target) + DEPLOYMENT_TARGET="${2}" + shift; shift + ;; + --sdk-version) + MACOS_SDK_VERSION="${2}" + shift; shift + ;; + --lit-args) + ADDITIONAL_LIT_ARGS="${2}" + shift; shift + ;; + --no-cleanup) + NO_CLEANUP="" + shift + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "${1} is not a supported argument" + usage + exit 1 + ;; + esac +done + +if [[ -z ${LIBCXX_ROOT+x} ]]; then echo "--libcxx-root is a required parameter"; usage; exit 1; fi +if [[ -z ${LIBCXXABI_ROOT+x} ]]; then echo "--libcxxabi-root is a required parameter"; usage; exit 1; fi +if [[ -z ${STD+x} ]]; then echo "--std is a required parameter"; usage; exit 1; fi +if [[ -z ${ARCH+x} ]]; then echo "--arch is a required parameter"; usage; exit 1; fi +if [[ -z ${DEPLOYMENT_TARGET+x} ]]; then echo "--deployment-target is a required parameter"; usage; exit 1; fi +if [[ -z ${MACOS_SDK_VERSION+x} ]]; then echo "--sdk-version is a required parameter"; usage; exit 1; fi +if [[ -z ${ADDITIONAL_LIT_ARGS+x} ]]; then ADDITIONAL_LIT_ARGS=""; fi + + +TEMP_DIR="$(mktemp -d)" +echo "Created temporary directory ${TEMP_DIR}" +function cleanup { + if [[ -z ${NO_CLEANUP+x} ]]; then + echo "Removing temporary directory ${TEMP_DIR}" + rm -rf "${TEMP_DIR}" + else + echo "Temporary directory is at '${TEMP_DIR}', make sure to clean it up yourself" + fi +} +trap cleanup EXIT + + +LLVM_ROOT="${TEMP_DIR}/llvm" +LIBCXX_BUILD_DIR="${TEMP_DIR}/libcxx-build" +LIBCXX_INSTALL_DIR="${TEMP_DIR}/libcxx-install" +LIBCXXABI_BUILD_DIR="${TEMP_DIR}/libcxxabi-build" +LIBCXXABI_INSTALL_DIR="${TEMP_DIR}/libcxxabi-install" + +PREVIOUS_DYLIBS_URL="http://lab.llvm.org:8080/roots/libcxx-roots.tar.gz" +LLVM_TARBALL_URL="https://github.com/llvm-mirror/llvm/archive/master.tar.gz" +export CC="$(xcrun --find clang)" +export CXX="$(xcrun --find clang++)" + + +echo "@@@ Downloading LLVM tarball of master (only used for CMake configuration) @@@" +mkdir "${LLVM_ROOT}" +curl -L "${LLVM_TARBALL_URL}" | tar -xz --strip-components=1 -C "${LLVM_ROOT}" +echo "@@@@@@" + + +echo "@@@ Configuring architecture-related stuff @@@" +if [[ "${ARCH}" == "64" ]]; then CMAKE_ARCH_STRING="x86_64"; else CMAKE_ARCH_STRING="i386"; fi +if [[ "${ARCH}" == "64" ]]; then LIT_ARCH_STRING=""; else LIT_ARCH_STRING="--param=enable_32bit=true"; fi +echo "@@@@@@" + + +echo "@@@ Configuring CMake for libc++ @@@" +mkdir -p "${LIBCXX_BUILD_DIR}" +(cd "${LIBCXX_BUILD_DIR}" && + xcrun cmake "${LIBCXX_ROOT}" -GNinja \ + -DLLVM_PATH="${LLVM_ROOT}" \ + -DCMAKE_INSTALL_PREFIX="${LIBCXX_INSTALL_DIR}" \ + -DCMAKE_OSX_ARCHITECTURES="${CMAKE_ARCH_STRING}" +) +echo "@@@@@@" + + +echo "@@@ Configuring CMake for libc++abi @@@" +mkdir -p "${LIBCXXABI_BUILD_DIR}" +(cd "${LIBCXXABI_BUILD_DIR}" && + xcrun cmake "${LIBCXXABI_ROOT}" -GNinja \ + -DLIBCXXABI_LIBCXX_PATH="${LIBCXX_ROOT}" \ + -DLLVM_PATH="${LLVM_ROOT}" \ + -DCMAKE_INSTALL_PREFIX="${LIBCXXABI_INSTALL_DIR}" \ + -DCMAKE_OSX_ARCHITECTURES="${CMAKE_ARCH_STRING}" +) +echo "@@@@@@" + + +echo "@@@ Installing the latest libc++ headers @@@" +ninja -C "${LIBCXX_BUILD_DIR}" install-cxx-headers +echo "@@@@@@" + + +echo "@@@ Downloading dylibs for older deployment targets @@@" +# TODO: The tarball should contain libc++abi.dylib too, we shouldn't be relying on the system's +# TODO: We should also link against the libc++abi.dylib that was shipped in the SDK +PREVIOUS_DYLIBS_DIR="${TEMP_DIR}/libcxx-dylibs" +mkdir "${PREVIOUS_DYLIBS_DIR}" +curl "${PREVIOUS_DYLIBS_URL}" | tar -xz --strip-components=1 -C "${PREVIOUS_DYLIBS_DIR}" +LIBCXX_ON_DEPLOYMENT_TARGET="${PREVIOUS_DYLIBS_DIR}/macOS/${DEPLOYMENT_TARGET}/libc++.dylib" +LIBCXXABI_ON_DEPLOYMENT_TARGET="/usr/lib/libc++abi.dylib" +LIBCXX_IN_SDK="${PREVIOUS_DYLIBS_DIR}/macOS/${MACOS_SDK_VERSION}/libc++.dylib" +echo "@@@@@@" + + +# TODO: We need to also run the tests for libc++abi. +# TODO: Make sure lit will actually run against the libc++abi we specified +echo "@@@ Running tests for libc++ @@@" +"${LIBCXX_BUILD_DIR}/bin/llvm-lit" -sv "${LIBCXX_ROOT}/test" \ + --param=enable_experimental=false \ + --param=enable_filesystem=false \ + ${LIT_ARCH_STRING} \ + --param=cxx_under_test="${CXX}" \ + --param=cxx_headers="${LIBCXX_INSTALL_DIR}/include/c++/v1" \ + --param=std="${STD}" \ + --param=platform="macosx${DEPLOYMENT_TARGET}" \ + --param=cxx_runtime_root="$(dirname "${LIBCXX_ON_DEPLOYMENT_TARGET}")" \ + --param=abi_library_path="$(dirname "${LIBCXXABI_ON_DEPLOYMENT_TARGET}")" \ + --param=use_system_cxx_lib="$(dirname "${LIBCXX_IN_SDK}")" \ + ${ADDITIONAL_LIT_ARGS} +echo "@@@@@@" From 668faeab19b6827e5755b747b2b84b6a882a336b Mon Sep 17 00:00:00 2001 From: JF Bastien Date: Wed, 9 Jan 2019 22:56:45 +0000 Subject: [PATCH 87/94] [NFC] Normalize some test 'main' signatures There were 3 tests with 'int main(void)', and 6 with the return type on a different line. I'm about to send a patch for main in tests, and this NFC change is unrelated. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350770 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/std/containers/unord/unord.map/compare.pass.cpp | 3 +-- .../ostream.inserters.arithmetic/minmax_showbase.pass.cpp | 2 +- .../locale.num.get/facet.num.get.members/test_min_max.pass.cpp | 2 +- .../locale.num.get/facet.num.get.members/test_neg_one.pass.cpp | 2 +- test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp | 3 +-- .../utilities/charconv/charconv.from.chars/integral.pass.cpp | 3 +-- .../std/utilities/charconv/charconv.to.chars/integral.pass.cpp | 3 +-- .../bind/func.bind/func.bind.bind/nested.pass.cpp | 3 +-- test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp | 3 +-- 9 files changed, 9 insertions(+), 15 deletions(-) diff --git a/test/std/containers/unord/unord.map/compare.pass.cpp b/test/std/containers/unord/unord.map/compare.pass.cpp index cffc1dbd4..2761bf177 100644 --- a/test/std/containers/unord/unord.map/compare.pass.cpp +++ b/test/std/containers/unord/unord.map/compare.pass.cpp @@ -33,8 +33,7 @@ namespace std }; } -int -main() +int main() { typedef std::unordered_map MapT; typedef MapT::iterator Iter; diff --git a/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minmax_showbase.pass.cpp b/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minmax_showbase.pass.cpp index 9e602d4e7..c23b3028c 100644 --- a/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minmax_showbase.pass.cpp +++ b/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minmax_showbase.pass.cpp @@ -46,7 +46,7 @@ static void test(std::ios_base::fmtflags fmt, const char *expected) assert(ss.str() == expected); } -int main(void) +int main() { const std::ios_base::fmtflags o = std::ios_base::oct; const std::ios_base::fmtflags d = std::ios_base::dec; diff --git a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp index e2218fffb..ab02716e3 100644 --- a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp +++ b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp @@ -52,7 +52,7 @@ void check_limits() } } -int main(void) +int main() { check_limits(); check_limits(); diff --git a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_neg_one.pass.cpp b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_neg_one.pass.cpp index 712d2897d..bb40f31db 100644 --- a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_neg_one.pass.cpp +++ b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_neg_one.pass.cpp @@ -149,7 +149,7 @@ void test_negate() { } } -int main(void) +int main() { test_neg_one(); test_neg_one(); diff --git a/test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp b/test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp index d9c517230..59673ec88 100644 --- a/test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp +++ b/test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp @@ -63,8 +63,7 @@ test4() assert((std::regex_match(target, smatch, regex))); } -int -main() +int main() { test1(); test2(); diff --git a/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp b/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp index 4dec67e87..7b08f3047 100644 --- a/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp +++ b/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp @@ -184,8 +184,7 @@ struct test_signed : roundtrip_test_base } }; -int -main() +int main() { run(integrals); run(all_signed); diff --git a/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp b/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp index ddf614e33..63891b1ee 100644 --- a/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp +++ b/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp @@ -82,8 +82,7 @@ struct test_signed : to_chars_test_base } }; -int -main() +int main() { run(integrals); run(all_signed); diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp index 5b660da61..ac43dd769 100644 --- a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp @@ -42,8 +42,7 @@ struct plus_one } }; -int -main() +int main() { using std::placeholders::_1; diff --git a/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp b/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp index ce6dcf811..977d2b6da 100644 --- a/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp @@ -26,8 +26,7 @@ struct X void operator()() {} }; -int -main() +int main() { X x; std::function f(x); From a131ebfcaf83dc9459976fe42e8070827e721dc8 Mon Sep 17 00:00:00 2001 From: JF Bastien Date: Wed, 9 Jan 2019 23:20:24 +0000 Subject: [PATCH 88/94] [NFC] Always lock free test: add indirection I have a big patch coming up, and this indirection is required to avoid hitting the following after my big change: error: empty struct has size 0 in C, size 1 in C++ [-Werror,-Wextern-c-compat] git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350772 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp b/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp index 7a8d4c1f4..43436e65a 100644 --- a/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp +++ b/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp @@ -59,7 +59,7 @@ void checkLongLongTypes() { static_assert((0 != ATOMIC_LLONG_LOCK_FREE) == ExpectLockFree, ""); } -int main() +void run() { // structs and unions can't be defined in the template invocation. // Work around this with a typedef. @@ -134,3 +134,5 @@ int main() static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE)); static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE)); } + +int main() { run(); } From 4fb9e8f89a5ade3e80def4a5d4d033852901be35 Mon Sep 17 00:00:00 2001 From: JF Bastien Date: Thu, 10 Jan 2019 18:50:34 +0000 Subject: [PATCH 89/94] Filesystem tests: fix fs.op.relative Summary: The test wasn't using the testing infrastructure properly. Reviewers: ldionne, mclow.lists, EricWF Subscribers: christof, jkorous, dexonsmith, libcxx-commits Differential Revision: https://reviews.llvm.org/D56519 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350872 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../fs.op.relative/relative.pass.cpp | 128 ++++++++++++------ 1 file changed, 84 insertions(+), 44 deletions(-) diff --git a/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp b/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp index e240c6496..940f886f9 100644 --- a/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp +++ b/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp @@ -16,9 +16,8 @@ // path proximate(const path& p, const path& base, error_code& ec); #include "filesystem_include.hpp" +#include #include -#include -#include #include #include "test_macros.h" @@ -30,49 +29,90 @@ TEST_SUITE(filesystem_proximate_path_test_suite) -TEST_CASE(test_signature) { - +TEST_CASE(test_signature_0) { + fs::path p(""); + const fs::path output = fs::weakly_canonical(p); + TEST_CHECK(output == std::string(fs::current_path())); } -int main() { - // clang-format off - struct { - std::string input; - std::string expect; - } TestCases[] = { - {"", fs::current_path()}, - {".", fs::current_path()}, - {StaticEnv::File, StaticEnv::File}, - {StaticEnv::Dir, StaticEnv::Dir}, - {StaticEnv::SymlinkToDir, StaticEnv::Dir}, - {StaticEnv::SymlinkToDir / "dir2/.", StaticEnv::Dir / "dir2"}, - // FIXME? If the trailing separator occurs in a part of the path that exists, - // it is ommitted. Otherwise it is added to the end of the result. - {StaticEnv::SymlinkToDir / "dir2/./", StaticEnv::Dir / "dir2"}, - {StaticEnv::SymlinkToDir / "dir2/DNE/./", StaticEnv::Dir / "dir2/DNE/"}, - {StaticEnv::SymlinkToDir / "dir2", StaticEnv::Dir2}, - {StaticEnv::SymlinkToDir / "dir2/../dir2/DNE/..", StaticEnv::Dir2 / ""}, - {StaticEnv::SymlinkToDir / "dir2/dir3/../DNE/DNE2", StaticEnv::Dir2 / "DNE/DNE2"}, - {StaticEnv::Dir / "../dir1", StaticEnv::Dir}, - {StaticEnv::Dir / "./.", StaticEnv::Dir}, - {StaticEnv::Dir / "DNE/../foo", StaticEnv::Dir / "foo"} - }; - // clang-format on - int ID = 0; - bool Failed = false; - for (auto& TC : TestCases) { - ++ID; - fs::path p(TC.input); - const fs::path output = fs::weakly_canonical(p); - if (output != TC.expect) { - Failed = true; - std::cerr << "TEST CASE #" << ID << " FAILED: \n"; - std::cerr << " Input: '" << TC.input << "'\n"; - std::cerr << " Expected: '" << TC.expect << "'\n"; - std::cerr << " Output: '" << output.native() << "'"; - std::cerr << std::endl; - } - } - return Failed; + +TEST_CASE(test_signature_1) { + fs::path p("."); + const fs::path output = fs::weakly_canonical(p); + TEST_CHECK(output == std::string(fs::current_path())); +} + +TEST_CASE(test_signature_2) { + fs::path p(StaticEnv::File); + const fs::path output = fs::weakly_canonical(p); + TEST_CHECK(output == std::string(StaticEnv::File)); +} + +TEST_CASE(test_signature_3) { + fs::path p(StaticEnv::Dir); + const fs::path output = fs::weakly_canonical(p); + TEST_CHECK(output == std::string(StaticEnv::Dir)); +} + +TEST_CASE(test_signature_4) { + fs::path p(StaticEnv::SymlinkToDir); + const fs::path output = fs::weakly_canonical(p); + TEST_CHECK(output == std::string(StaticEnv::Dir)); +} + +TEST_CASE(test_signature_5) { + fs::path p(StaticEnv::SymlinkToDir / "dir2/."); + const fs::path output = fs::weakly_canonical(p); + TEST_CHECK(output == std::string(StaticEnv::Dir / "dir2")); +} + +TEST_CASE(test_signature_6) { + // FIXME? If the trailing separator occurs in a part of the path that exists, + // it is ommitted. Otherwise it is added to the end of the result. + fs::path p(StaticEnv::SymlinkToDir / "dir2/./"); + const fs::path output = fs::weakly_canonical(p); + TEST_CHECK(output == std::string(StaticEnv::Dir / "dir2")); +} + +TEST_CASE(test_signature_7) { + fs::path p(StaticEnv::SymlinkToDir / "dir2/DNE/./"); + const fs::path output = fs::weakly_canonical(p); + TEST_CHECK(output == std::string(StaticEnv::Dir / "dir2/DNE/")); +} + +TEST_CASE(test_signature_8) { + fs::path p(StaticEnv::SymlinkToDir / "dir2"); + const fs::path output = fs::weakly_canonical(p); + TEST_CHECK(output == std::string(StaticEnv::Dir2)); +} + +TEST_CASE(test_signature_9) { + fs::path p(StaticEnv::SymlinkToDir / "dir2/../dir2/DNE/.."); + const fs::path output = fs::weakly_canonical(p); + TEST_CHECK(output == std::string(StaticEnv::Dir2 / "")); +} + +TEST_CASE(test_signature_10) { + fs::path p(StaticEnv::SymlinkToDir / "dir2/dir3/../DNE/DNE2"); + const fs::path output = fs::weakly_canonical(p); + TEST_CHECK(output == std::string(StaticEnv::Dir2 / "DNE/DNE2")); +} + +TEST_CASE(test_signature_11) { + fs::path p(StaticEnv::Dir / "../dir1"); + const fs::path output = fs::weakly_canonical(p); + TEST_CHECK(output == std::string(StaticEnv::Dir)); +} + +TEST_CASE(test_signature_12) { + fs::path p(StaticEnv::Dir / "./."); + const fs::path output = fs::weakly_canonical(p); + TEST_CHECK(output == std::string(StaticEnv::Dir)); +} + +TEST_CASE(test_signature_13) { + fs::path p(StaticEnv::Dir / "DNE/../foo"); + const fs::path output = fs::weakly_canonical(p); + TEST_CHECK(output == std::string(StaticEnv::Dir / "foo")); } TEST_SUITE_END() From 134a848236518442cc6b4b8006a2927db2e6636b Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Thu, 10 Jan 2019 20:06:11 +0000 Subject: [PATCH 90/94] [libcxx] Reorganize tests since the application of P0602R4 Summary: P0602R4 makes the special member functions of optional and variant conditionally trivial based on the types in the optional/variant. We already implemented that, but the tests were organized as if this were a non-standard extension. This patch reorganizes the tests in a way that makes more sense since this is not an extension anymore. Reviewers: EricWF, mpark, mclow.lists Subscribers: christof, jkorous, dexonsmith, libcxx-commits Differential Revision: https://reviews.llvm.org/D54772 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350884 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/optional | 4 +- include/variant | 8 +- .../optional.object/triviality.abi.pass.cpp} | 32 +++--- .../optional.object.assign/copy.pass.cpp | 6 +- .../optional.object.assign/move.pass.cpp | 38 +++++++- .../optional.object.ctor/copy.fail.cpp | 36 ------- .../optional.object/special_members.pass.cpp | 63 ++++++++++++ .../optional.object/triviality.pass.cpp | 97 +++++++++++++++++++ .../variant.assign/copy.pass.cpp | 32 +++--- .../variant.assign/move.pass.cpp | 32 +++--- .../variant.ctor/copy.pass.cpp | 28 +++--- .../variant.ctor/move.pass.cpp | 28 +++--- www/cxx2a_status.html | 2 +- 13 files changed, 294 insertions(+), 112 deletions(-) rename test/{std/utilities/optional/optional.object/special_member_gen.pass.cpp => libcxx/utilities/optional/optional.object/triviality.abi.pass.cpp} (75%) delete mode 100644 test/std/utilities/optional/optional.object/optional.object.ctor/copy.fail.cpp create mode 100644 test/std/utilities/optional/optional.object/special_members.pass.cpp create mode 100644 test/std/utilities/optional/optional.object/triviality.pass.cpp diff --git a/include/optional b/include/optional index 544140f23..70422068e 100644 --- a/include/optional +++ b/include/optional @@ -105,8 +105,8 @@ namespace std { // 23.6.3.3, assignment optional &operator=(nullopt_t) noexcept; - optional &operator=(const optional &); - optional &operator=(optional &&) noexcept(see below ); + optional &operator=(const optional &); // constexpr in C++20 + optional &operator=(optional &&) noexcept(see below); // constexpr in C++20 template optional &operator=(U &&); template optional &operator=(const optional &); template optional &operator=(optional &&); diff --git a/include/variant b/include/variant index 4a771dc63..a4339de6c 100644 --- a/include/variant +++ b/include/variant @@ -23,8 +23,8 @@ namespace std { // 20.7.2.1, constructors constexpr variant() noexcept(see below); - variant(const variant&); - variant(variant&&) noexcept(see below); + variant(const variant&); // constexpr in C++20 + variant(variant&&) noexcept(see below); // constexpr in C++20 template constexpr variant(T&&) noexcept(see below); @@ -46,8 +46,8 @@ namespace std { ~variant(); // 20.7.2.3, assignment - variant& operator=(const variant&); - variant& operator=(variant&&) noexcept(see below); + variant& operator=(const variant&); // constexpr in C++20 + variant& operator=(variant&&) noexcept(see below); // constexpr in C++20 template variant& operator=(T&&) noexcept(see below); diff --git a/test/std/utilities/optional/optional.object/special_member_gen.pass.cpp b/test/libcxx/utilities/optional/optional.object/triviality.abi.pass.cpp similarity index 75% rename from test/std/utilities/optional/optional.object/special_member_gen.pass.cpp rename to test/libcxx/utilities/optional/optional.object/triviality.abi.pass.cpp index 0b9b6e717..cdfb02736 100644 --- a/test/std/utilities/optional/optional.object/special_member_gen.pass.cpp +++ b/test/libcxx/utilities/optional/optional.object/triviality.abi.pass.cpp @@ -8,8 +8,18 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14 + // +// This test asserts the triviality of special member functions of optional +// whenever T has these special member functions trivial. The goal of this test +// is to make sure that we do not change the triviality of those, since that +// constitues an ABI break (small enough optionals would be passed by registers). +// +// constexpr optional(const optional& rhs); +// constexpr optional(optional&& rhs) noexcept(see below); +// constexpr optional& operator=(const optional& rhs); +// constexpr optional& operator=(optional&& rhs) noexcept(see below); #include #include @@ -21,41 +31,27 @@ template struct SpecialMemberTest { using O = std::optional; - static_assert(std::is_default_constructible_v, - "optional is always default constructible."); - static_assert(std::is_copy_constructible_v == std::is_copy_constructible_v, - "optional is copy constructible if and only if T is copy constructible."); - static_assert(std::is_move_constructible_v == - (std::is_copy_constructible_v || std::is_move_constructible_v), - "optional is move constructible if and only if T is copy or move constructible."); - static_assert(std::is_copy_assignable_v == - (std::is_copy_constructible_v && std::is_copy_assignable_v), - "optional is copy assignable if and only if T is both copy " - "constructible and copy assignable."); - static_assert(std::is_move_assignable_v == - ((std::is_move_constructible_v && std::is_move_assignable_v) || - (std::is_copy_constructible_v && std::is_copy_assignable_v)), - "optional is move assignable if and only if T is both move constructible and " - "move assignable, or both copy constructible and copy assignable."); - - // The following tests are for not-yet-standardized behavior (P0602): static_assert(std::is_trivially_destructible_v == std::is_trivially_destructible_v, "optional is trivially destructible if and only if T is."); + static_assert(std::is_trivially_copy_constructible_v == std::is_trivially_copy_constructible_v, "optional is trivially copy constructible if and only if T is."); + static_assert(std::is_trivially_move_constructible_v == std::is_trivially_move_constructible_v || (!std::is_move_constructible_v && std::is_trivially_copy_constructible_v), "optional is trivially move constructible if T is trivially move constructible, " "or if T is trivially copy constructible and is not move constructible."); + static_assert(std::is_trivially_copy_assignable_v == (std::is_trivially_destructible_v && std::is_trivially_copy_constructible_v && std::is_trivially_copy_assignable_v), "optional is trivially copy assignable if and only if T is trivially destructible, " "trivially copy constructible, and trivially copy assignable."); + static_assert(std::is_trivially_move_assignable_v == (std::is_trivially_destructible_v && ((std::is_trivially_move_constructible_v && std::is_trivially_move_assignable_v) || diff --git a/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp index 98c90aa1d..bec0f09a3 100644 --- a/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp +++ b/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp @@ -10,7 +10,7 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 // -// optional& operator=(const optional& rhs); +// optional& operator=(const optional& rhs); // constexpr in C++20 #include #include @@ -53,15 +53,19 @@ int main() { { using O = optional; +#if TEST_STD_VER > 17 LIBCPP_STATIC_ASSERT(assign_empty(O{42}), ""); LIBCPP_STATIC_ASSERT(assign_value(O{42}), ""); +#endif assert(assign_empty(O{42})); assert(assign_value(O{42})); } { using O = optional; +#if TEST_STD_VER > 17 LIBCPP_STATIC_ASSERT(assign_empty(O{42}), ""); LIBCPP_STATIC_ASSERT(assign_value(O{42}), ""); +#endif assert(assign_empty(O{42})); assert(assign_value(O{42})); } diff --git a/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp index ed8b433da..c41674f13 100644 --- a/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp +++ b/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp @@ -12,11 +12,12 @@ // optional& operator=(optional&& rhs) // noexcept(is_nothrow_move_assignable::value && -// is_nothrow_move_constructible::value); +// is_nothrow_move_constructible::value); // constexpr in C++20 #include -#include #include +#include +#include #include "test_macros.h" #include "archetypes.hpp" @@ -51,6 +52,21 @@ struct Y {}; bool X::throw_now = false; int X::alive = 0; + +template +constexpr bool assign_empty(optional&& lhs) { + optional rhs; + lhs = std::move(rhs); + return !lhs.has_value() && !rhs.has_value(); +} + +template +constexpr bool assign_value(optional&& lhs) { + optional rhs(101); + lhs = std::move(rhs); + return lhs.has_value() && rhs.has_value() && *lhs == Tp{101}; +} + int main() { { @@ -97,6 +113,24 @@ int main() assert(static_cast(opt) == static_cast(opt2)); assert(*opt == *opt2); } + { + using O = optional; +#if TEST_STD_VER > 17 + LIBCPP_STATIC_ASSERT(assign_empty(O{42}), ""); + LIBCPP_STATIC_ASSERT(assign_value(O{42}), ""); +#endif + assert(assign_empty(O{42})); + assert(assign_value(O{42})); + } + { + using O = optional; +#if TEST_STD_VER > 17 + LIBCPP_STATIC_ASSERT(assign_empty(O{42}), ""); + LIBCPP_STATIC_ASSERT(assign_value(O{42}), ""); +#endif + assert(assign_empty(O{42})); + assert(assign_value(O{42})); + } #ifndef TEST_HAS_NO_EXCEPTIONS { static_assert(!std::is_nothrow_move_assignable>::value, ""); diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/copy.fail.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/copy.fail.cpp deleted file mode 100644 index 593368348..000000000 --- a/test/std/utilities/optional/optional.object/optional.object.ctor/copy.fail.cpp +++ /dev/null @@ -1,36 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11, c++14 -// - -// constexpr optional(const optional& rhs); -// If is_trivially_copy_constructible_v is true, -// this constructor shall be a constexpr constructor. - -#include -#include -#include - -#include "test_macros.h" - -struct S { - constexpr S() : v_(0) {} - S(int v) : v_(v) {} - S(const S &rhs) : v_(rhs.v_) {} // make it not trivially copyable - int v_; -}; - - -int main() -{ - static_assert (!std::is_trivially_copy_constructible_v, "" ); - constexpr std::optional o1; - constexpr std::optional o2 = o1; // not constexpr -} diff --git a/test/std/utilities/optional/optional.object/special_members.pass.cpp b/test/std/utilities/optional/optional.object/special_members.pass.cpp new file mode 100644 index 000000000..3bc561cfe --- /dev/null +++ b/test/std/utilities/optional/optional.object/special_members.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// + +// Make sure we properly generate special member functions for optional +// based on the properties of T itself. + +#include +#include + +#include "archetypes.hpp" + + +template +struct SpecialMemberTest { + using O = std::optional; + + static_assert(std::is_default_constructible_v, + "optional is always default constructible."); + + static_assert(std::is_copy_constructible_v == std::is_copy_constructible_v, + "optional is copy constructible if and only if T is copy constructible."); + + static_assert(std::is_move_constructible_v == + (std::is_copy_constructible_v || std::is_move_constructible_v), + "optional is move constructible if and only if T is copy or move constructible."); + + static_assert(std::is_copy_assignable_v == + (std::is_copy_constructible_v && std::is_copy_assignable_v), + "optional is copy assignable if and only if T is both copy " + "constructible and copy assignable."); + + static_assert(std::is_move_assignable_v == + ((std::is_move_constructible_v && std::is_move_assignable_v) || + (std::is_copy_constructible_v && std::is_copy_assignable_v)), + "optional is move assignable if and only if T is both move constructible and " + "move assignable, or both copy constructible and copy assignable."); +}; + +template static void sink(Args&&...) {} + +template +struct DoTestsMetafunction { + DoTestsMetafunction() { sink(SpecialMemberTest{}...); } +}; + +int main() { + sink( + ImplicitTypes::ApplyTypes{}, + ExplicitTypes::ApplyTypes{}, + NonLiteralTypes::ApplyTypes{}, + NonTrivialTypes::ApplyTypes{} + ); +} diff --git a/test/std/utilities/optional/optional.object/triviality.pass.cpp b/test/std/utilities/optional/optional.object/triviality.pass.cpp new file mode 100644 index 000000000..c21c85aad --- /dev/null +++ b/test/std/utilities/optional/optional.object/triviality.pass.cpp @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// The following special member functions should propagate the triviality of +// the element held in the optional (see P0602R4): +// +// constexpr optional(const optional& rhs); +// constexpr optional(optional&& rhs) noexcept(see below); +// constexpr optional& operator=(const optional& rhs); +// constexpr optional& operator=(optional&& rhs) noexcept(see below); + + +#include +#include + +#include "archetypes.hpp" + + +constexpr bool implies(bool p, bool q) { + return !p || q; +} + +template +struct SpecialMemberTest { + using O = std::optional; + + static_assert(implies(std::is_trivially_copy_constructible_v, + std::is_trivially_copy_constructible_v), + "optional is trivially copy constructible if T is trivially copy constructible."); + + static_assert(implies(std::is_trivially_move_constructible_v, + std::is_trivially_move_constructible_v), + "optional is trivially move constructible if T is trivially move constructible"); + + static_assert(implies(std::is_trivially_copy_constructible_v && + std::is_trivially_copy_assignable_v && + std::is_trivially_destructible_v, + + std::is_trivially_copy_assignable_v), + "optional is trivially copy assignable if T is " + "trivially copy constructible, " + "trivially copy assignable, and " + "trivially destructible"); + + static_assert(implies(std::is_trivially_move_constructible_v && + std::is_trivially_move_assignable_v && + std::is_trivially_destructible_v, + + std::is_trivially_move_assignable_v), + "optional is trivially move assignable if T is " + "trivially move constructible, " + "trivially move assignable, and" + "trivially destructible."); +}; + +template static void sink(Args&&...) {} + +template +struct DoTestsMetafunction { + DoTestsMetafunction() { sink(SpecialMemberTest{}...); } +}; + +struct TrivialMoveNonTrivialCopy { + TrivialMoveNonTrivialCopy() = default; + TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy&) {} + TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy&&) = default; + TrivialMoveNonTrivialCopy& operator=(const TrivialMoveNonTrivialCopy&) { return *this; } + TrivialMoveNonTrivialCopy& operator=(TrivialMoveNonTrivialCopy&&) = default; +}; + +struct TrivialCopyNonTrivialMove { + TrivialCopyNonTrivialMove() = default; + TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove&) = default; + TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {} + TrivialCopyNonTrivialMove& operator=(const TrivialCopyNonTrivialMove&) = default; + TrivialCopyNonTrivialMove& operator=(TrivialCopyNonTrivialMove&&) { return *this; } +}; + +int main() { + sink( + ImplicitTypes::ApplyTypes{}, + ExplicitTypes::ApplyTypes{}, + NonLiteralTypes::ApplyTypes{}, + NonTrivialTypes::ApplyTypes{}, + DoTestsMetafunction{} + ); +} diff --git a/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp b/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp index 775ecffea..5ea7069f5 100644 --- a/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp +++ b/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp @@ -26,7 +26,7 @@ // template class variant; -// variant& operator=(variant const&); +// variant& operator=(variant const&); // constexpr in C++20 #include #include @@ -240,7 +240,8 @@ void test_copy_assignment_sfinae() { static_assert(!std::is_copy_assignable::value, ""); } - // The following tests are for not-yet-standardized behavior (P0602): + // Make sure we properly propagate triviality (see P0602R4). +#if TEST_STD_VER > 17 { using V = std::variant; static_assert(std::is_trivially_copy_assignable::value, ""); @@ -262,6 +263,7 @@ void test_copy_assignment_sfinae() { using V = std::variant; static_assert(std::is_trivially_copy_assignable::value, ""); } +#endif // > C++17 } void test_copy_assignment_empty_empty() { @@ -384,7 +386,8 @@ void test_copy_assignment_same_index() { } #endif // TEST_HAS_NO_EXCEPTIONS - // The following tests are for not-yet-standardized behavior (P0602): + // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). +#if TEST_STD_VER > 17 { struct { constexpr Result operator()() const { @@ -441,6 +444,7 @@ void test_copy_assignment_same_index() { static_assert(result.index == 1, ""); static_assert(result.value == 42, ""); } +#endif // > C++17 } void test_copy_assignment_different_index() { @@ -530,7 +534,8 @@ void test_copy_assignment_different_index() { } #endif // TEST_HAS_NO_EXCEPTIONS - // The following tests are for not-yet-standardized behavior (P0602): + // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). +#if TEST_STD_VER > 17 { struct { constexpr Result operator()() const { @@ -559,10 +564,11 @@ void test_copy_assignment_different_index() { static_assert(result.index == 1, ""); static_assert(result.value == 42, ""); } +#endif // > C++17 } template -constexpr bool test_constexpr_assign_extension_imp( +constexpr bool test_constexpr_assign_imp( std::variant&& v, ValueType&& new_value) { const std::variant cp( @@ -572,15 +578,17 @@ constexpr bool test_constexpr_assign_extension_imp( std::get(v) == std::get(cp); } -void test_constexpr_copy_assignment_extension() { - // The following tests are for not-yet-standardized behavior (P0602): +void test_constexpr_copy_assignment() { + // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). +#if TEST_STD_VER > 17 using V = std::variant; static_assert(std::is_trivially_copyable::value, ""); static_assert(std::is_trivially_copy_assignable::value, ""); - static_assert(test_constexpr_assign_extension_imp<0>(V(42l), 101l), ""); - static_assert(test_constexpr_assign_extension_imp<0>(V(nullptr), 101l), ""); - static_assert(test_constexpr_assign_extension_imp<1>(V(42l), nullptr), ""); - static_assert(test_constexpr_assign_extension_imp<2>(V(42l), 101), ""); + static_assert(test_constexpr_assign_imp<0>(V(42l), 101l), ""); + static_assert(test_constexpr_assign_imp<0>(V(nullptr), 101l), ""); + static_assert(test_constexpr_assign_imp<1>(V(42l), nullptr), ""); + static_assert(test_constexpr_assign_imp<2>(V(42l), 101), ""); +#endif // > C++17 } int main() { @@ -591,5 +599,5 @@ int main() { test_copy_assignment_different_index(); test_copy_assignment_sfinae(); test_copy_assignment_not_noexcept(); - test_constexpr_copy_assignment_extension(); + test_constexpr_copy_assignment(); } diff --git a/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp b/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp index 7b2dedd0d..cee141a8c 100644 --- a/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp +++ b/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp @@ -27,7 +27,7 @@ // template class variant; -// variant& operator=(variant&&) noexcept(see below); +// variant& operator=(variant&&) noexcept(see below); // constexpr in C++20 #include #include @@ -206,7 +206,8 @@ void test_move_assignment_sfinae() { static_assert(!std::is_move_assignable::value, ""); } - // The following tests are for not-yet-standardized behavior (P0602): + // Make sure we properly propagate triviality (see P0602R4). +#if TEST_STD_VER > 17 { using V = std::variant; static_assert(std::is_trivially_move_assignable::value, ""); @@ -232,6 +233,7 @@ void test_move_assignment_sfinae() { using V = std::variant; static_assert(std::is_trivially_move_assignable::value, ""); } +#endif // > C++17 } void test_move_assignment_empty_empty() { @@ -353,7 +355,8 @@ void test_move_assignment_same_index() { } #endif // TEST_HAS_NO_EXCEPTIONS - // The following tests are for not-yet-standardized behavior (P0602): + // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). +#if TEST_STD_VER > 17 { struct { constexpr Result operator()() const { @@ -396,6 +399,7 @@ void test_move_assignment_same_index() { static_assert(result.index == 1, ""); static_assert(result.value == 42, ""); } +#endif // > C++17 } void test_move_assignment_different_index() { @@ -445,7 +449,8 @@ void test_move_assignment_different_index() { } #endif // TEST_HAS_NO_EXCEPTIONS - // The following tests are for not-yet-standardized behavior (P0602): + // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). +#if TEST_STD_VER > 17 { struct { constexpr Result operator()() const { @@ -474,10 +479,11 @@ void test_move_assignment_different_index() { static_assert(result.index == 1, ""); static_assert(result.value == 42, ""); } +#endif // > C++17 } template -constexpr bool test_constexpr_assign_extension_imp( +constexpr bool test_constexpr_assign_imp( std::variant&& v, ValueType&& new_value) { std::variant v2( @@ -488,15 +494,17 @@ constexpr bool test_constexpr_assign_extension_imp( std::get(v) == std::get(cp); } -void test_constexpr_move_assignment_extension() { - // The following tests are for not-yet-standardized behavior (P0602): +void test_constexpr_move_assignment() { + // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). +#if TEST_STD_VER > 17 using V = std::variant; static_assert(std::is_trivially_copyable::value, ""); static_assert(std::is_trivially_move_assignable::value, ""); - static_assert(test_constexpr_assign_extension_imp<0>(V(42l), 101l), ""); - static_assert(test_constexpr_assign_extension_imp<0>(V(nullptr), 101l), ""); - static_assert(test_constexpr_assign_extension_imp<1>(V(42l), nullptr), ""); - static_assert(test_constexpr_assign_extension_imp<2>(V(42l), 101), ""); + static_assert(test_constexpr_assign_imp<0>(V(42l), 101l), ""); + static_assert(test_constexpr_assign_imp<0>(V(nullptr), 101l), ""); + static_assert(test_constexpr_assign_imp<1>(V(42l), nullptr), ""); + static_assert(test_constexpr_assign_imp<2>(V(42l), 101), ""); +#endif // > C++17 } int main() { @@ -507,5 +515,5 @@ int main() { test_move_assignment_different_index(); test_move_assignment_sfinae(); test_move_assignment_noexcept(); - test_constexpr_move_assignment_extension(); + test_constexpr_move_assignment(); } diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp index 9e1e77725..6eeec69c8 100644 --- a/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp +++ b/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp @@ -22,7 +22,7 @@ // template class variant; -// variant(variant const&); +// variant(variant const&); // constexpr in C++20 #include #include @@ -126,7 +126,8 @@ void test_copy_ctor_sfinae() { static_assert(!std::is_copy_constructible::value, ""); } - // The following tests are for not-yet-standardized behavior (P0602): + // Make sure we properly propagate triviality (see P0602R4). +#if TEST_STD_VER > 17 { using V = std::variant; static_assert(std::is_trivially_copy_constructible::value, ""); @@ -144,6 +145,7 @@ void test_copy_ctor_sfinae() { using V = std::variant; static_assert(std::is_trivially_copy_constructible::value, ""); } +#endif // > C++17 } void test_copy_ctor_basic() { @@ -174,7 +176,8 @@ void test_copy_ctor_basic() { assert(std::get<1>(v2).value == 42); } - // The following tests are for not-yet-standardized behavior (P0602): + // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). +#if TEST_STD_VER > 17 { constexpr std::variant v(std::in_place_index<0>, 42); static_assert(v.index() == 0, ""); @@ -217,6 +220,7 @@ void test_copy_ctor_basic() { static_assert(v2.index() == 1, ""); static_assert(std::get<1>(v2).value == 42, ""); } +#endif // > C++17 } void test_copy_ctor_valueless_by_exception() { @@ -231,17 +235,16 @@ void test_copy_ctor_valueless_by_exception() { } template -constexpr bool test_constexpr_copy_ctor_extension_imp( - std::variant const& v) -{ +constexpr bool test_constexpr_copy_ctor_imp(std::variant const& v) { auto v2 = v; return v2.index() == v.index() && v2.index() == Idx && std::get(v2) == std::get(v); } -void test_constexpr_copy_ctor_extension() { - // NOTE: This test is for not yet standardized behavior. (P0602) +void test_constexpr_copy_ctor() { + // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). +#if TEST_STD_VER > 17 using V = std::variant; #ifdef TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE static_assert(std::is_trivially_destructible::value, ""); @@ -252,16 +255,17 @@ void test_constexpr_copy_ctor_extension() { #else // TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE static_assert(std::is_trivially_copyable::value, ""); #endif // TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE - static_assert(test_constexpr_copy_ctor_extension_imp<0>(V(42l)), ""); - static_assert(test_constexpr_copy_ctor_extension_imp<1>(V(nullptr)), ""); - static_assert(test_constexpr_copy_ctor_extension_imp<2>(V(101)), ""); + static_assert(test_constexpr_copy_ctor_imp<0>(V(42l)), ""); + static_assert(test_constexpr_copy_ctor_imp<1>(V(nullptr)), ""); + static_assert(test_constexpr_copy_ctor_imp<2>(V(101)), ""); +#endif // > C++17 } int main() { test_copy_ctor_basic(); test_copy_ctor_valueless_by_exception(); test_copy_ctor_sfinae(); - test_constexpr_copy_ctor_extension(); + test_constexpr_copy_ctor(); #if 0 // disable this for the moment; it fails on older compilers. // Need to figure out which compilers will support it. diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp index e6cdb0e96..f59367109 100644 --- a/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp +++ b/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp @@ -22,7 +22,7 @@ // template class variant; -// variant(variant&&) noexcept(see below); +// variant(variant&&) noexcept(see below); // constexpr in C++20 #include #include @@ -147,7 +147,8 @@ void test_move_ctor_sfinae() { static_assert(!std::is_move_constructible::value, ""); } - // The following tests are for not-yet-standardized behavior (P0602): + // Make sure we properly propagate triviality (see P0602R4). +#if TEST_STD_VER > 17 { using V = std::variant; static_assert(std::is_trivially_move_constructible::value, ""); @@ -165,6 +166,7 @@ void test_move_ctor_sfinae() { using V = std::variant; static_assert(std::is_trivially_move_constructible::value, ""); } +#endif // > C++17 } template @@ -214,7 +216,8 @@ void test_move_ctor_basic() { assert(std::get<1>(v2).value == 42); } - // The following tests are for not-yet-standardized behavior (P0602): + // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). +#if TEST_STD_VER > 17 { struct { constexpr Result operator()() const { @@ -287,6 +290,7 @@ void test_move_ctor_basic() { static_assert(result.index == 1, ""); static_assert(result.value.value == 42, ""); } +#endif // > C++17 } void test_move_ctor_valueless_by_exception() { @@ -300,9 +304,7 @@ void test_move_ctor_valueless_by_exception() { } template -constexpr bool test_constexpr_ctor_extension_imp( - std::variant const& v) -{ +constexpr bool test_constexpr_ctor_imp(std::variant const& v) { auto copy = v; auto v2 = std::move(copy); return v2.index() == v.index() && @@ -310,8 +312,9 @@ constexpr bool test_constexpr_ctor_extension_imp( std::get(v2) == std::get(v); } -void test_constexpr_move_ctor_extension() { - // NOTE: This test is for not yet standardized behavior. (P0602) +void test_constexpr_move_ctor() { + // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). +#if TEST_STD_VER > 17 using V = std::variant; #ifdef TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE static_assert(std::is_trivially_destructible::value, ""); @@ -323,9 +326,10 @@ void test_constexpr_move_ctor_extension() { static_assert(std::is_trivially_copyable::value, ""); #endif // TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE static_assert(std::is_trivially_move_constructible::value, ""); - static_assert(test_constexpr_ctor_extension_imp<0>(V(42l)), ""); - static_assert(test_constexpr_ctor_extension_imp<1>(V(nullptr)), ""); - static_assert(test_constexpr_ctor_extension_imp<2>(V(101)), ""); + static_assert(test_constexpr_ctor_imp<0>(V(42l)), ""); + static_assert(test_constexpr_ctor_imp<1>(V(nullptr)), ""); + static_assert(test_constexpr_ctor_imp<2>(V(101)), ""); +#endif // > C++17 } int main() { @@ -333,5 +337,5 @@ int main() { test_move_ctor_valueless_by_exception(); test_move_noexcept(); test_move_ctor_sfinae(); - test_constexpr_move_ctor_extension(); + test_constexpr_move_ctor(); } diff --git a/www/cxx2a_status.html b/www/cxx2a_status.html index 63ae029ed..a5e87ec18 100644 --- a/www/cxx2a_status.html +++ b/www/cxx2a_status.html @@ -115,7 +115,7 @@ P0487R1LWGFixing operator>>(basic_istream&, CharT*) (LWG 2499)San DiegoComplete8.0 P0591R4LWGUtility functions to implement uses-allocator constructionSan Diego P0595R2CWGP0595R2 std::is_constant_evaluated()San Diego - P0602R4LWGvariant and optional should propagate copy/move trivialitySan Diego + P0602R4LWGvariant and optional should propagate copy/move trivialitySan DiegoComplete8.0 P0608R3LWGA sane variant converting constructorSan Diego P0655R1LWGvisit<R>: Explicit Return Type for visitSan Diego P0771R1LWGstd::function move constructor should be noexceptSan DiegoComplete6.0 From 8d42566e70f025efc5f68bf52cbbbe41981a1e0e Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Fri, 11 Jan 2019 15:12:04 +0000 Subject: [PATCH 91/94] Implement the 'sys_time' portions of the C++20 calendaring stuff. Reviewed as D56494 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350929 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/chrono | 188 +++++++++++++++--- .../ctor.local_days.pass.cpp | 73 +++++++ .../ctor.sys_days.pass.cpp | 73 +++++++ .../ctor.local_days.pass.cpp | 51 ++++- .../ctor.sys_days.pass.cpp | 54 ++++- .../ctor.year_month_day_last.pass.cpp | 46 ++++- .../time.cal.ymd.members/ok.pass.cpp | 31 +++ .../op.local_days.pass.cpp | 94 +++++++++ .../time.cal.ymd.members/op.sys_days.pass.cpp | 94 +++++++++ .../time.cal.ymdlast.members/day.pass.cpp | 30 ++- .../op_local_days.pass.cpp | 39 +++- .../op_sys_days.pass.cpp | 39 +++- .../ctor.local_days.pass.cpp | 65 +++++- .../ctor.sys_days.pass.cpp | 65 +++++- .../ctor.year_month_day_last.pass.cpp | 41 ---- .../op.local_days.pass.cpp | 74 +++++++ .../op.sys_days.pass.cpp | 74 +++++++ .../op_local_days.pass.cpp | 38 +++- .../op_sys_days.pass.cpp | 55 ++++- .../local_time.types.pass.cpp | 65 ++++++ .../time.clock.system/sys.time.types.pass.cpp | 64 ++++++ 21 files changed, 1210 insertions(+), 143 deletions(-) create mode 100644 test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.local_days.pass.cpp create mode 100644 test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.sys_days.pass.cpp create mode 100644 test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.local_days.pass.cpp create mode 100644 test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.sys_days.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.year_month_day_last.pass.cpp create mode 100644 test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.local_days.pass.cpp create mode 100644 test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.sys_days.pass.cpp create mode 100644 test/std/utilities/time/time.clock/time.clock.system/local_time.types.pass.cpp create mode 100644 test/std/utilities/time/time.clock/time.clock.system/sys.time.types.pass.cpp diff --git a/include/chrono b/include/chrono index cabf18c03..96759f986 100644 --- a/include/chrono +++ b/include/chrono @@ -1592,6 +1592,19 @@ using file_clock = _VSTD_FS::_FilesystemClock; template using file_time = time_point; + +template +using sys_time = time_point; +using sys_seconds = sys_time; +using sys_days = sys_time; + +struct local_t {}; +template +using local_time = time_point; +using local_seconds = local_time; +using local_days = local_time; + + struct _LIBCPP_TYPE_VIS last_spec { explicit last_spec() = default; }; class _LIBCPP_TYPE_VIS day { @@ -1812,21 +1825,36 @@ private: unsigned char __wd; public: weekday() = default; - explicit inline constexpr weekday(unsigned __val) noexcept: __wd(static_cast(__val)) {} -// inline constexpr weekday(const sys_days& dp) noexcept; -// explicit constexpr weekday(const local_days& dp) noexcept; + inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast(__val)) {} + inline constexpr weekday(const sys_days& __sysd) noexcept + : __wd(__weekday_from_days(__sysd.time_since_epoch().count())) {} + inline explicit constexpr weekday(const local_days& __locd) noexcept + : __wd(__weekday_from_days(__locd.time_since_epoch().count())) {} + inline constexpr weekday& operator++() noexcept { __wd = (__wd == 6 ? 0 : __wd + 1); return *this; } inline constexpr weekday operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; } inline constexpr weekday& operator--() noexcept { __wd = (__wd == 0 ? 6 : __wd - 1); return *this; } inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; } constexpr weekday& operator+=(const days& __dd) noexcept; constexpr weekday& operator-=(const days& __dd) noexcept; - explicit inline constexpr operator unsigned() const noexcept { return __wd; } + inline explicit constexpr operator unsigned() const noexcept { return __wd; } inline constexpr bool ok() const noexcept { return __wd <= 6; } - constexpr weekday_indexed operator[](unsigned __index) const noexcept; - constexpr weekday_last operator[](last_spec) const noexcept; + constexpr weekday_indexed operator[](unsigned __index) const noexcept; + constexpr weekday_last operator[](last_spec) const noexcept; + + static constexpr unsigned char __weekday_from_days(int __days) noexcept; }; + +// https://howardhinnant.github.io/date_algorithms.html#weekday_from_days +inline constexpr +unsigned char weekday::__weekday_from_days(int __days) noexcept +{ + return static_cast( + static_cast(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6) + ); +} + inline constexpr bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept { return static_cast(__lhs) == static_cast(__rhs); } @@ -2221,6 +2249,7 @@ constexpr year_month operator-(const year_month& __lhs, const months& __rhs) noe constexpr year_month operator-(const year_month& __lhs, const years& __rhs) noexcept { return __lhs + -__rhs; } +class year_month_day_last; class _LIBCPP_TYPE_VIS year_month_day { private: @@ -2232,24 +2261,66 @@ public: inline constexpr year_month_day( const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept : __y{__yval}, __m{__mval}, __d{__dval} {} -// inline constexpr year_month_day(const year_month_day_last& __ymdl) noexcept; -// inline constexpr year_month_day(const sys_days& dp) noexcept; -// inline explicit constexpr year_month_day(const local_days& dp) noexcept; + constexpr year_month_day(const year_month_day_last& __ymdl) noexcept; + inline constexpr year_month_day(const sys_days& __sysd) noexcept + : year_month_day(__from_days(__sysd.time_since_epoch())) {} + inline explicit constexpr year_month_day(const local_days& __locd) noexcept + : year_month_day(__from_days(__locd.time_since_epoch())) {} + constexpr year_month_day& operator+=(const months& __dm) noexcept; constexpr year_month_day& operator-=(const months& __dm) noexcept; constexpr year_month_day& operator+=(const years& __dy) noexcept; constexpr year_month_day& operator-=(const years& __dy) noexcept; - inline constexpr chrono::year year() const noexcept { return __y; } - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr chrono::day day() const noexcept { return __d; } -// inline constexpr operator sys_days() const noexcept; -// inline explicit constexpr operator local_days() const noexcept; -// TODO: This is not quite correct; requires the calendar bits to do right -// d_ is in the range [1d, (y_/m_/last).day()], - inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok() && __d.ok(); } + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::day day() const noexcept { return __d; } + inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + + constexpr bool ok() const noexcept; + + static constexpr year_month_day __from_days(days __d) noexcept; + constexpr days __to_days() const noexcept; }; + +// https://howardhinnant.github.io/date_algorithms.html#civil_from_days +inline constexpr +year_month_day +year_month_day::__from_days(days __d) noexcept +{ + static_assert(std::numeric_limits::digits >= 18, ""); + static_assert(std::numeric_limits::digits >= 20 , ""); + const int __z = __d.count() + 719468; + const int __era = (__z >= 0 ? __z : __z - 146096) / 146097; + const unsigned __doe = static_cast(__z - __era * 146097); // [0, 146096] + const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399] + const int __yr = static_cast(__yoe) + __era * 400; + const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365] + const unsigned __mp = (5 * __doy + 2)/153; // [0, 11] + const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31] + const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12] + return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}}; +} + +// https://howardhinnant.github.io/date_algorithms.html#days_from_civil +inline constexpr days year_month_day::__to_days() const noexcept +{ + static_assert(std::numeric_limits::digits >= 18, ""); + static_assert(std::numeric_limits::digits >= 20 , ""); + + const int __yr = static_cast(__y) - (__m <= February); + const unsigned __mth = static_cast(__m); + const unsigned __dy = static_cast(__d); + + const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400; + const unsigned __yoe = static_cast(__yr - __era * 400); // [0, 399] + const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365] + const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096] + return days{__era * 146097 + static_cast(__doe) - 719468}; +} + inline constexpr bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } @@ -2347,15 +2418,29 @@ public: constexpr year_month_day_last& operator+=(const years& __y) noexcept; constexpr year_month_day_last& operator-=(const years& __y) noexcept; - constexpr chrono::year year() const noexcept { return __y; } - constexpr chrono::month month() const noexcept { return __mdl.month(); } - constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl; } -// constexpr chrono::day day() const noexcept; -// constexpr operator sys_days() const noexcept; -// explicit constexpr operator local_days() const noexcept; - constexpr bool ok() const noexcept { return __y.ok() && __mdl.ok(); } + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __mdl.month(); } + inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl; } + constexpr chrono::day day() const noexcept; + inline constexpr operator sys_days() const noexcept { return sys_days{year()/month()/day()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{year()/month()/day()}; } + inline constexpr bool ok() const noexcept { return __y.ok() && __mdl.ok(); } }; +inline constexpr +chrono::day year_month_day_last::day() const noexcept +{ + constexpr chrono::day __d[] = + { + chrono::day(31), chrono::day(28), chrono::day(31), + chrono::day(30), chrono::day(31), chrono::day(30), + chrono::day(31), chrono::day(31), chrono::day(30), + chrono::day(31), chrono::day(30), chrono::day(31) + }; + return month() != February || !__y.is_leap() ? + __d[static_cast(month()) - 1] : chrono::day{29}; +} + inline constexpr bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept { return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); } @@ -2429,6 +2514,15 @@ inline constexpr year_month_day_last& year_month_day_last::operator-=(const mont inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } +inline constexpr year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept + : __y{__ymdl.year()}, __m{__ymdl.month()}, __d{__ymdl.day()} {} + +inline constexpr bool year_month_day::ok() const noexcept +{ + if (!__y.ok() || !__m.ok()) return false; + return chrono::day{1} <= __d && __d <= (__y / __m / last).day(); +} + class _LIBCPP_TYPE_VIS year_month_weekday { chrono::year __y; chrono::month __m; @@ -2438,8 +2532,10 @@ public: constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept : __y{__yval}, __m{__mval}, __wdi{__wdival} {} -// constexpr year_month_weekday(const sys_days& dp) noexcept; -// explicit constexpr year_month_weekday(const local_days& dp) noexcept; + constexpr year_month_weekday(const sys_days& __sysd) noexcept + : year_month_weekday(__from_days(__sysd.time_since_epoch())) {} + inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept + : year_month_weekday(__from_days(__locd.time_since_epoch())) {} constexpr year_month_weekday& operator+=(const months& m) noexcept; constexpr year_month_weekday& operator-=(const months& m) noexcept; constexpr year_month_weekday& operator+=(const years& y) noexcept; @@ -2451,16 +2547,37 @@ public: inline constexpr unsigned index() const noexcept { return __wdi.index(); } inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; } -// constexpr operator sys_days() const noexcept; -// explicit constexpr operator local_days() const noexcept; + inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } inline constexpr bool ok() const noexcept { if (!__y.ok() || !__m.ok() || !__wdi.ok()) return false; // TODO: make sure it's a valid date return true; } + + static constexpr year_month_weekday __from_days(days __d) noexcept; + constexpr days __to_days() const noexcept; }; +inline constexpr +year_month_weekday year_month_weekday::__from_days(days __d) noexcept +{ + const sys_days __sysd{__d}; + const chrono::weekday __wd = chrono::weekday(__sysd); + const year_month_day __ymd = year_month_day(__sysd); + return year_month_weekday{__ymd.year(), __ymd.month(), + __wd[(static_cast(__ymd.day())-1)/7+1]}; +} + +inline constexpr +days year_month_weekday::__to_days() const noexcept +{ + const sys_days __sysd = sys_days(__y/__m/1); + return (__sysd + (__wdi.weekday() - chrono::weekday(__sysd) + days{(__wdi.index()-1)*7})) + .time_since_epoch(); +} + inline constexpr bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } @@ -2538,11 +2655,22 @@ public: inline constexpr chrono::month month() const noexcept { return __m; } inline constexpr chrono::weekday weekday() const noexcept { return __wdl.weekday(); } inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; } -// constexpr operator sys_days() const noexcept; -// explicit constexpr operator local_days() const noexcept; + inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok() && __wdl.ok(); } + + constexpr days __to_days() const noexcept; + }; +inline constexpr +days year_month_weekday_last::__to_days() const noexcept +{ + const sys_days __last = sys_days{__y/__m/last}; + return (__last - (chrono::weekday{__last} - __wdl.weekday())).time_since_epoch(); + +} + inline constexpr bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.local_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.local_days.pass.cpp new file mode 100644 index 000000000..235138235 --- /dev/null +++ b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.local_days.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// +// class weekday; + +// constexpr weekday(const local_days& dp) noexcept; +// +// Effects: Constructs an object of type weekday by computing what day +// of the week corresponds to the local_days dp, and representing +// that day of the week in wd_ +// +// Remarks: For any value ymd of type year_month_day for which ymd.ok() is true, +// ymd == year_month_day{sys_days{ymd}} is true. +// +// [Example: +// If dp represents 1970-01-01, the constructed weekday represents Thursday by storing 4 in wd_. +// —end example] + +#include +#include +#include + +#include "test_macros.h" + +int main() +{ + using local_days = std::chrono::local_days; + using days = std::chrono::days; + using weekday = std::chrono::weekday; + + ASSERT_NOEXCEPT(weekday{std::declval()}); + + { + constexpr local_days sd{}; // 1-Jan-1970 was a Thursday + constexpr weekday wd{sd}; + + static_assert( wd.ok(), ""); + static_assert(static_cast(wd) == 4, ""); + } + + { + constexpr local_days sd{days{10957+32}}; // 2-Feb-2000 was a Wednesday + constexpr weekday wd{sd}; + + static_assert( wd.ok(), ""); + static_assert(static_cast(wd) == 3, ""); + } + + + { + constexpr local_days sd{days{-10957}}; // 2-Jan-1940 was a Tuesday + constexpr weekday wd{sd}; + + static_assert( wd.ok(), ""); + static_assert(static_cast(wd) == 2, ""); + } + + { + local_days sd{days{-(10957+34)}}; // 29-Nov-1939 was a Wednesday + weekday wd{sd}; + + assert( wd.ok()); + assert(static_cast(wd) == 3); + } +} diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.sys_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.sys_days.pass.cpp new file mode 100644 index 000000000..c49d05d3a --- /dev/null +++ b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.sys_days.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// +// class weekday; + +// constexpr weekday(const sys_days& dp) noexcept; +// +// Effects: Constructs an object of type weekday by computing what day +// of the week corresponds to the sys_days dp, and representing +// that day of the week in wd_ +// +// Remarks: For any value ymd of type year_month_day for which ymd.ok() is true, +// ymd == year_month_day{sys_days{ymd}} is true. +// +// [Example: +// If dp represents 1970-01-01, the constructed weekday represents Thursday by storing 4 in wd_. +// —end example] + +#include +#include +#include + +#include "test_macros.h" + +int main() +{ + using sys_days = std::chrono::sys_days; + using days = std::chrono::days; + using weekday = std::chrono::weekday; + + ASSERT_NOEXCEPT(weekday{std::declval()}); + + { + constexpr sys_days sd{}; // 1-Jan-1970 was a Thursday + constexpr weekday wd{sd}; + + static_assert( wd.ok(), ""); + static_assert(static_cast(wd) == 4, ""); + } + + { + constexpr sys_days sd{days{10957+32}}; // 2-Feb-2000 was a Wednesday + constexpr weekday wd{sd}; + + static_assert( wd.ok(), ""); + static_assert(static_cast(wd) == 3, ""); + } + + + { + constexpr sys_days sd{days{-10957}}; // 2-Jan-1940 was a Tuesday + constexpr weekday wd{sd}; + + static_assert( wd.ok(), ""); + static_assert(static_cast(wd) == 2, ""); + } + + { + sys_days sd{days{-(10957+34)}}; // 29-Nov-1939 was a Wednesday + weekday wd{sd}; + + assert( wd.ok()); + assert(static_cast(wd) == 3); + } +} diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.local_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.local_days.pass.cpp index f3321d508..5c7de1418 100644 --- a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.local_days.pass.cpp +++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.local_days.pass.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 -// XFAIL: * // // class year_month_day; @@ -34,11 +33,53 @@ int main() { using year = std::chrono::year; - using month = std::chrono::month; using day = std::chrono::day; -// using local_days = std::chrono::local_days; + using local_days = std::chrono::local_days; + using days = std::chrono::days; using year_month_day = std::chrono::year_month_day; -// ASSERT_NOEXCEPT(year_month_day{std::declval()}); - assert(false); + ASSERT_NOEXCEPT(year_month_day{std::declval()}); + + { + constexpr local_days sd{}; + constexpr year_month_day ymd{sd}; + + static_assert( ymd.ok(), ""); + static_assert( ymd.year() == year{1970}, ""); + static_assert( ymd.month() == std::chrono::January, ""); + static_assert( ymd.day() == day{1}, ""); + } + + { + constexpr local_days sd{days{10957+32}}; + constexpr year_month_day ymd{sd}; + + static_assert( ymd.ok(), ""); + static_assert( ymd.year() == year{2000}, ""); + static_assert( ymd.month() == std::chrono::February, ""); + static_assert( ymd.day() == day{2}, ""); + } + + +// There's one more leap day between 1/1/40 and 1/1/70 +// when compared to 1/1/70 -> 1/1/2000 + { + constexpr local_days sd{days{-10957}}; + constexpr year_month_day ymd{sd}; + + static_assert( ymd.ok(), ""); + static_assert( ymd.year() == year{1940}, ""); + static_assert( ymd.month() == std::chrono::January, ""); + static_assert( ymd.day() == day{2}, ""); + } + + { + local_days sd{days{-(10957+34)}}; + year_month_day ymd{sd}; + + assert( ymd.ok()); + assert( ymd.year() == year{1939}); + assert( ymd.month() == std::chrono::November); + assert( ymd.day() == day{29}); + } } diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.sys_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.sys_days.pass.cpp index d2e268d7d..36a6c7d18 100644 --- a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.sys_days.pass.cpp +++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.sys_days.pass.cpp @@ -7,15 +7,14 @@ // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 -// XFAIL: * // // class year_month_day; // constexpr year_month_day(const sys_days& dp) noexcept; // -// Effects: Constructs an object of type year_month_day that corresponds -// to the date represented by dp +// Effects: Constructs an object of type year_month_day that corresponds +// to the date represented by dp. // // Remarks: For any value ymd of type year_month_day for which ymd.ok() is true, // ymd == year_month_day{sys_days{ymd}} is true. @@ -33,12 +32,53 @@ int main() { using year = std::chrono::year; - using month = std::chrono::month; using day = std::chrono::day; -// using sys_days = std::chrono::sys_days; + using sys_days = std::chrono::sys_days; + using days = std::chrono::days; using year_month_day = std::chrono::year_month_day; -// ASSERT_NOEXCEPT(year_month_day{std::declval()}); - assert(false); + ASSERT_NOEXCEPT(year_month_day{std::declval()}); + { + constexpr sys_days sd{}; + constexpr year_month_day ymd{sd}; + + static_assert( ymd.ok(), ""); + static_assert( ymd.year() == year{1970}, ""); + static_assert( ymd.month() == std::chrono::January, ""); + static_assert( ymd.day() == day{1}, ""); + } + + { + constexpr sys_days sd{days{10957+32}}; + constexpr year_month_day ymd{sd}; + + static_assert( ymd.ok(), ""); + static_assert( ymd.year() == year{2000}, ""); + static_assert( ymd.month() == std::chrono::February, ""); + static_assert( ymd.day() == day{2}, ""); + } + + +// There's one more leap day between 1/1/40 and 1/1/70 +// when compared to 1/1/70 -> 1/1/2000 + { + constexpr sys_days sd{days{-10957}}; + constexpr year_month_day ymd{sd}; + + static_assert( ymd.ok(), ""); + static_assert( ymd.year() == year{1940}, ""); + static_assert( ymd.month() == std::chrono::January, ""); + static_assert( ymd.day() == day{2}, ""); + } + + { + sys_days sd{days{-(10957+34)}}; + year_month_day ymd{sd}; + + assert( ymd.ok()); + assert( ymd.year() == year{1939}); + assert( ymd.month() == std::chrono::November); + assert( ymd.day() == day{29}); + } } diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.year_month_day_last.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.year_month_day_last.pass.cpp index 2b5fbab1a..a8d6526b3 100644 --- a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.year_month_day_last.pass.cpp +++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.year_month_day_last.pass.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 -// XFAIL: * // // class year_month_day; @@ -33,10 +32,49 @@ int main() using year = std::chrono::year; using month = std::chrono::month; using day = std::chrono::day; -// using year_month_day_last = std::chrono::year_month_day_last; + using month_day_last = std::chrono::month_day_last; + using year_month_day_last = std::chrono::year_month_day_last; using year_month_day = std::chrono::year_month_day; -// ASSERT_NOEXCEPT(year_month_day{std::declval()}); - assert(false); + ASSERT_NOEXCEPT(year_month_day{std::declval()}); + { + constexpr year_month_day_last ymdl{year{2019}, month_day_last{month{1}}}; + constexpr year_month_day ymd{ymdl}; + + static_assert( ymd.year() == year{2019}, ""); + static_assert( ymd.month() == month{1}, ""); + static_assert( ymd.day() == day{31}, ""); + static_assert( ymd.ok(), ""); + } + + { + constexpr year_month_day_last ymdl{year{1970}, month_day_last{month{4}}}; + constexpr year_month_day ymd{ymdl}; + + static_assert( ymd.year() == year{1970}, ""); + static_assert( ymd.month() == month{4}, ""); + static_assert( ymd.day() == day{30}, ""); + static_assert( ymd.ok(), ""); + } + + { + constexpr year_month_day_last ymdl{year{2000}, month_day_last{month{2}}}; + constexpr year_month_day ymd{ymdl}; + + static_assert( ymd.year() == year{2000}, ""); + static_assert( ymd.month() == month{2}, ""); + static_assert( ymd.day() == day{29}, ""); + static_assert( ymd.ok(), ""); + } + + { // Feb 1900 was NOT a leap year. + year_month_day_last ymdl{year{1900}, month_day_last{month{2}}}; + year_month_day ymd{ymdl}; + + assert( ymd.year() == year{1900}); + assert( ymd.month() == month{2}); + assert( ymd.day() == day{28}); + assert( ymd.ok()); + } } diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ok.pass.cpp index 529d0d760..cab0599b9 100644 --- a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ok.pass.cpp +++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ok.pass.cpp @@ -44,6 +44,37 @@ int main() static_assert( year_month_day{year{2019}, January, day{1}}.ok(), ""); // All OK +// Some months have a 31st + static_assert( year_month_day{year{2020}, month{ 1}, day{31}}.ok(), ""); + static_assert(!year_month_day{year{2020}, month{ 2}, day{31}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{ 3}, day{31}}.ok(), ""); + static_assert(!year_month_day{year{2020}, month{ 4}, day{31}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{ 5}, day{31}}.ok(), ""); + static_assert(!year_month_day{year{2020}, month{ 6}, day{31}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{ 7}, day{31}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{ 8}, day{31}}.ok(), ""); + static_assert(!year_month_day{year{2020}, month{ 9}, day{31}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{10}, day{31}}.ok(), ""); + static_assert(!year_month_day{year{2020}, month{11}, day{31}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{12}, day{31}}.ok(), ""); + +// Everyone except FEB has a 30th + static_assert( year_month_day{year{2020}, month{ 1}, day{30}}.ok(), ""); + static_assert(!year_month_day{year{2020}, month{ 2}, day{30}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{ 3}, day{30}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{ 4}, day{30}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{ 5}, day{30}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{ 6}, day{30}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{ 7}, day{30}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{ 8}, day{30}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{ 9}, day{30}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{10}, day{30}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{11}, day{30}}.ok(), ""); + static_assert( year_month_day{year{2020}, month{12}, day{30}}.ok(), ""); + + static_assert(!year_month_day{year{2019}, std::chrono::February, day{29}}.ok(), ""); // Not a leap year + static_assert( year_month_day{year{2020}, std::chrono::February, day{29}}.ok(), ""); // Ok; 2020 is a leap year + for (unsigned i = 0; i <= 50; ++i) { year_month_day ym{year{2019}, January, day{i}}; diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.local_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.local_days.pass.cpp new file mode 100644 index 000000000..720a1c800 --- /dev/null +++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.local_days.pass.cpp @@ -0,0 +1,94 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// +// class year_month_day; + +// constexpr operator local_days() const noexcept; +// +// Returns: If ok(), returns a local_days holding a count of days from the +// local_days epoch to *this (a negative value if *this represents a date +// prior to the sys_days epoch). Otherwise, if y_.ok() && m_.ok() is true, +// returns a sys_days which is offset from sys_days{y_/m_/last} by the +// number of days d_ is offset from sys_days{y_/m_/last}.day(). Otherwise +// the value returned is unspecified. +// +// Remarks: A local_days in the range [days{-12687428}, days{11248737}] which +// is converted to a year_month_day shall have the same value when +// converted back to a sys_days. +// +// [Example: +// static_assert(year_month_day{local_days{2017y/January/0}} == 2016y/December/31); +// static_assert(year_month_day{local_days{2017y/January/31}} == 2017y/January/31); +// static_assert(year_month_day{local_days{2017y/January/32}} == 2017y/February/1); +// —end example] + +#include +#include +#include + +#include "test_macros.h" + +void RunTheExample() +{ + using namespace std::chrono; + + static_assert(year_month_day{local_days{2017y/January/0}} == 2016y/December/31); + static_assert(year_month_day{local_days{2017y/January/31}} == 2017y/January/31); + static_assert(year_month_day{local_days{2017y/January/32}} == 2017y/February/1); +} + +int main() +{ + using year = std::chrono::year; + using month = std::chrono::month; + using day = std::chrono::day; + using local_days = std::chrono::local_days; + using days = std::chrono::days; + using year_month_day = std::chrono::year_month_day; + + ASSERT_NOEXCEPT(local_days(std::declval())); + RunTheExample(); + + { + constexpr year_month_day ymd{year{1970}, month{1}, day{1}}; + constexpr local_days sd{ymd}; + + static_assert( sd.time_since_epoch() == days{0}, ""); + static_assert( year_month_day{sd} == ymd, ""); // and back + } + + { + constexpr year_month_day ymd{year{2000}, month{2}, day{2}}; + constexpr local_days sd{ymd}; + + static_assert( sd.time_since_epoch() == days{10957+32}, ""); + static_assert( year_month_day{sd} == ymd, ""); // and back + } + +// There's one more leap day between 1/1/40 and 1/1/70 +// when compared to 1/1/70 -> 1/1/2000 + { + constexpr year_month_day ymd{year{1940}, month{1}, day{2}}; + constexpr local_days sd{ymd}; + + static_assert( sd.time_since_epoch() == days{-10957}, ""); + static_assert( year_month_day{sd} == ymd, ""); // and back + } + + { + year_month_day ymd{year{1939}, month{11}, day{29}}; + local_days sd{ymd}; + + assert( sd.time_since_epoch() == days{-(10957+34)}); + assert( year_month_day{sd} == ymd); // and back + } + +} diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.sys_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.sys_days.pass.cpp new file mode 100644 index 000000000..da9865d9c --- /dev/null +++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.sys_days.pass.cpp @@ -0,0 +1,94 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// +// class year_month_day; + +// constexpr operator sys_days() const noexcept; +// +// Returns: If ok(), returns a sys_days holding a count of days from the +// sys_days epoch to *this (a negative value if *this represents a date +// prior to the sys_days epoch). Otherwise, if y_.ok() && m_.ok() is true, +// returns a sys_days which is offset from sys_days{y_/m_/last} by the +// number of days d_ is offset from sys_days{y_/m_/last}.day(). Otherwise +// the value returned is unspecified. +// +// Remarks: A sys_days in the range [days{-12687428}, days{11248737}] which +// is converted to a year_month_day shall have the same value when +// converted back to a sys_days. +// +// [Example: +// static_assert(year_month_day{sys_days{2017y/January/0}} == 2016y/December/31); +// static_assert(year_month_day{sys_days{2017y/January/31}} == 2017y/January/31); +// static_assert(year_month_day{sys_days{2017y/January/32}} == 2017y/February/1); +// —end example] + +#include +#include +#include + +#include "test_macros.h" + +void RunTheExample() +{ + using namespace std::chrono; + + static_assert(year_month_day{sys_days{2017y/January/0}} == 2016y/December/31); + static_assert(year_month_day{sys_days{2017y/January/31}} == 2017y/January/31); + static_assert(year_month_day{sys_days{2017y/January/32}} == 2017y/February/1); +} + +int main() +{ + using year = std::chrono::year; + using month = std::chrono::month; + using day = std::chrono::day; + using sys_days = std::chrono::sys_days; + using days = std::chrono::days; + using year_month_day = std::chrono::year_month_day; + + ASSERT_NOEXCEPT(sys_days(std::declval())); + RunTheExample(); + + { + constexpr year_month_day ymd{year{1970}, month{1}, day{1}}; + constexpr sys_days sd{ymd}; + + static_assert( sd.time_since_epoch() == days{0}, ""); + static_assert( year_month_day{sd} == ymd, ""); // and back + } + + { + constexpr year_month_day ymd{year{2000}, month{2}, day{2}}; + constexpr sys_days sd{ymd}; + + static_assert( sd.time_since_epoch() == days{10957+32}, ""); + static_assert( year_month_day{sd} == ymd, ""); // and back + } + +// There's one more leap day between 1/1/40 and 1/1/70 +// when compared to 1/1/70 -> 1/1/2000 + { + constexpr year_month_day ymd{year{1940}, month{1}, day{2}}; + constexpr sys_days sd{ymd}; + + static_assert( sd.time_since_epoch() == days{-10957}, ""); + static_assert( year_month_day{sd} == ymd, ""); // and back + } + + { + year_month_day ymd{year{1939}, month{11}, day{29}}; + sys_days sd{ymd}; + + assert( sd.time_since_epoch() == days{-(10957+34)}); + assert( year_month_day{sd} == ymd); // and back + } + +} diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/day.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/day.pass.cpp index f68e3239f..db3369c6c 100644 --- a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/day.pass.cpp +++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/day.pass.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 -// XFAIL: * // // class year_month_day_last; @@ -29,15 +28,24 @@ int main() using month_day_last = std::chrono::month_day_last; using year_month_day_last = std::chrono::year_month_day_last; -// TODO: wait for calendar -// ASSERT_NOEXCEPT( std::declval().day()); -// ASSERT_SAME_TYPE(day, decltype(std::declval().day())); -// -// static_assert( year_month_day_last{}.day() == day{}, ""); + ASSERT_NOEXCEPT( std::declval().day()); + ASSERT_SAME_TYPE(day, decltype(std::declval().day())); - for (unsigned i = 1; i <= 12; ++i) - { - year_month_day_last ymd(year{1234}, month_day_last{month{i}}); - assert( static_cast(ymd.day()) == i); - } +// Some months have a 31st + static_assert( year_month_day_last{year{2020}, month_day_last{month{ 1}}}.day() == day{31}, ""); + static_assert( year_month_day_last{year{2020}, month_day_last{month{ 2}}}.day() == day{29}, ""); + static_assert( year_month_day_last{year{2020}, month_day_last{month{ 3}}}.day() == day{31}, ""); + static_assert( year_month_day_last{year{2020}, month_day_last{month{ 4}}}.day() == day{30}, ""); + static_assert( year_month_day_last{year{2020}, month_day_last{month{ 5}}}.day() == day{31}, ""); + static_assert( year_month_day_last{year{2020}, month_day_last{month{ 6}}}.day() == day{30}, ""); + static_assert( year_month_day_last{year{2020}, month_day_last{month{ 7}}}.day() == day{31}, ""); + static_assert( year_month_day_last{year{2020}, month_day_last{month{ 8}}}.day() == day{31}, ""); + static_assert( year_month_day_last{year{2020}, month_day_last{month{ 9}}}.day() == day{30}, ""); + static_assert( year_month_day_last{year{2020}, month_day_last{month{10}}}.day() == day{31}, ""); + static_assert( year_month_day_last{year{2020}, month_day_last{month{11}}}.day() == day{30}, ""); + static_assert( year_month_day_last{year{2020}, month_day_last{month{12}}}.day() == day{31}, ""); + + assert((year_month_day_last{year{2019}, month_day_last{month{ 2}}}.day() == day{28})); + assert((year_month_day_last{year{2020}, month_day_last{month{ 2}}}.day() == day{29})); + assert((year_month_day_last{year{2021}, month_day_last{month{ 2}}}.day() == day{28})); } diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_local_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_local_days.pass.cpp index 43a3ef203..45f1ac4ae 100644 --- a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_local_days.pass.cpp +++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_local_days.pass.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 -// XFAIL: * // // class year_month_day_last; @@ -24,13 +23,39 @@ int main() { using year = std::chrono::year; - using month = std::chrono::month; - using day = std::chrono::day; using month_day_last = std::chrono::month_day_last; using year_month_day_last = std::chrono::year_month_day_last; -// using sys_days = std::chrono::local_days; + using local_days = std::chrono::local_days; + using days = std::chrono::days; -// ASSERT_NOEXCEPT( static_cast(std::declval().year())); -// ASSERT_SAME_TYPE(year, decltype(static_cast(std::declval().year())); - assert(false); + ASSERT_NOEXCEPT( static_cast(std::declval())); + ASSERT_SAME_TYPE(local_days, decltype(static_cast(std::declval()))); + + { // Last day in Jan 1970 was the 31st + constexpr year_month_day_last ymdl{year{1970}, month_day_last{std::chrono::January}}; + constexpr local_days sd{ymdl}; + + static_assert(sd.time_since_epoch() == days{30}, ""); + } + + { + constexpr year_month_day_last ymdl{year{2000}, month_day_last{std::chrono::January}}; + constexpr local_days sd{ymdl}; + + static_assert(sd.time_since_epoch() == days{10957+30}, ""); + } + + { + constexpr year_month_day_last ymdl{year{1940}, month_day_last{std::chrono::January}}; + constexpr local_days sd{ymdl}; + + static_assert(sd.time_since_epoch() == days{-10957+29}, ""); + } + + { + year_month_day_last ymdl{year{1939}, month_day_last{std::chrono::November}}; + local_days sd{ymdl}; + + assert(sd.time_since_epoch() == days{-(10957+33)}); + } } diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_sys_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_sys_days.pass.cpp index 8c1b3131e..20aff6d1d 100644 --- a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_sys_days.pass.cpp +++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_sys_days.pass.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 -// XFAIL: * // // class year_month_day_last; @@ -24,13 +23,39 @@ int main() { using year = std::chrono::year; - using month = std::chrono::month; - using day = std::chrono::day; using month_day_last = std::chrono::month_day_last; using year_month_day_last = std::chrono::year_month_day_last; -// using sys_days = std::chrono::sys_days; + using sys_days = std::chrono::sys_days; + using days = std::chrono::days; -// ASSERT_NOEXCEPT( static_cast(std::declval().year())); -// ASSERT_SAME_TYPE(year, decltype(static_cast(std::declval().year())); - assert(false); + ASSERT_NOEXCEPT( static_cast(std::declval())); + ASSERT_SAME_TYPE(sys_days, decltype(static_cast(std::declval()))); + + { // Last day in Jan 1970 was the 31st + constexpr year_month_day_last ymdl{year{1970}, month_day_last{std::chrono::January}}; + constexpr sys_days sd{ymdl}; + + static_assert(sd.time_since_epoch() == days{30}, ""); + } + + { + constexpr year_month_day_last ymdl{year{2000}, month_day_last{std::chrono::January}}; + constexpr sys_days sd{ymdl}; + + static_assert(sd.time_since_epoch() == days{10957+30}, ""); + } + + { + constexpr year_month_day_last ymdl{year{1940}, month_day_last{std::chrono::January}}; + constexpr sys_days sd{ymdl}; + + static_assert(sd.time_since_epoch() == days{-10957+29}, ""); + } + + { + year_month_day_last ymdl{year{1939}, month_day_last{std::chrono::November}}; + sys_days sd{ymdl}; + + assert(sd.time_since_epoch() == days{-(10957+33)}); + } } diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.local_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.local_days.pass.cpp index dbc3c855a..a0b98abb7 100644 --- a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.local_days.pass.cpp +++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.local_days.pass.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 -// XFAIL: * // // class year_month_weekday; @@ -33,12 +32,64 @@ int main() { - using year = std::chrono::year; - using month = std::chrono::month; - using day = std::chrono::day; -// using local_days = std::chrono::local_days; + using year = std::chrono::year; + using days = std::chrono::days; + using local_days = std::chrono::local_days; + using weekday_indexed = std::chrono::weekday_indexed; using year_month_weekday = std::chrono::year_month_weekday; -// ASSERT_NOEXCEPT(year_month_weekday{std::declval()}); - assert(false); + ASSERT_NOEXCEPT(year_month_weekday{std::declval()}); + + { + constexpr local_days sd{}; // 1-Jan-1970 was a Thursday + constexpr year_month_weekday ymwd{sd}; + + static_assert( ymwd.ok(), ""); + static_assert( ymwd.year() == year{1970}, ""); + static_assert( ymwd.month() == std::chrono::January, ""); + static_assert( ymwd.weekday() == std::chrono::Thursday, ""); + static_assert( ymwd.index() == 1, ""); + static_assert( ymwd.weekday_indexed() == weekday_indexed{std::chrono::Thursday, 1}, ""); + static_assert( ymwd == year_month_weekday{local_days{ymwd}}, ""); // round trip + } + + { + constexpr local_days sd{days{10957+32}}; // 2-Feb-2000 was a Wednesday + constexpr year_month_weekday ymwd{sd}; + + static_assert( ymwd.ok(), ""); + static_assert( ymwd.year() == year{2000}, ""); + static_assert( ymwd.month() == std::chrono::February, ""); + static_assert( ymwd.weekday() == std::chrono::Wednesday, ""); + static_assert( ymwd.index() == 1, ""); + static_assert( ymwd.weekday_indexed() == weekday_indexed{std::chrono::Wednesday, 1}, ""); + static_assert( ymwd == year_month_weekday{local_days{ymwd}}, ""); // round trip + } + + + { + constexpr local_days sd{days{-10957}}; // 2-Jan-1940 was a Tuesday + constexpr year_month_weekday ymwd{sd}; + + static_assert( ymwd.ok(), ""); + static_assert( ymwd.year() == year{1940}, ""); + static_assert( ymwd.month() == std::chrono::January, ""); + static_assert( ymwd.weekday() == std::chrono::Tuesday, ""); + static_assert( ymwd.index() == 1, ""); + static_assert( ymwd.weekday_indexed() == weekday_indexed{std::chrono::Tuesday, 1}, ""); + static_assert( ymwd == year_month_weekday{local_days{ymwd}}, ""); // round trip + } + + { + local_days sd{days{-(10957+34)}}; // 29-Nov-1939 was a Wednesday + year_month_weekday ymwd{sd}; + + assert( ymwd.ok()); + assert( ymwd.year() == year{1939}); + assert( ymwd.month() == std::chrono::November); + assert( ymwd.weekday() == std::chrono::Wednesday); + assert( ymwd.index() == 5); + assert((ymwd.weekday_indexed() == weekday_indexed{std::chrono::Wednesday, 5})); + assert( ymwd == year_month_weekday{local_days{ymwd}}); // round trip + } } diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.sys_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.sys_days.pass.cpp index 52b3f712f..b9d3b6c62 100644 --- a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.sys_days.pass.cpp +++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.sys_days.pass.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 -// XFAIL: * // // class year_month_weekday; @@ -32,12 +31,64 @@ int main() { - using year = std::chrono::year; - using month = std::chrono::month; - using day = std::chrono::day; -// using sys_days = std::chrono::sys_days; + using year = std::chrono::year; + using days = std::chrono::days; + using sys_days = std::chrono::sys_days; + using weekday_indexed = std::chrono::weekday_indexed; using year_month_weekday = std::chrono::year_month_weekday; -// ASSERT_NOEXCEPT(year_month_weekday{std::declval()}); - assert(false); + ASSERT_NOEXCEPT(year_month_weekday{std::declval()}); + + { + constexpr sys_days sd{}; // 1-Jan-1970 was a Thursday + constexpr year_month_weekday ymwd{sd}; + + static_assert( ymwd.ok(), ""); + static_assert( ymwd.year() == year{1970}, ""); + static_assert( ymwd.month() == std::chrono::January, ""); + static_assert( ymwd.weekday() == std::chrono::Thursday, ""); + static_assert( ymwd.index() == 1, ""); + static_assert( ymwd.weekday_indexed() == weekday_indexed{std::chrono::Thursday, 1}, ""); + static_assert( ymwd == year_month_weekday{sys_days{ymwd}}, ""); // round trip + } + + { + constexpr sys_days sd{days{10957+32}}; // 2-Feb-2000 was a Wednesday + constexpr year_month_weekday ymwd{sd}; + + static_assert( ymwd.ok(), ""); + static_assert( ymwd.year() == year{2000}, ""); + static_assert( ymwd.month() == std::chrono::February, ""); + static_assert( ymwd.weekday() == std::chrono::Wednesday, ""); + static_assert( ymwd.index() == 1, ""); + static_assert( ymwd.weekday_indexed() == weekday_indexed{std::chrono::Wednesday, 1}, ""); + static_assert( ymwd == year_month_weekday{sys_days{ymwd}}, ""); // round trip + } + + + { + constexpr sys_days sd{days{-10957}}; // 2-Jan-1940 was a Tuesday + constexpr year_month_weekday ymwd{sd}; + + static_assert( ymwd.ok(), ""); + static_assert( ymwd.year() == year{1940}, ""); + static_assert( ymwd.month() == std::chrono::January, ""); + static_assert( ymwd.weekday() == std::chrono::Tuesday, ""); + static_assert( ymwd.index() == 1, ""); + static_assert( ymwd.weekday_indexed() == weekday_indexed{std::chrono::Tuesday, 1}, ""); + static_assert( ymwd == year_month_weekday{sys_days{ymwd}}, ""); // round trip + } + + { + sys_days sd{days{-(10957+34)}}; // 29-Nov-1939 was a Wednesday + year_month_weekday ymwd{sd}; + + assert( ymwd.ok()); + assert( ymwd.year() == year{1939}); + assert( ymwd.month() == std::chrono::November); + assert( ymwd.weekday() == std::chrono::Wednesday); + assert( ymwd.index() == 5); + assert((ymwd.weekday_indexed() == weekday_indexed{std::chrono::Wednesday, 5})); + assert( ymwd == year_month_weekday{sys_days{ymwd}}); // round trip + } } diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.year_month_day_last.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.year_month_day_last.pass.cpp deleted file mode 100644 index b873a1956..000000000 --- a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.year_month_day_last.pass.cpp +++ /dev/null @@ -1,41 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 -// XFAIL: * - -// -// class year_month_weekday; - -// constexpr year_month_weekday(const year_month_weekday_last& ymdl) noexcept; -// -// Effects: Constructs an object of type year_month_weekday by initializing -// y_ with ymdl.year(), m_ with ymdl.month(), and d_ with ymdl.day(). -// -// constexpr chrono::year year() const noexcept; -// constexpr chrono::month month() const noexcept; -// constexpr chrono::day day() const noexcept; -// constexpr bool ok() const noexcept; - -#include -#include -#include - -#include "test_macros.h" - -int main() -{ - using year = std::chrono::year; - using month = std::chrono::month; - using day = std::chrono::day; - using year_month_weekday_last = std::chrono::year_month_weekday_last; - using year_month_weekday = std::chrono::year_month_weekday; - - ASSERT_NOEXCEPT(year_month_weekday{std::declval()}); - -} diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.local_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.local_days.pass.cpp new file mode 100644 index 000000000..ef30ce526 --- /dev/null +++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.local_days.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// +// class year_month_weekday; + +// explicit constexpr operator local_days() const noexcept; +// +// Returns: If y_.ok() && m_.ok() && wdi_.weekday().ok(), returns a +// sys_days that represents the date (index() - 1) * 7 days after the first +// weekday() of year()/month(). If index() is 0 the returned sys_days +// represents the date 7 days prior to the first weekday() of +// year()/month(). Otherwise the returned value is unspecified. +// + +#include +#include +#include + +#include "test_macros.h" + +int main() +{ + using year = std::chrono::year; + using month = std::chrono::month; + using weekday_indexed = std::chrono::weekday_indexed; + using local_days = std::chrono::local_days; + using days = std::chrono::days; + using year_month_weekday = std::chrono::year_month_weekday; + + ASSERT_NOEXCEPT(local_days(std::declval())); + + { + constexpr year_month_weekday ymwd{year{1970}, month{1}, weekday_indexed{std::chrono::Thursday, 1}}; + constexpr local_days sd{ymwd}; + + static_assert( sd.time_since_epoch() == days{0}, ""); + static_assert( year_month_weekday{sd} == ymwd, ""); // and back + } + + { + constexpr year_month_weekday ymwd{year{2000}, month{2}, weekday_indexed{std::chrono::Wednesday, 1}}; + constexpr local_days sd{ymwd}; + + static_assert( sd.time_since_epoch() == days{10957+32}, ""); + static_assert( year_month_weekday{sd} == ymwd, ""); // and back + } + +// There's one more leap day between 1/1/40 and 1/1/70 +// when compared to 1/1/70 -> 1/1/2000 + { + constexpr year_month_weekday ymwd{year{1940}, month{1},weekday_indexed{std::chrono::Tuesday, 1}}; + constexpr local_days sd{ymwd}; + + static_assert( sd.time_since_epoch() == days{-10957}, ""); + static_assert( year_month_weekday{sd} == ymwd, ""); // and back + } + + { + year_month_weekday ymwd{year{1939}, month{11}, weekday_indexed{std::chrono::Wednesday, 5}}; + local_days sd{ymwd}; + + assert( sd.time_since_epoch() == days{-(10957+34)}); + assert( year_month_weekday{sd} == ymwd); // and back + } + +} diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.sys_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.sys_days.pass.cpp new file mode 100644 index 000000000..04986e50d --- /dev/null +++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.sys_days.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// +// class year_month_weekday; + +// constexpr operator sys_days() const noexcept; +// +// Returns: If y_.ok() && m_.ok() && wdi_.weekday().ok(), returns a +// sys_days that represents the date (index() - 1) * 7 days after the first +// weekday() of year()/month(). If index() is 0 the returned sys_days +// represents the date 7 days prior to the first weekday() of +// year()/month(). Otherwise the returned value is unspecified. +// + +#include +#include +#include + +#include "test_macros.h" + +int main() +{ + using year = std::chrono::year; + using month = std::chrono::month; + using weekday_indexed = std::chrono::weekday_indexed; + using sys_days = std::chrono::sys_days; + using days = std::chrono::days; + using year_month_weekday = std::chrono::year_month_weekday; + + ASSERT_NOEXCEPT(sys_days(std::declval())); + + { + constexpr year_month_weekday ymwd{year{1970}, month{1}, weekday_indexed{std::chrono::Thursday, 1}}; + constexpr sys_days sd{ymwd}; + + static_assert( sd.time_since_epoch() == days{0}, ""); + static_assert( year_month_weekday{sd} == ymwd, ""); // and back + } + + { + constexpr year_month_weekday ymwd{year{2000}, month{2}, weekday_indexed{std::chrono::Wednesday, 1}}; + constexpr sys_days sd{ymwd}; + + static_assert( sd.time_since_epoch() == days{10957+32}, ""); + static_assert( year_month_weekday{sd} == ymwd, ""); // and back + } + +// There's one more leap day between 1/1/40 and 1/1/70 +// when compared to 1/1/70 -> 1/1/2000 + { + constexpr year_month_weekday ymwd{year{1940}, month{1},weekday_indexed{std::chrono::Tuesday, 1}}; + constexpr sys_days sd{ymwd}; + + static_assert( sd.time_since_epoch() == days{-10957}, ""); + static_assert( year_month_weekday{sd} == ymwd, ""); // and back + } + + { + year_month_weekday ymwd{year{1939}, month{11}, weekday_indexed{std::chrono::Wednesday, 5}}; + sys_days sd{ymwd}; + + assert( sd.time_since_epoch() == days{-(10957+34)}); + assert( year_month_weekday{sd} == ymwd); // and back + } + +} diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_local_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_local_days.pass.cpp index 56009c422..45f1ac4ae 100644 --- a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_local_days.pass.cpp +++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_local_days.pass.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 -// XFAIL: * // // class year_month_day_last; @@ -24,12 +23,39 @@ int main() { using year = std::chrono::year; - using month = std::chrono::month; - using day = std::chrono::day; using month_day_last = std::chrono::month_day_last; using year_month_day_last = std::chrono::year_month_day_last; - using sys_days = std::chrono::local_days; + using local_days = std::chrono::local_days; + using days = std::chrono::days; - ASSERT_NOEXCEPT( static_cast(std::declval().year())); - ASSERT_SAME_TYPE(year, decltype(static_cast(std::declval().year())); + ASSERT_NOEXCEPT( static_cast(std::declval())); + ASSERT_SAME_TYPE(local_days, decltype(static_cast(std::declval()))); + + { // Last day in Jan 1970 was the 31st + constexpr year_month_day_last ymdl{year{1970}, month_day_last{std::chrono::January}}; + constexpr local_days sd{ymdl}; + + static_assert(sd.time_since_epoch() == days{30}, ""); + } + + { + constexpr year_month_day_last ymdl{year{2000}, month_day_last{std::chrono::January}}; + constexpr local_days sd{ymdl}; + + static_assert(sd.time_since_epoch() == days{10957+30}, ""); + } + + { + constexpr year_month_day_last ymdl{year{1940}, month_day_last{std::chrono::January}}; + constexpr local_days sd{ymdl}; + + static_assert(sd.time_since_epoch() == days{-10957+29}, ""); + } + + { + year_month_day_last ymdl{year{1939}, month_day_last{std::chrono::November}}; + local_days sd{ymdl}; + + assert(sd.time_since_epoch() == days{-(10957+33)}); + } } diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_sys_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_sys_days.pass.cpp index 47beca7d9..c5abe4ace 100644 --- a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_sys_days.pass.cpp +++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_sys_days.pass.cpp @@ -7,13 +7,13 @@ // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 -// XFAIL: * // -// class year_month_day_last; +// class year_month_weekday_last; // constexpr operator sys_days() const noexcept; -// Returns: sys_days{year()/month()/day()}. +// Returns: If ok() == true, returns a sys_days that represents the last weekday() +// of year()/month(). Otherwise the returned value is unspecified. #include #include @@ -21,16 +21,49 @@ #include "test_macros.h" +#include + int main() { - using year = std::chrono::year; - using month = std::chrono::month; - using day = std::chrono::day; - using month_day_last = std::chrono::month_day_last; - using year_month_day_last = std::chrono::year_month_day_last; - using sys_days = std::chrono::sys_days; + using year = std::chrono::year; + using month = std::chrono::month; + using year_month_weekday_last = std::chrono::year_month_weekday_last; + using sys_days = std::chrono::sys_days; + using days = std::chrono::days; + using weekday = std::chrono::weekday; + using weekday_last = std::chrono::weekday_last; - ASSERT_NOEXCEPT( static_cast(std::declval().year())); - ASSERT_SAME_TYPE(year, decltype(static_cast(std::declval().year())); + ASSERT_NOEXCEPT( static_cast(std::declval())); + ASSERT_SAME_TYPE(sys_days, decltype(static_cast(std::declval()))); + constexpr month January = std::chrono::January; + constexpr weekday Tuesday = std::chrono::Tuesday; + + { // Last Tuesday in Jan 1970 was the 27th + constexpr year_month_weekday_last ymwdl{year{1970}, January, weekday_last{Tuesday}}; + constexpr sys_days sd{ymwdl}; + + static_assert(sd.time_since_epoch() == days{26}, ""); + } + + { // Last Tuesday in Jan 2000 was the 25th + constexpr year_month_weekday_last ymwdl{year{2000}, January, weekday_last{Tuesday}}; + constexpr sys_days sd{ymwdl}; + + static_assert(sd.time_since_epoch() == days{10957+24}, ""); + } + + { // Last Tuesday in Jan 1940 was the 30th + constexpr year_month_weekday_last ymwdl{year{1940}, January, weekday_last{Tuesday}}; + constexpr sys_days sd{ymwdl}; + + static_assert(sd.time_since_epoch() == days{-10958+29}, ""); + } + + { // Last Tuesday in Nov 1939 was the 28th + year_month_weekday_last ymdl{year{1939}, std::chrono::November, weekday_last{Tuesday}}; + sys_days sd{ymdl}; + + assert(sd.time_since_epoch() == days{-(10957+35)}); + } } diff --git a/test/std/utilities/time/time.clock/time.clock.system/local_time.types.pass.cpp b/test/std/utilities/time/time.clock/time.clock.system/local_time.types.pass.cpp new file mode 100644 index 000000000..9f91ca744 --- /dev/null +++ b/test/std/utilities/time/time.clock/time.clock.system/local_time.types.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// struct local_t {}; +// template +// using local_time = time_point; +// using local_seconds = sys_time; +// using local_days = sys_time; + +// [Example: +// sys_seconds{sys_days{1970y/January/1}}.time_since_epoch() is 0s. +// sys_seconds{sys_days{2000y/January/1}}.time_since_epoch() is 946’684’800s, which is 10’957 * 86’400s. +// —end example] + + +#include +#include + +#include "test_macros.h" + +int main() +{ + using local_t = std::chrono::local_t; + using year = std::chrono::year; + + using seconds = std::chrono::seconds; + using minutes = std::chrono::minutes; + using days = std::chrono::days; + + using local_seconds = std::chrono::local_seconds; + using local_minutes = std::chrono::local_time; + using local_days = std::chrono::local_days; + + constexpr std::chrono::month January = std::chrono::January; + + ASSERT_SAME_TYPE(std::chrono::local_time, local_seconds); + ASSERT_SAME_TYPE(std::chrono::local_time, local_days); + +// Test the long form, too + ASSERT_SAME_TYPE(std::chrono::time_point, local_seconds); + ASSERT_SAME_TYPE(std::chrono::time_point, local_minutes); + ASSERT_SAME_TYPE(std::chrono::time_point, local_days); + +// Test some well known values + local_days d0 = local_days{year{1970}/January/1}; + local_days d1 = local_days{year{2000}/January/1}; + ASSERT_SAME_TYPE(decltype(d0.time_since_epoch()), days); + assert( d0.time_since_epoch().count() == 0); + assert( d1.time_since_epoch().count() == 10957); + + local_seconds s0{d0}; + local_seconds s1{d1}; + ASSERT_SAME_TYPE(decltype(s0.time_since_epoch()), seconds); + assert( s0.time_since_epoch().count() == 0); + assert( s1.time_since_epoch().count() == 946684800L); +} diff --git a/test/std/utilities/time/time.clock/time.clock.system/sys.time.types.pass.cpp b/test/std/utilities/time/time.clock/time.clock.system/sys.time.types.pass.cpp new file mode 100644 index 000000000..299e06818 --- /dev/null +++ b/test/std/utilities/time/time.clock/time.clock.system/sys.time.types.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// template +// using sys_time = time_point; +// using sys_seconds = sys_time; +// using sys_days = sys_time; + +// [Example: +// sys_seconds{sys_days{1970y/January/1}}.time_since_epoch() is 0s. +// sys_seconds{sys_days{2000y/January/1}}.time_since_epoch() is 946’684’800s, which is 10’957 * 86’400s. +// —end example] + + +#include +#include + +#include "test_macros.h" + +int main() +{ + using system_clock = std::chrono::system_clock; + using year = std::chrono::year; + + using seconds = std::chrono::seconds; + using minutes = std::chrono::minutes; + using days = std::chrono::days; + + using sys_seconds = std::chrono::sys_seconds; + using sys_minutes = std::chrono::sys_time; + using sys_days = std::chrono::sys_days; + + constexpr std::chrono::month January = std::chrono::January; + + ASSERT_SAME_TYPE(std::chrono::sys_time, sys_seconds); + ASSERT_SAME_TYPE(std::chrono::sys_time, sys_days); + +// Test the long form, too + ASSERT_SAME_TYPE(std::chrono::time_point, sys_seconds); + ASSERT_SAME_TYPE(std::chrono::time_point, sys_minutes); + ASSERT_SAME_TYPE(std::chrono::time_point, sys_days); + +// Test some well known values + sys_days d0 = sys_days{year{1970}/January/1}; + sys_days d1 = sys_days{year{2000}/January/1}; + ASSERT_SAME_TYPE(decltype(d0.time_since_epoch()), days); + assert( d0.time_since_epoch().count() == 0); + assert( d1.time_since_epoch().count() == 10957); + + sys_seconds s0{d0}; + sys_seconds s1{d1}; + ASSERT_SAME_TYPE(decltype(s0.time_since_epoch()), seconds); + assert( s0.time_since_epoch().count() == 0); + assert( s1.time_since_epoch().count() == 946684800L); +} From ef48e7bccee4f956744564e47b9c932e0605f7a8 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Fri, 11 Jan 2019 15:45:56 +0000 Subject: [PATCH 92/94] Don't use the form '2017y' in tests, since some gcc versions don't allow it git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350930 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../time.cal.ymd.members/op.local_days.pass.cpp | 6 +++--- .../time.cal.ymd/time.cal.ymd.members/op.sys_days.pass.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.local_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.local_days.pass.cpp index 720a1c800..a70fe30fc 100644 --- a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.local_days.pass.cpp +++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.local_days.pass.cpp @@ -40,9 +40,9 @@ void RunTheExample() { using namespace std::chrono; - static_assert(year_month_day{local_days{2017y/January/0}} == 2016y/December/31); - static_assert(year_month_day{local_days{2017y/January/31}} == 2017y/January/31); - static_assert(year_month_day{local_days{2017y/January/32}} == 2017y/February/1); + static_assert(year_month_day{local_days{year{2017}/January/0}} == year{2016}/December/31); + static_assert(year_month_day{local_days{year{2017}/January/31}} == year{2017}/January/31); + static_assert(year_month_day{local_days{year{2017}/January/32}} == year{2017}/February/1); } int main() diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.sys_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.sys_days.pass.cpp index da9865d9c..4e263bccc 100644 --- a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.sys_days.pass.cpp +++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.sys_days.pass.cpp @@ -40,9 +40,9 @@ void RunTheExample() { using namespace std::chrono; - static_assert(year_month_day{sys_days{2017y/January/0}} == 2016y/December/31); - static_assert(year_month_day{sys_days{2017y/January/31}} == 2017y/January/31); - static_assert(year_month_day{sys_days{2017y/January/32}} == 2017y/February/1); + static_assert(year_month_day{sys_days{year{2017}/January/0}} == year{2016}/December/31); + static_assert(year_month_day{sys_days{year{2017}/January/31}} == year{2017}/January/31); + static_assert(year_month_day{sys_days{year{2017}/January/32}} == year{2017}/February/1); } int main() From 7aafc4d66a52bf0c6f03db4b805b844b3c79dffa Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Fri, 11 Jan 2019 17:31:17 +0000 Subject: [PATCH 93/94] [libcxx] Call __count_bool_true for bitset count This patch aims to help clang with better information so it can inline __bit_reference count function usage for both std::biset. Current clang inliner can not infer that the passed typed will be used only to select the optimized variant, it evaluates the type argument and type check as a load plus compare (although later optimization phases correctly optimized this out). It is mainly to help llvm inliner to generate better code for std::bitset count for aarch64. It helps on both runtime and code size, since if inline decides that _VSTD::count should not be inlined the vectorization will create both aligned and unaligned variants (which add both code size and runtime costs) git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350936 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/bitset | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/bitset b/include/bitset index 6e28596d0..98947e027 100644 --- a/include/bitset +++ b/include/bitset @@ -991,7 +991,7 @@ inline size_t bitset<_Size>::count() const _NOEXCEPT { - return static_cast(_VSTD::count(base::__make_iter(0), base::__make_iter(_Size), true)); + return static_cast(__count_bool_true(base::__make_iter(0), _Size)); } template From 749373168df326e54446b407190fbd064bfee64f Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Fri, 11 Jan 2019 21:57:12 +0000 Subject: [PATCH 94/94] Change from a to a . Fixes PR#39871. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@350972 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/__tuple | 18 +++++++++--------- include/array | 4 ++-- include/tuple | 4 ++-- include/utility | 4 ++-- .../tuple_size_incomplete.fail.cpp | 8 ++++---- .../tuple_size_incomplete.pass.cpp | 4 ++-- .../tuple_size_structured_bindings.pass.cpp | 4 ++-- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/include/__tuple b/include/__tuple index 69d6ee961..3b23d78af 100644 --- a/include/__tuple +++ b/include/__tuple @@ -22,36 +22,36 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template class _LIBCPP_TEMPLATE_VIS tuple_size; +template struct _LIBCPP_TEMPLATE_VIS tuple_size; #if !defined(_LIBCPP_CXX03_LANG) template using __enable_if_tuple_size_imp = _Tp; template -class _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< +struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< const _Tp, typename enable_if::value>::type, integral_constant)>>> : public integral_constant::value> {}; template -class _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< +struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< volatile _Tp, typename enable_if::value>::type, integral_constant)>>> : public integral_constant::value> {}; template -class _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< +struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< const volatile _Tp, integral_constant)>>> : public integral_constant::value> {}; #else -template class _LIBCPP_TEMPLATE_VIS tuple_size : public tuple_size<_Tp> {}; -template class _LIBCPP_TEMPLATE_VIS tuple_size : public tuple_size<_Tp> {}; -template class _LIBCPP_TEMPLATE_VIS tuple_size : public tuple_size<_Tp> {}; +template struct _LIBCPP_TEMPLATE_VIS tuple_size : public tuple_size<_Tp> {}; +template struct _LIBCPP_TEMPLATE_VIS tuple_size : public tuple_size<_Tp> {}; +template struct _LIBCPP_TEMPLATE_VIS tuple_size : public tuple_size<_Tp> {}; #endif template class _LIBCPP_TEMPLATE_VIS tuple_element; @@ -165,7 +165,7 @@ template class _LIBCPP_TEMPLATE_VIS tuple; template struct __tuple_like > : true_type {}; template -class _LIBCPP_TEMPLATE_VIS tuple_size > +struct _LIBCPP_TEMPLATE_VIS tuple_size > : public integral_constant { }; @@ -291,7 +291,7 @@ public: template -class _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> > +struct _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> > : public integral_constant { }; diff --git a/include/array b/include/array index 8f4e111ac..56f688765 100644 --- a/include/array +++ b/include/array @@ -91,7 +91,7 @@ template template void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); // C++17 -template class tuple_size; +template struct tuple_size; template class tuple_element; template struct tuple_size>; template struct tuple_element>; @@ -430,7 +430,7 @@ swap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y) } template -class _LIBCPP_TEMPLATE_VIS tuple_size > +struct _LIBCPP_TEMPLATE_VIS tuple_size > : public integral_constant {}; template diff --git a/include/tuple b/include/tuple index 2e54a5f66..4cc69030b 100644 --- a/include/tuple +++ b/include/tuple @@ -84,8 +84,8 @@ template constexpr T make_from_tuple(Tuple&& t); // C++17 // 20.4.1.4, tuple helper classes: -template class tuple_size; // undefined -template class tuple_size>; +template struct tuple_size; // undefined +template struct tuple_size>; template inline constexpr size_t tuple_size_v = tuple_size::value; // C++17 template class tuple_element; // undefined diff --git a/include/utility b/include/utility index fb7f44705..3fa0bc4c7 100644 --- a/include/utility +++ b/include/utility @@ -103,7 +103,7 @@ swap(pair& x, pair& y) noexcept(noexcept(x.swap(y))); struct piecewise_construct_t { }; inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); -template class tuple_size; +template struct tuple_size; template class tuple_element; template struct tuple_size >; @@ -683,7 +683,7 @@ make_pair(_T1 __x, _T2 __y) #endif // _LIBCPP_CXX03_LANG template - class _LIBCPP_TEMPLATE_VIS tuple_size > + struct _LIBCPP_TEMPLATE_VIS tuple_size > : public integral_constant {}; template diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp index 818001833..05ff8a4df 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp @@ -12,7 +12,7 @@ // template class tuple; // template -// class tuple_size> +// struct tuple_size> // : public integral_constant { }; // UNSUPPORTED: c++98, c++03 @@ -26,19 +26,19 @@ struct Dummy2 {}; struct Dummy3 {}; template <> -class std::tuple_size { +struct std::tuple_size { public: static size_t value; }; template <> -class std::tuple_size { +struct std::tuple_size { public: static void value() {} }; template <> -class std::tuple_size {}; +struct std::tuple_size {}; int main() { diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp index ccdd48e4c..c4f2e52ab 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp @@ -12,7 +12,7 @@ // template class tuple; // template -// class tuple_size> +// struct tuple_size> // : public integral_constant { }; // XFAIL: gcc-4.9 @@ -31,7 +31,7 @@ struct Dummy1 {}; struct Dummy2 {}; namespace std { -template <> class tuple_size : public integral_constant {}; +template <> struct tuple_size : public integral_constant {}; } template diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp index 03fb78caa..a18b9fc89 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp @@ -12,7 +12,7 @@ // template class tuple; // template -// class tuple_size> +// struct tuple_size> // : public integral_constant { }; // UNSUPPORTED: c++98, c++03, c++11, c++14 @@ -129,7 +129,7 @@ void test_before_tuple_size_specialization() { } template <> -class std::tuple_size { +struct std::tuple_size { public: static const size_t value = 1; };