diff options
author | Dan Albert <danalbert@google.com> | 2019-01-16 10:05:47 -0800 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-01-16 10:05:47 -0800 |
commit | 44312eb8e9e9bd53070a123cc80966d79458b6ad (patch) | |
tree | a9059b15e2036c13521bcd81f5c21a08a906fe72 | |
parent | c6900002571b9687cbd57fd468dc5caeaba75058 (diff) | |
parent | e4b6d367d490a1498a8d1cef84c1f52752a8a0f9 (diff) | |
download | external_libcxx-44312eb8e9e9bd53070a123cc80966d79458b6ad.tar.gz external_libcxx-44312eb8e9e9bd53070a123cc80966d79458b6ad.tar.bz2 external_libcxx-44312eb8e9e9bd53070a123cc80966d79458b6ad.zip |
Merge to upstream r350972.
am: e4b6d367d4
Change-Id: I5d25f3049e395f1b66829140a87e6c94f68f5703
404 files changed, 8700 insertions, 1735 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/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 <array> +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <tuple> +#include <vector> + +#include "benchmark/benchmark.h" + +#include "CartesianBenchmarks.hpp" +#include "GenerateInput.hpp" + +namespace { + +template <typename I, typename N> +std::array<I, 10> every_10th_percentile_N(I first, N n) { + N step = n / 10; + std::array<I, 10> res; + + for (size_t i = 0; i < 10; ++i) { + res[i] = first; + std::advance(first, step); + } + + return res; +} + +template <class IntT> +struct TestIntBase { + static std::vector<IntT> generateInput(size_t size) { + std::vector<IntT> Res(size); + std::generate(Res.begin(), Res.end(), + [] { return getRandomInteger<IntT>(); }); + return Res; + } +}; + +struct TestInt32 : TestIntBase<std::int32_t> { + static constexpr const char* Name = "TestInt32"; +}; + +struct TestInt64 : TestIntBase<std::int64_t> { + static constexpr const char* Name = "TestInt64"; +}; + +struct TestUint32 : TestIntBase<std::uint32_t> { + static constexpr const char* Name = "TestUint32"; +}; + +struct TestMediumString { + static constexpr const char* Name = "TestMediumString"; + static constexpr size_t StringSize = 32; + + static std::vector<std::string> generateInput(size_t size) { + std::vector<std::string> Res(size); + std::generate(Res.begin(), Res.end(), [] { return getRandomString(StringSize); }); + return Res; + } +}; + +using AllTestTypes = std::tuple<TestInt32, TestInt64, TestUint32, TestMediumString>; + +struct LowerBoundAlg { + template <class I, class V> + 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 <class I, class V> + 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 <class I, class V> + std::pair<I, I> 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<LowerBoundAlg, UpperBoundAlg, EqualRangeAlg>; + +template <class Alg, class TestType> +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<size_t> Quantities = {1 << 8, 1 << 10, 1 << 20}; + makeCartesianProductBenchmark<PartitionPointBench, AllAlgs, AllTestTypes>( + Quantities); + benchmark::RunSpecifiedBenchmarks(); +} 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/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/docs/TestingLibcxx.rst b/docs/TestingLibcxx.rst index 43c0684dc..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=<bool> @@ -155,14 +154,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=<bool> - - **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="<list-of-args>" Specify additional compile flags as a space delimited string. 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/__config b/include/__config index ef69bf495..728387642 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 @@ -713,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 @@ -971,14 +977,14 @@ template <unsigned> 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__) @@ -1002,6 +1008,10 @@ template <unsigned> 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) @@ -1359,16 +1369,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/__hash_table b/include/__hash_table index c2f87aaaa..87d0b62d0 100644 --- a/include/__hash_table +++ b/include/__hash_table @@ -35,15 +35,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Key, class _Tp> struct __hash_value_type; -template <class _Key, class _Cp, class _Hash, - bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value> -class __unordered_map_hasher; - -template <class _Key, class _Cp, class _Pred, - bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value - > -class __unordered_map_equal; - #ifndef _LIBCPP_CXX03_LANG template <class _Tp> 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 <class _Key, class _Hash, class _Equal> +struct __enforce_unordered_container_requirements { #ifndef _LIBCPP_CXX03_LANG -template <class _Key, class _Hash, class _Equal, class _Alloc> -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 <class _Key, class _Value, class _Hash, class _Equal, class _Alloc> -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 <class _Key, class _Hash, class _Equal> +#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 <class _Key, class _Hash, class _Equal> +int __diagnose_unordered_container_requirements(void*); template <class _Tp, class _Hash, class _Equal, class _Alloc> 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/__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<char>; template <> struct char_traits<wchar_t>; +template <> struct char_traits<char8_t>; // c++20 } // std @@ -389,6 +390,102 @@ char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __ } +#ifndef _LIBCPP_NO_HAS_CHAR8_T + +template <> +struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t> +{ + 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<char8_t>::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<char8_t>::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<char8_t>::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/__tree b/include/__tree index aa7370bfb..814851085 100644 --- a/include/__tree +++ b/include/__tree @@ -40,10 +40,6 @@ template <class _Tp, class _VoidPtr> class __tree_node; template <class _Key, class _Value> struct __value_type; -template <class _Key, class _CP, class _Compare, - bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value> -class __map_value_compare; - template <class _Allocator> class __map_node_destructor; template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_iterator; template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_const_iterator; @@ -966,24 +962,12 @@ private: }; +template<class _Tp, class _Compare> #ifndef _LIBCPP_CXX03_LANG -template <class _Tp, class _Compare, class _Allocator> -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 <class _Key, class _Value, class _KeyComp, class _Alloc> -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 _Tp, class _Compare, class _Allocator> class __tree @@ -1855,10 +1839,6 @@ __tree<_Tp, _Compare, _Allocator>::~__tree() { static_assert((is_copy_constructible<value_compare>::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/__tuple b/include/__tuple index 69d6ee961..3b23d78af 100644 --- a/include/__tuple +++ b/include/__tuple @@ -22,36 +22,36 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size; +template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size; #if !defined(_LIBCPP_CXX03_LANG) template <class _Tp, class...> using __enable_if_tuple_size_imp = _Tp; template <class _Tp> -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<!is_volatile<_Tp>::value>::type, integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> : public integral_constant<size_t, tuple_size<_Tp>::value> {}; template <class _Tp> -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<!is_const<_Tp>::value>::type, integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> : public integral_constant<size_t, tuple_size<_Tp>::value> {}; template <class _Tp> -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<size_t, sizeof(tuple_size<_Tp>)>>> : public integral_constant<size_t, tuple_size<_Tp>::value> {}; #else -template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {}; -template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {}; -template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {}; +template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {}; +template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {}; +template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {}; #endif template <size_t _Ip, class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_element; @@ -165,7 +165,7 @@ template <class ..._Tp> class _LIBCPP_TEMPLATE_VIS tuple; template <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {}; template <class ..._Tp> -class _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> > +struct _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> > : public integral_constant<size_t, sizeof...(_Tp)> { }; @@ -291,7 +291,7 @@ public: template <class ..._Tp> -class _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> > +struct _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> > : public integral_constant<size_t, sizeof...(_Tp)> { }; 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 <typename _Integral> +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + is_integral<_Integral>::value, + _Integral +>::type +__half_positive(_Integral __value) +{ + return static_cast<_Integral>(static_cast<typename make_unsigned<_Integral>::type>(__value) / 2); +} + +template <typename _Tp> +_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 <class _Compare> @@ -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/include/array b/include/array index 8f4e111ac..56f688765 100644 --- a/include/array +++ b/include/array @@ -91,7 +91,7 @@ template <class T, size_t N> template <class T, size_t N > void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // C++17 -template <class T> class tuple_size; +template <class T> struct tuple_size; template <size_t I, class T> class tuple_element; template <class T, size_t N> struct tuple_size<array<T, N>>; template <size_t I, class T, size_t N> struct tuple_element<I, array<T, N>>; @@ -430,7 +430,7 @@ swap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y) } template <class _Tp, size_t _Size> -class _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> > +struct _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> > : public integral_constant<size_t, _Size> {}; template <size_t _Ip, class _Tp, size_t _Size> 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<size_t>(_VSTD::count(base::__make_iter(0), base::__make_iter(_Size), true)); + return static_cast<size_t>(__count_bool_true(base::__make_iter(0), _Size)); } template <size_t _Size> diff --git a/include/chrono b/include/chrono index e99e3c74c..96759f986 100644 --- a/include/chrono +++ b/include/chrono @@ -808,6 +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 @@ -1581,10 +1586,27 @@ typedef system_clock high_resolution_clock; #endif #if _LIBCPP_STD_VER > 17 +// [time.clock.file], type file_clock +using file_clock = _VSTD_FS::_FilesystemClock; -struct _LIBCPP_TYPE_VIS last_spec { explicit last_spec() = default; }; +template<class _Duration> +using file_time = time_point<file_clock, _Duration>; + + +template <class _Duration> +using sys_time = time_point<system_clock, _Duration>; +using sys_seconds = sys_time<seconds>; +using sys_days = sys_time<days>; + +struct local_t {}; +template<class Duration> +using local_time = time_point<local_t, Duration>; +using local_seconds = local_time<seconds>; +using local_days = local_time<days>; +struct _LIBCPP_TYPE_VIS last_spec { explicit last_spec() = default; }; + class _LIBCPP_TYPE_VIS day { private: unsigned char __d; @@ -1803,21 +1825,36 @@ private: unsigned char __wd; public: weekday() = default; - explicit inline constexpr weekday(unsigned __val) noexcept: __wd(static_cast<unsigned char>(__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<unsigned char>(__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<unsigned char>( + static_cast<unsigned>(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6) + ); +} + inline constexpr bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept { return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); } @@ -2212,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: @@ -2223,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::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; + 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()}; } -// 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(); } + 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<unsigned>::digits >= 18, ""); + static_assert(std::numeric_limits<int>::digits >= 20 , ""); + const int __z = __d.count() + 719468; + const int __era = (__z >= 0 ? __z : __z - 146096) / 146097; + const unsigned __doe = static_cast<unsigned>(__z - __era * 146097); // [0, 146096] + const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399] + const int __yr = static_cast<int>(__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<unsigned>::digits >= 18, ""); + static_assert(std::numeric_limits<int>::digits >= 20 , ""); + + const int __yr = static_cast<int>(__y) - (__m <= February); + const unsigned __mth = static_cast<unsigned>(__m); + const unsigned __dy = static_cast<unsigned>(__d); + + const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400; + const unsigned __yoe = static_cast<unsigned>(__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<int>(__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(); } @@ -2338,16 +2418,30 @@ 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<unsigned>(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(); } @@ -2420,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; @@ -2429,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; @@ -2442,17 +2547,38 @@ 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<unsigned>(__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(); } @@ -2529,12 +2655,23 @@ 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(); } @@ -2689,6 +2826,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<rep, period> 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<rep> __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<rep> __secs; + return time_point(__secs(__t)); + } +}; +_LIBCPP_END_NAMESPACE_FILESYSTEM +#endif // !_LIBCPP_CXX03_LANG + _LIBCPP_POP_MACROS #endif // _LIBCPP_CHRONO diff --git a/include/deque b/include/deque index 414c7a859..6f7d04be5 100644 --- a/include/deque +++ b/include/deque @@ -150,6 +150,11 @@ template <class T, class Allocator> void swap(deque<T,Allocator>& x, deque<T,Allocator>& y) noexcept(noexcept(x.swap(y))); +template <class T, class Allocator, class U> + void erase(deque<T, Allocator>& c, const U& value); // C++20 +template <class T, class Allocator, class Predicate> + void erase_if(deque<T, Allocator>& c, Predicate pred); // C++20 + } // std */ @@ -987,7 +992,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<allocator_type>::value); #endif protected: @@ -1156,7 +1161,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<allocator_type>::value) #endif { @@ -2342,7 +2347,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 +2609,7 @@ template <class _Tp, class _Allocator> 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 +2860,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<allocator_type>::value) #endif { @@ -2927,6 +2933,19 @@ swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y) __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Tp, class _Allocator, class _Up> +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 <class _Tp, class _Allocator, class _Predicate> +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/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 "<experimental/any> has been removed. Use <any> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/any> has been removed. Use <any> instead.") +#else +# warning "<experimental/any> has been removed. Use <any> 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 "<experimental/chrono> has been removed. Use <chrono> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/chrono> has been removed. Use <chrono> instead.") +#else +# warning "<experimental/chrono> has been removed. Use <chrono> 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 "<experimental/numeric> has been removed. Use <numeric> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/numeric> has been removed. Use <numeric> instead.") +#else +# warning "<experimental/numeric> has been removed. Use <numeric> 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 "<experimental/optional> has been removed. Use <optional> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/optional> has been removed. Use <optional> instead.") +#else +# warning "<experimental/optional> has been removed. Use <optional> 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 "<experimental/ratio> has been removed. Use <ratio> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/ratio> has been removed. Use <ratio> instead.") +#else +# warning "<experimental/ratio> has been removed. Use <ratio> 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 "<experimental/string_view> has been removed. Use <string_view> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/string_view> has been removed. Use <string_view> instead.") +#else +# warning "<experimental/string_view> has been removed. Use <string_view> 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 "<experimental/system_error> has been removed. Use <system_error> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/system_error> has been removed. Use <system_error> instead.") +#else +# warning "<experimental/system_error> has been removed. Use <system_error> 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 "<experimental/tuple> has been removed. Use <tuple> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/tuple> has been removed. Use <tuple> instead.") +#else +# warning "<experimental/tuple> has been removed. Use <tuple> instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_TUPLE diff --git a/include/filesystem b/include/filesystem index 339bb252f..af713a063 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<rep, period> 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<rep> __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<rep> __secs; - return time_point(__secs(__t)); - } -}; - typedef chrono::time_point<_FilesystemClock> file_time_type; struct _LIBCPP_TYPE_VIS space_info { @@ -1181,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 { @@ -1197,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 <class _Source> _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_pathable<_Source>::value, path>::type 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 <class T, class Allocator> void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y) noexcept(noexcept(x.swap(y))); +template <class T, class Allocator, class U> + void erase(forward_list<T, Allocator>& c, const U& value); // C++20 +template <class T, class Allocator, class Predicate> + void erase_if(forward_list<T, Allocator>& 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 <class _Tp, class _Allocator, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) +{ __c.remove_if(__pred); } + +template <class _Tp, class _Allocator, class _Up> +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/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/include/functional b/include/functional index 1bddb9fad..1fb44f271 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 _Fp, class _Ap, class _FB> class __alloc_func; + +template <class _Fp, class _Ap, class _Rp, class... _ArgTypes> +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 _Fp> class __base; template<class _Rp, class ..._ArgTypes> @@ -1494,37 +1569,37 @@ public: #endif // _LIBCPP_NO_RTTI }; +// __func implements __base for a given functor type. + template<class _FD, class _Alloc, class _FB> class __func; template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 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<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 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<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT { - __f_.~__compressed_pair<_Fp, _Alloc>(); + __f_.destroy(); } template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> @@ -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<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> _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,493 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT #endif // _LIBCPP_NO_RTTI +// __value_func creates a value-type from a __func. + +template <class _Fp> class __value_func; + +template <class _Rp, class... _ArgTypes> 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 <class _Fp, class _Alloc> + _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<sizeof(__buf_)>::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 <typename _Tp> + _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT + { + if (__f_ == 0) + return 0; + return (const _Tp*)__f_->target(typeid(_Tp)); + } +#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 <typename _Fun> +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 <typename _Fun> + _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 <typename _Fun> static void* __large_clone(const void* __s) + { + const _Fun* __f = static_cast<const _Fun*>(__s); + return __f->__clone(); + } + + template <typename _Fun> static void __large_destroy(void* __s) + { + typedef allocator_traits<typename _Fun::_Alloc> __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 <typename _Fun> + _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 <typename _Fun> + _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 <typename _Tp> +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 <class _Fp> struct __policy_invoker; + +template <class _Rp, class... _ArgTypes> +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 <typename _Fun> + _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 <typename _Fun> + 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 _Fp> class __policy_func; + +template <class _Rp, class... _ArgTypes> 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 <class _Fp, class _Alloc> + _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 <typename _Tp> + _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<const _Tp*>(__buf_.__large); + else + return reinterpret_cast<const _Tp*>(&__buf_.__small); + } +#endif // _LIBCPP_NO_RTTI +}; + } // __function template<class _Rp, class ..._ArgTypes> @@ -1604,13 +2165,13 @@ 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_; +#ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION + typedef __function::__value_func<_Rp(_ArgTypes...)> __func; +#else + typedef __function::__policy_func<_Rp(_ArgTypes...)> __func; +#endif - _LIBCPP_NO_CFI static __base *__as_base(void *p) { - return reinterpret_cast<__base*>(p); - } + __func __f_; template <class _Fp, bool = __lazy_and< integral_constant<bool, !is_same<__uncvref_t<_Fp>, function>::value>, @@ -1637,9 +2198,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<class _Fp, class = _EnableIfCallable<_Fp>> @@ -1648,10 +2209,10 @@ public: #if _LIBCPP_STD_VER <= 14 template<class _Alloc> _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&) _NOEXCEPT : __f_(0) {} + function(allocator_arg_t, const _Alloc&) _NOEXCEPT {} template<class _Alloc> _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT : __f_(0) {} + function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} template<class _Alloc> function(allocator_arg_t, const _Alloc&, const function&); template<class _Alloc> @@ -1680,7 +2241,9 @@ public: // function capacity: _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return __f_;} + _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT { + return static_cast<bool>(__f_); + } // deleted overloads close possible hole in the type system template<class _R2, class... _ArgTypes2> @@ -1700,125 +2263,38 @@ public: }; template<class _Rp, class ..._ArgTypes> -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<class _Rp, class ..._ArgTypes> template <class _Alloc> 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<class _Rp, class ..._ArgTypes> +template <class _Rp, class... _ArgTypes> 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<class _Rp, class ..._ArgTypes> template <class _Alloc> 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<class _Rp, class ..._ArgTypes> +template <class _Rp, class... _ArgTypes> template <class _Fp, class> 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<class _Rp, class ..._ArgTypes> +template <class _Rp, class... _ArgTypes> template <class _Fp, class _Alloc, class> -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<class _Rp, class ..._ArgTypes> @@ -1833,19 +2309,7 @@ template<class _Rp, class ..._ArgTypes> 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 +2317,7 @@ template<class _Rp, class ..._ArgTypes> 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 +2331,20 @@ function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) } template<class _Rp, class ..._ArgTypes> -function<_Rp(_ArgTypes...)>::~function() -{ - if ((void *)__f_ == &__buf_) - __f_->destroy(); - else if (__f_) - __f_->destroy_deallocate(); -} +function<_Rp(_ArgTypes...)>::~function() {} template<class _Rp, class ..._ArgTypes> 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<sizeof(__buf_)>::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<class _Rp, class ..._ArgTypes> _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 +2353,7 @@ template<class _Rp, class ..._ArgTypes> 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<class _Rp, class ..._ArgTypes> @@ -1944,9 +2361,7 @@ template <typename _Tp> _Tp* function<_Rp(_ArgTypes...)>::target() _NOEXCEPT { - if (__f_ == 0) - return nullptr; - return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); + return (_Tp*)(__f_.template target<_Tp>()); } template<class _Rp, class ..._ArgTypes> @@ -1954,9 +2369,7 @@ template <typename _Tp> 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 @@ -2540,6 +2953,18 @@ template <class _Tp> using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; #endif // > C++17 +template <class _Container, class _Predicate> +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/iosfwd b/include/iosfwd index d4384859e..31f1902e5 100644 --- a/include/iosfwd +++ b/include/iosfwd @@ -18,6 +18,12 @@ namespace std { template<class charT> struct char_traits; +template<> struct char_traits<char>; +template<> struct char_traits<char8_t>; // C++20 +template<> struct char_traits<char16_t>; +template<> struct char_traits<char32_t>; +template<> struct char_traits<wchar_t>; + template<class T> class allocator; class ios_base; @@ -98,6 +104,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD class _LIBCPP_TYPE_VIS ios_base; template<class _CharT> struct _LIBCPP_TEMPLATE_VIS char_traits; +template<> struct char_traits<char>; +#ifndef _LIBCPP_NO_HAS_CHAR8_T +template<> struct char_traits<char8_t>; +#endif +template<> struct char_traits<char16_t>; +template<> struct char_traits<char32_t>; +template<> struct char_traits<wchar_t>; + template<class _Tp> class _LIBCPP_TEMPLATE_VIS allocator; template <class _CharT, class _Traits = char_traits<_CharT> > @@ -175,6 +189,9 @@ typedef basic_fstream<wchar_t> wfstream; template <class _State> class _LIBCPP_TEMPLATE_VIS fpos; typedef fpos<mbstate_t> streampos; typedef fpos<mbstate_t> wstreampos; +#ifndef _LIBCPP_NO_HAS_CHAR8_T +typedef fpos<mbstate_t> u8streampos; +#endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS typedef fpos<mbstate_t> u16streampos; typedef fpos<mbstate_t> u32streampos; diff --git a/include/istream b/include/istream index 8487dbeba..30ee4f4b8 100644 --- a/include/istream +++ b/include/istream @@ -160,6 +160,7 @@ template <class charT, class traits, class T> */ #include <__config> +#include <version> #include <ostream> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -1504,7 +1505,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<char>) _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<wchar_t>) _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_iostream<char>) 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<cv long double>; _LIBCPP_PUSH_MACROS #include <__undef_macros> +#include <version> _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/include/list b/include/list index 1a28c21ab..c69e31d93 100644 --- a/include/list +++ b/include/list @@ -169,6 +169,11 @@ template <class T, class Alloc> void swap(list<T,Alloc>& x, list<T,Alloc>& y) noexcept(noexcept(x.swap(y))); +template <class T, class Allocator, class U> + void erase(list<T, Allocator>& c, const U& value); // C++20 +template <class T, class Allocator, class Predicate> + void erase_if(list<T, Allocator>& 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 <class _Tp, class _Allocator, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred) +{ __c.remove_if(__pred); } + +template <class _Tp, class _Allocator, class _Up> +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/locale b/include/locale index 3a8dfbcf0..ac589d360 100644 --- a/include/locale +++ b/include/locale @@ -187,6 +187,7 @@ template <class charT> class messages_byname; #include <streambuf> #include <iterator> #include <limits> +#include <version> #ifndef __APPLE__ #include <cstdarg> #endif diff --git a/include/map b/include/map index d3c59f3c5..616bb46cf 100644 --- a/include/map +++ b/include/map @@ -254,6 +254,10 @@ void swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); +template <class Key, class T, class Compare, class Allocator, class Predicate> + void erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); // C++20 + + template <class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>> class multimap @@ -465,6 +469,9 @@ swap(multimap<Key, T, Compare, Allocator>& x, multimap<Key, T, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); +template <class Key, class T, class Compare, class Allocator, class Predicate> + void erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20 + } // std */ @@ -486,7 +493,8 @@ swap(multimap<Key, T, Compare, Allocator>& x, _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Key, class _CP, class _Compare, bool _IsSmall> +template <class _Key, class _CP, class _Compare, + bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value> class __map_value_compare : private _Compare { @@ -900,6 +908,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<typename allocator_type::value_type, value_type>::value), "Allocator::value_type must be same type as value_type"); @@ -1612,6 +1621,14 @@ swap(map<_Key, _Tp, _Compare, _Allocator>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + + template <class _Key, class _Tp, class _Compare = less<_Key>, class _Allocator = allocator<pair<const _Key, _Tp> > > class _LIBCPP_TEMPLATE_VIS multimap @@ -1626,6 +1643,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<typename allocator_type::value_type, value_type>::value), "Allocator::value_type must be same type as value_type"); @@ -2148,6 +2166,13 @@ swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate> +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/memory b/include/memory index 9fca9fe41..93f04c6fa 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 <class _Alloc, class _Pointer, class ..._Args> -struct __has_construct - : false_type -{ -}; - -#else // _LIBCPP_HAS_NO_VARIADICS +template <class _Alloc, class _Pointer, class _Tp, class = void> +struct __has_construct : std::false_type {}; -template <class _Alloc, class _Pointer, class _Args> -struct __has_construct - : false_type -{ -}; +template <class _Alloc, class _Pointer, class _Tp> +struct __has_construct<_Alloc, _Pointer, _Tp, typename __void_t< + decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Pointer>(), _VSTD::declval<_Tp>())) +>::type> : std::true_type {}; -#endif // _LIBCPP_HAS_NO_VARIADICS +template <class _Alloc, class _Pointer, class = void> +struct __has_destroy : false_type {}; template <class _Alloc, class _Pointer> -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 <class _Alloc> struct __has_max_size @@ -1510,6 +1502,12 @@ struct __alloc_traits_difference_type<_Alloc, _Ptr, true> typedef typename _Alloc::difference_type type; }; +template <class _Tp> +struct __is_default_allocator : false_type {}; + +template <class _Tp> +struct __is_default_allocator<_VSTD::allocator<_Tp> > : true_type {}; + template <class _Alloc> struct _LIBCPP_TEMPLATE_VIS allocator_traits { @@ -1571,9 +1569,10 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits } template <class _Tp, class _A0> _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<allocator_type, _Tp*, const _A0&>(), + __a, __p, __a0); } template <class _Tp, class _A0, class _A1> _LIBCPP_INLINE_VISIBILITY @@ -1613,7 +1612,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)); } @@ -1622,7 +1621,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits static typename enable_if < - (is_same<allocator_type, allocator<_Tp> >::value + (__is_default_allocator<allocator_type>::value || !__has_construct<allocator_type, _Tp*, _Tp>::value) && is_trivially_move_constructible<_Tp>::value, void @@ -1647,23 +1646,25 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits construct(__a, _VSTD::__to_raw_pointer(__begin2), *__begin1); } - template <class _Tp> + template <class _SourceTp, class _DestTp, + class _RawSourceTp = typename remove_const<_SourceTp>::type, + class _RawDestTp = typename remove_const<_DestTp>::type> _LIBCPP_INLINE_VISIBILITY static typename enable_if < - (is_same<allocator_type, allocator<_Tp> >::value - || !__has_construct<allocator_type, _Tp*, _Tp>::value) && - is_trivially_move_constructible<_Tp>::value, + is_trivially_move_constructible<_DestTp>::value && + is_same<_RawSourceTp, _RawDestTp>::value && + (__is_default_allocator<allocator_type>::value || + !__has_construct<allocator_type, _DestTp*, _SourceTp&>::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; } } @@ -1686,7 +1687,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits static typename enable_if < - (is_same<allocator_type, allocator<_Tp> >::value + (__is_default_allocator<allocator_type>::value || !__has_construct<allocator_type, _Tp*, _Tp>::value) && is_trivially_move_constructible<_Tp>::value, void @@ -1721,6 +1722,19 @@ private: { ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...); } +#else // _LIBCPP_HAS_NO_VARIADICS + template <class _Tp, class _A0> + _LIBCPP_INLINE_VISIBILITY + static void __construct(true_type, allocator_type& __a, _Tp* __p, + const _A0& __a0) + {__a.construct(__p, __a0);} + template <class _Tp, class _A0> + _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 <class _Tp> 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 <class U = T> optional &operator=(U &&); template <class U> optional &operator=(const optional<U> &); template <class U> optional &operator=(optional<U> &&); diff --git a/include/ostream b/include/ostream index ef34f71c1..d700a369b 100644 --- a/include/ostream +++ b/include/ostream @@ -140,6 +140,7 @@ template <class charT, class traits, class T> #include <locale> #include <iterator> #include <bitset> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -1092,7 +1093,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x) use_facet<ctype<_CharT> >(__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<char>) _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<wchar_t>) #endif diff --git a/include/regex b/include/regex index b415903b2..5ac2c1ab4 100644 --- a/include/regex +++ b/include/regex @@ -996,6 +996,10 @@ public: static const char_class_type __regex_word = 0x8000; #elif defined(__mips__) && defined(__GLIBC__) static const char_class_type __regex_word = static_cast<char_class_type>(_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 diff --git a/include/set b/include/set index ccf785ab1..a0155f0b2 100644 --- a/include/set +++ b/include/set @@ -216,6 +216,9 @@ void swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); +template <class Key, class Compare, class Allocator, class Predicate> + void erase_if(set<Key, Compare, Allocator>& c, Predicate pred); // C++20 + template <class Key, class Compare = less<Key>, class Allocator = allocator<Key>> class multiset @@ -412,6 +415,9 @@ void swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); +template <class Key, class Compare, class Allocator, class Predicate> + void erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20 + } // std */ @@ -445,6 +451,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<typename allocator_type::value_type, value_type>::value), "Allocator::value_type must be same type as value_type"); @@ -911,6 +918,13 @@ swap(set<_Key, _Compare, _Allocator>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Key, class _Compare, class _Allocator, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + template <class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key> > class _LIBCPP_TEMPLATE_VIS multiset @@ -925,6 +939,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<typename allocator_type::value_type, value_type>::value), "Allocator::value_type must be same type as value_type"); @@ -1390,6 +1405,13 @@ swap(multiset<_Key, _Compare, _Allocator>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Key, class _Compare, class _Allocator, class _Predicate> +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/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<char>) _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<wchar_t>) diff --git a/include/string b/include/string index 31ad307e5..fb838d1e5 100644 --- a/include/string +++ b/include/string @@ -437,6 +437,11 @@ template<class charT, class traits, class Allocator> basic_istream<charT, traits>& getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str); +template<class charT, class traits, class Allocator, class U> +void erase(basic_string<charT, traits, Allocator>& c, const U& value); // C++20 +template<class charT, class traits, class Allocator, class Predicate> +void erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20 + typedef basic_string<char> string; typedef basic_string<wchar_t> wstring; typedef basic_string<char16_t> u16string; @@ -4170,11 +4175,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<char8_t> u8string; +#endif +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS typedef basic_string<char16_t> u16string; typedef basic_string<char32_t> u32string; - #endif // _LIBCPP_HAS_NO_UNICODE_CHARS _LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* __idx = 0, int __base = 10); @@ -4274,6 +4281,18 @@ getline(basic_istream<_CharT, _Traits>&& __is, #endif // _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER > 17 +template<class _CharT, class _Traits, class _Allocator, class _Up> +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<class _CharT, class _Traits, class _Allocator, class _Predicate> +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<class _CharT, class _Traits, class _Allocator> @@ -4331,6 +4350,14 @@ inline namespace literals return basic_string<wchar_t> (__str, __len); } +#ifndef _LIBCPP_NO_HAS_CHAR8_T + inline _LIBCPP_INLINE_VISIBILITY + basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT + { + return basic_string<char8_t> (__str, __len); + } +#endif + inline _LIBCPP_INLINE_VISIBILITY basic_string<char16_t> 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<basic_string_view<_CharT, _Traits> >::type } typedef basic_string_view<char> string_view; +#ifndef _LIBCPP_NO_HAS_CHAR8_T +typedef basic_string_view<char8_t> u8string_view; +#endif typedef basic_string_view<char16_t> u16string_view; typedef basic_string_view<char32_t> u32string_view; typedef basic_string_view<wchar_t> wstring_view; @@ -802,6 +805,14 @@ inline namespace literals return basic_string_view<wchar_t> (__str, __len); } +#ifndef _LIBCPP_NO_HAS_CHAR8_T + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + basic_string_view<char8_t> operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT + { + return basic_string_view<char8_t> (__str, __len); + } +#endif + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT { diff --git a/include/tuple b/include/tuple index 2e54a5f66..4cc69030b 100644 --- a/include/tuple +++ b/include/tuple @@ -84,8 +84,8 @@ template <class T, class Tuple> constexpr T make_from_tuple(Tuple&& t); // C++17 // 20.4.1.4, tuple helper classes: -template <class T> class tuple_size; // undefined -template <class... T> class tuple_size<tuple<T...>>; +template <class T> struct tuple_size; // undefined +template <class... T> struct tuple_size<tuple<T...>>; template <class T> inline constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17 template <size_t I, class T> class tuple_element; // undefined 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<char> : public tr template <> struct __libcpp_is_integral<signed char> : public true_type {}; template <> struct __libcpp_is_integral<unsigned char> : public true_type {}; template <> struct __libcpp_is_integral<wchar_t> : public true_type {}; -#if _LIBCPP_STD_VER > 17 && defined(__cpp_char8_t) +#ifndef _LIBCPP_NO_HAS_CHAR8_T template <> struct __libcpp_is_integral<char8_t> : public true_type {}; #endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS diff --git a/include/typeinfo b/include/typeinfo index 92f1e2255..841153286 100644 --- a/include/typeinfo +++ b/include/typeinfo @@ -73,12 +73,8 @@ public: #include <vcruntime_typeinfo.h> #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 diff --git a/include/unordered_map b/include/unordered_map index 6f60749c9..6035b05dc 100644 --- a/include/unordered_map +++ b/include/unordered_map @@ -384,6 +384,12 @@ template <class Key, class T, class Hash, class Pred, class Alloc> unordered_multimap<Key, T, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y))); +template <class K, class T, class H, class P, class A, class Predicate> + void erase_if(unordered_set<K, T, H, P, A>& c, Predicate pred); // C++20 + +template <class K, class T, class H, class P, class A, class Predicate> + void erase_if(unordered_multiset<K, T, H, P, A>& c, Predicate pred); // C++20 + template <class Key, class T, class Hash, class Pred, class Alloc> bool operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x, @@ -414,7 +420,8 @@ template <class Key, class T, class Hash, class Pred, class Alloc> _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Key, class _Cp, class _Hash, bool _IsEmpty> +template <class _Key, class _Cp, class _Hash, + bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value> class __unordered_map_hasher : private _Hash { @@ -482,7 +489,8 @@ swap(__unordered_map_hasher<_Key, _Cp, _Hash, __b>& __x, __x.swap(__y); } -template <class _Key, class _Cp, class _Pred, bool _IsEmpty> +template <class _Key, class _Cp, class _Pred, + bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value> class __unordered_map_equal : private _Pred { @@ -845,6 +853,7 @@ public: typedef const value_type& const_reference; static_assert((is_same<value_type, typename allocator_type::value_type>::value), "Invalid allocator::value_type"); + static_assert(sizeof(__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), ""); private: typedef __hash_value_type<key_type, mapped_type> __value_type; @@ -1623,6 +1632,13 @@ swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, class _Predicate> +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 <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> bool operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, @@ -1667,6 +1683,7 @@ public: typedef const value_type& const_reference; static_assert((is_same<value_type, typename allocator_type::value_type>::value), "Invalid allocator::value_type"); + static_assert(sizeof(__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), ""); private: typedef __hash_value_type<key_type, mapped_type> __value_type; @@ -2239,6 +2256,13 @@ swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, class _Predicate> +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 <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> bool operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, diff --git a/include/unordered_set b/include/unordered_set index de23ca2a3..b4e61da89 100644 --- a/include/unordered_set +++ b/include/unordered_set @@ -339,6 +339,13 @@ template <class Value, class Hash, class Pred, class Alloc> unordered_multiset<Value, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y))); +template <class K, class T, class H, class P, class A, class Predicate> + void erase_if(unordered_set<K, T, H, P, A>& c, Predicate pred); // C++20 + +template <class K, class T, class H, class P, class A, class Predicate> + void erase_if(unordered_multiset<K, T, H, P, A>& c, Predicate pred); // C++20 + + template <class Value, class Hash, class Pred, class Alloc> bool operator==(const unordered_multiset<Value, Hash, Pred, Alloc>& x, @@ -384,6 +391,7 @@ public: typedef const value_type& const_reference; static_assert((is_same<value_type, typename allocator_type::value_type>::value), "Invalid allocator::value_type"); + static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), ""); private: typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table; @@ -933,6 +941,13 @@ swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Value, class _Hash, class _Pred, class _Alloc, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(unordered_set<_Value, _Hash, _Pred, _Alloc>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + template <class _Value, class _Hash, class _Pred, class _Alloc> bool operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, @@ -976,6 +991,7 @@ public: typedef const value_type& const_reference; static_assert((is_same<value_type, typename allocator_type::value_type>::value), "Invalid allocator::value_type"); + static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), ""); private: typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table; @@ -1495,6 +1511,13 @@ swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Value, class _Hash, class _Pred, class _Alloc, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + template <class _Value, class _Hash, class _Pred, class _Alloc> bool operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, diff --git a/include/utility b/include/utility index ddfa27e22..3fa0bc4c7 100644 --- a/include/utility +++ b/include/utility @@ -103,7 +103,7 @@ swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); struct piecewise_construct_t { }; inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); -template <class T> class tuple_size; +template <class T> struct tuple_size; template <size_t I, class T> class tuple_element; template <class T1, class T2> struct tuple_size<pair<T1, T2> >; @@ -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<first_type>::value && + is_nothrow_default_constructible<second_type>::value) + : first(), second() {} template <bool _Dummy = true, _EnableB< _CheckArgsDep<_Dummy>::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<first_type>::value && + is_nothrow_copy_constructible<second_type>::value) : first(__t1), second(__t2) {} template<bool _Dummy = true, _EnableB< @@ -423,6 +427,8 @@ struct _LIBCPP_TEMPLATE_VIS pair > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(_T1 const& __t1, _T2 const& __t2) + _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value && + is_nothrow_copy_constructible<second_type>::value) : first(__t1), second(__t2) {} template<class _U1, class _U2, _EnableB< @@ -430,6 +436,8 @@ struct _LIBCPP_TEMPLATE_VIS pair > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(_U1&& __u1, _U2&& __u2) + _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value && + is_nothrow_constructible<second_type, _U2>::value)) : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} template<class _U1, class _U2, _EnableB< @@ -437,6 +445,8 @@ struct _LIBCPP_TEMPLATE_VIS pair > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(_U1&& __u1, _U2&& __u2) + _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value && + is_nothrow_constructible<second_type, _U2>::value)) : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} template<class _U1, class _U2, _EnableB< @@ -444,6 +454,8 @@ struct _LIBCPP_TEMPLATE_VIS pair > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(pair<_U1, _U2> const& __p) + _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value && + is_nothrow_constructible<second_type, _U2 const&>::value)) : first(__p.first), second(__p.second) {} template<class _U1, class _U2, _EnableB< @@ -451,6 +463,8 @@ struct _LIBCPP_TEMPLATE_VIS pair > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(pair<_U1, _U2> const& __p) + _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value && + is_nothrow_constructible<second_type, _U2 const&>::value)) : first(__p.first), second(__p.second) {} template<class _U1, class _U2, _EnableB< @@ -458,6 +472,8 @@ struct _LIBCPP_TEMPLATE_VIS pair > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(pair<_U1, _U2>&&__p) + _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value && + is_nothrow_constructible<second_type, _U2&&>::value)) : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} template<class _U1, class _U2, _EnableB< @@ -465,6 +481,8 @@ struct _LIBCPP_TEMPLATE_VIS pair > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(pair<_U1, _U2>&& __p) + _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value && + is_nothrow_constructible<second_type, _U2&&>::value)) : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} template<class _Tuple, _EnableB< @@ -487,6 +505,8 @@ struct _LIBCPP_TEMPLATE_VIS pair _LIBCPP_INLINE_VISIBILITY pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) + _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value && + is_nothrow_constructible<second_type, _Args2...>::value)) : pair(__pc, __first_args, __second_args, typename __make_tuple_indices<sizeof...(_Args1)>::type(), typename __make_tuple_indices<sizeof...(_Args2) >::type()) {} @@ -663,7 +683,7 @@ make_pair(_T1 __x, _T2 __y) #endif // _LIBCPP_CXX03_LANG template <class _T1, class _T2> - class _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> > + struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> > : public integral_constant<size_t, 2> {}; template <size_t _Ip, class _T1, class _T2> diff --git a/include/variant b/include/variant index b33b1c40a..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 <class T> 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 <class T> variant& operator=(T&&) noexcept(see below); @@ -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 (...) { diff --git a/include/vector b/include/vector index 196ea70ea..edb6d3e09 100644 --- a/include/vector +++ b/include/vector @@ -261,6 +261,11 @@ template <class T, class Allocator> void swap(vector<T,Allocator>& x, vector<T,Allocator>& y) noexcept(noexcept(x.swap(y))); +template <class T, class Allocator, class U> + void erase(vector<T, Allocator>& c, const U& value); // C++20 +template <class T, class Allocator, class Predicate> + void erase_if(vector<T, Allocator>& 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 <class _Tp, class _Allocator, class _Up> +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 <class _Tp, class _Allocator, class _Predicate> +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 aca84f8ed..d6ccb138f 100644 --- a/include/version +++ b/include/version @@ -30,6 +30,8 @@ __cpp_lib_bit_cast 201806L <bit> __cpp_lib_bool_constant 201505L <type_traits> __cpp_lib_boyer_moore_searcher 201603L <functional> __cpp_lib_byte 201603L <cstddef> +__cpp_lib_char8_t 201811L <atomic> <filesystem> <istream> <limits> + <locale> <ostream> <string> <string_view> __cpp_lib_chrono 201611L <chrono> __cpp_lib_chrono_udls 201304L <chrono> __cpp_lib_clamp 201603L <algorithm> @@ -37,6 +39,9 @@ __cpp_lib_complex_udls 201309L <complex> __cpp_lib_concepts 201806L <concepts> __cpp_lib_constexpr_swap_algorithms 201806L <algorithm> __cpp_lib_enable_shared_from_this 201603L <memory> +__cpp_lib_erase_if 201811L <string> <deque> <forward_list> <list> + <vector> <map> <set> <unordered_map> + <unordered_set> __cpp_lib_exchange_function 201304L <utility> __cpp_lib_execution 201603L <execution> __cpp_lib_filesystem 201703L <filesystem> @@ -114,6 +119,10 @@ __cpp_lib_void_t 201411L <type_traits> #endif #if _LIBCPP_STD_VER > 17 +#ifndef _LIBCPP_NO_HAS_CHAR8_T +# define __cpp_lib_char8_t 201811L +#endif +#define __cpp_lib_erase_if 201811L #endif #endif // _LIBCPP_VERSIONH 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}) + + # 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(cxx_objects - PROPERTIES - COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}" -) + 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 $<TARGET_OBJECTS:cxx_static_objects>) + set(cxx_shared_sources $<TARGET_OBJECTS:cxx_shared_objects>) +else() + cxx_object_library(cxx_objects) + set(cxx_static_sources $<TARGET_OBJECTS:cxx_objects>) + set(cxx_shared_sources $<TARGET_OBJECTS:cxx_objects>) +endif() # Build the shared library. if (LIBCXX_ENABLE_SHARED) - add_library(cxx_shared SHARED $<TARGET_OBJECTS:cxx_objects>) + 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 $<TARGET_OBJECTS:cxx_objects>) + 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 diff --git a/src/filesystem/operations.cpp b/src/filesystem/operations.cpp index c9396b59c..e3bbc7b64 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; @@ -1454,7 +1478,7 @@ static int DetermineLexicalElementCount(PathParser PP) { auto Elem = *PP; if (Elem == "..") --Count; - else if (Elem != ".") + else if (Elem != "." && Elem != "") ++Count; } return Count; @@ -1468,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()) @@ -1501,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; @@ -1514,21 +1541,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) +static int CompareRootName(PathParser *LHS, PathParser *RHS) { + if (!LHS->inRootName() && !RHS->inRootName()) + return 0; + + 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; + 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; - ++PP; - ++PP2; + ++LHS; + ++RHS; } - if (PP.State == PP2.State && !PP) - return 0; - if (!PP) + return 0; +} + +static int CompareEndState(PathParser *LHS, PathParser *RHS) { + if (LHS->atEnd() && !RHS->atEnd()) return -1; - 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/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. +// +//===----------------------------------------------------------------------===// + +// <algorithm> + +// __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 <algorithm> +#include <cassert> +#include <limits> +#include <type_traits> + +#include "test_macros.h" +#include "user_defined_integral.hpp" + +namespace { + +template <class IntType, class UnderlyingType = IntType> +TEST_CONSTEXPR bool test(IntType max_v = IntType(std::numeric_limits<UnderlyingType>::max())) { + return std::__half_positive(max_v) == max_v / 2; +} + +} // namespace + +int main() +{ + { + assert(test<char>()); + assert(test<int>()); + assert(test<long>()); + assert((test<UserDefinedIntegral<int>, int>())); + assert(test<size_t>()); +#if !defined(_LIBCPP_HAS_NO_INT128) + assert(test<__int128_t>()); +#endif // !defined(_LIBCPP_HAS_NO_INT128) + } + +#if TEST_STD_VER >= 11 + { + static_assert(test<char>(), ""); + static_assert(test<int>(), ""); + static_assert(test<long>(), ""); + static_assert(test<size_t>(), ""); +#if !defined(_LIBCPP_HAS_NO_INT128) + static_assert(test<__int128_t>(), ""); +#endif // !defined(_LIBCPP_HAS_NO_INT128) + } +#endif // TEST_STD_VER >= 11 +} 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<BadCompare const&, int const&, int const&>::value, ""); static_assert(std::__invokable<BadCompare&, int const&, int const&>::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<int, BadCompare>; C s; 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..e4f5d0b01 --- /dev/null +++ b/test/libcxx/containers/sequences/deque/pop_back_empty.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. +// +//===----------------------------------------------------------------------===// + +// <deque> + +// pop_back() more than the number of elements in a deque + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include <cstdlib> +#include <deque> + + +int main() { + std::deque<int> q; + 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 new file mode 100644 index 000000000..388dfa4e1 --- /dev/null +++ b/test/libcxx/containers/sequences/vector/pop_back_empty.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. +// +//===----------------------------------------------------------------------===// + +// <vector> + +// pop_back() more than the number of elements in a vector + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include <cstdlib> +#include <vector> + + +int main() { + std::vector<int> v; + v.push_back(0); + v.pop_back(); + v.pop_back(); + std::exit(1); +} 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. +// +//===----------------------------------------------------------------------===// + +// <vector> + +// template <class InputIter> vector(InputIter first, InputIter last); + +#include <vector> +#include <cassert> + +#include "min_allocator.h" + +void test_ctor_under_alloc() { + int arr1[] = {42}; + int arr2[] = {1, 101, 42}; + { + typedef std::vector<int, cpp03_allocator<int> > 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<int, cpp03_overload_allocator<int> > 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. +// +//===----------------------------------------------------------------------===// + +// <vector> + +// template <class InputIter> vector(InputIter first, InputIter last, +// const allocator_type& a); + +#include <vector> +#include <cassert> + +#include "min_allocator.h" + +void test_ctor_under_alloc() { + int arr1[] = {42}; + int arr2[] = {1, 101, 42}; + { + typedef std::vector<int, cpp03_allocator<int> > 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<int, cpp03_overload_allocator<int> > 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/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 <unordered_set> #include <unordered_map> @@ -34,8 +34,10 @@ int main() { static_assert(!std::__invokable<BadEqual const&, int const&, int const&>::value, ""); static_assert(std::__invokable<BadEqual&, int const&, int const&>::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<int, BadHash, BadEqual>; 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 + +// <experimental/system_error> + +#include <experimental/system_error> + +// expected-error@experimental/system_error:* {{"<experimental/system_error> has been removed. Use <system_error> 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. +// +//===----------------------------------------------------------------------===// + +// <experimental/system_error> + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include <experimental/system_error> + +#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 + +// <experimental/numeric> + +#include <experimental/numeric> + +// expected-error@experimental/numeric:* {{"<experimental/numeric> has been removed. Use <numeric> 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. +// +//===----------------------------------------------------------------------===// + +// <experimental/numeric> + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include <experimental/numeric> + +#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 + +// <experimental/string_view> + +#include <experimental/string_view> + +// expected-error@experimental/string_view:* {{"<experimental/string_view> has been removed. Use <string_view> 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. +// +//===----------------------------------------------------------------------===// + +// <experimental/string_view> + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include <experimental/string_view> + +#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 + +// <experimental/any> + +#include <experimental/any> + +// expected-error@experimental/any:* {{"<experimental/any> has been removed. Use <any> 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. +// +//===----------------------------------------------------------------------===// + +// <experimental/any> + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include <experimental/any> + +#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 + +// <experimental/optional> + +#include <experimental/optional> + +// expected-error@experimental/optional:* {{"<experimental/optional> has been removed. Use <optional> 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. +// +//===----------------------------------------------------------------------===// + +// <experimental/optional> + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include <experimental/optional> + +#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 + +// <experimental/ratio> + +#include <experimental/ratio> + +// expected-error@experimental/ratio:* {{"<experimental/ratio> has been removed. Use <ratio> 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. +// +//===----------------------------------------------------------------------===// + +// <experimental/ratio> + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include <experimental/ratio> + +#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 + +// <experimental/chrono> + +#include <experimental/chrono> + +// expected-error@experimental/chrono:* {{"<experimental/chrono> has been removed. Use <chrono> 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. +// +//===----------------------------------------------------------------------===// + +// <experimental/chrono> + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include <experimental/chrono> + +#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 + +// <experimental/tuple> + +#include <experimental/tuple> + +// expected-error@experimental/tuple:* {{"<experimental/tuple> has been removed. Use <tuple> 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. +// +//===----------------------------------------------------------------------===// + +// <experimental/tuple> + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-W#warnings" +#endif +#include <experimental/tuple> + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() {} 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. +// +//===----------------------------------------------------------------------===// +// <fstream> + +// template <class charT, class traits = char_traits<charT> > +// class basic_fstream + +// close(); + +// Inspired by PR#38052 - std::fstream still good after closing and updating content + +#include <fstream> +#include <cassert> +#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()); +} 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/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp b/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp index 0e28d61ef..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,10 +14,6 @@ // definitions, which does not yet provide aligned allocation // XFAIL: LIBCXX-WINDOWS-FIXME -// Clang 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.12 - // 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. diff --git a/test/libcxx/memory/aligned_allocation_macro.pass.cpp b/test/libcxx/memory/aligned_allocation_macro.pass.cpp index 0e13b15f2..368076dee 100644 --- a/test/libcxx/memory/aligned_allocation_macro.pass.cpp +++ b/test/libcxx/memory/aligned_allocation_macro.pass.cpp @@ -9,13 +9,17 @@ // 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 +// 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 <new> 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 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 + // <optional> +// This test asserts the triviality of special member functions of optional<T> +// 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<T>& operator=(const optional& rhs); +// constexpr optional<T>& operator=(optional&& rhs) noexcept(see below); #include <optional> #include <type_traits> @@ -21,41 +31,27 @@ template <class T> struct SpecialMemberTest { using O = std::optional<T>; - static_assert(std::is_default_constructible_v<O>, - "optional is always default constructible."); - static_assert(std::is_copy_constructible_v<O> == std::is_copy_constructible_v<T>, - "optional<T> is copy constructible if and only if T is copy constructible."); - static_assert(std::is_move_constructible_v<O> == - (std::is_copy_constructible_v<T> || std::is_move_constructible_v<T>), - "optional<T> is move constructible if and only if T is copy or move constructible."); - static_assert(std::is_copy_assignable_v<O> == - (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>), - "optional<T> is copy assignable if and only if T is both copy " - "constructible and copy assignable."); - static_assert(std::is_move_assignable_v<O> == - ((std::is_move_constructible_v<T> && std::is_move_assignable_v<T>) || - (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>)), - "optional<T> 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<O> == std::is_trivially_destructible_v<T>, "optional<T> is trivially destructible if and only if T is."); + static_assert(std::is_trivially_copy_constructible_v<O> == std::is_trivially_copy_constructible_v<T>, "optional<T> is trivially copy constructible if and only if T is."); + static_assert(std::is_trivially_move_constructible_v<O> == std::is_trivially_move_constructible_v<T> || (!std::is_move_constructible_v<T> && std::is_trivially_copy_constructible_v<T>), "optional<T> 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<O> == (std::is_trivially_destructible_v<T> && std::is_trivially_copy_constructible_v<T> && std::is_trivially_copy_assignable_v<T>), "optional<T> 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<O> == (std::is_trivially_destructible_v<T> && ((std::is_trivially_move_constructible_v<T> && std::is_trivially_move_assignable_v<T>) || 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 + +// <utility> + +// template <class T1, class T2> struct pair + +// template<class U, class V> pair(U&& x, V&& y); + +#include <utility> + + +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<ExplicitT, ExplicitT>, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitT>, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitNothrowT>, int, int>::value, ""); + static_assert( std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitNothrowT>, int, int>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitT>, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitT>, int, int>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitNothrowT>, int, int>::value, ""); + static_assert( std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitNothrowT>, 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 + +// <utility> + +// template <class T1, class T2> struct pair + +// pair(const T1& x, const T2& y); + +#include <utility> + + +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<std::pair<ExplicitT, ExplicitT>, + ExplicitT const&, ExplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitT>, + ExplicitNothrowT const&, ExplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitNothrowT>, + ExplicitT const&, ExplicitNothrowT const&>::value, ""); + static_assert( std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitNothrowT>, + ExplicitNothrowT const&, ExplicitNothrowT const&>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitT>, + ImplicitT const&, ImplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitT>, + ImplicitNothrowT const&, ImplicitT const&>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitNothrowT>, + ImplicitT const&, ImplicitNothrowT const&>::value, ""); + static_assert( std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitNothrowT>, + 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 + +// <utility> + +// template <class T1, class T2> struct pair + +// template <class U, class V> EXPLICIT constexpr pair(const pair<U, V>& p); + +#include <utility> + + +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<ExplicitT, ExplicitT>, + std::pair<int, int> const&>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitT>, + std::pair<int, int> const&>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitNothrowT>, + std::pair<int, int> const&>::value, ""); + static_assert( std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitNothrowT>, + std::pair<int, int> const&>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitT>, + std::pair<int, int> const&>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitT>, + std::pair<int, int> const&>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitNothrowT>, + std::pair<int, int> const&>::value, ""); + static_assert( std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitNothrowT>, + std::pair<int, int> 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..2dbf5511d --- /dev/null +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/default.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 + +// <utility> + +// template <class T1, class T2> struct pair + +// constexpr pair(); + +#include <utility> +#include <type_traits> + + +struct ThrowingDefault { + ThrowingDefault() { } +}; + +struct NonThrowingDefault { + NonThrowingDefault() noexcept { } +}; + +int main() { + + static_assert(!std::is_nothrow_default_constructible<std::pair<ThrowingDefault, ThrowingDefault>>::value, ""); + static_assert(!std::is_nothrow_default_constructible<std::pair<NonThrowingDefault, ThrowingDefault>>::value, ""); + static_assert(!std::is_nothrow_default_constructible<std::pair<ThrowingDefault, NonThrowingDefault>>::value, ""); + static_assert( std::is_nothrow_default_constructible<std::pair<NonThrowingDefault, NonThrowingDefault>>::value, ""); +} 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..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<int, double> 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<std::pair<T1, T2>>"}} + // expected-error-re@utility:* {{static_assert failed{{( due to requirement '2U[L]{0,2} < 2')?}} "Index out of bounds in std::tuple_element<std::pair<T1, T2>>"}} } } 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 + +// <utility> + +// template <class T1, class T2> struct pair + +// template <class... Args1, class... Args2> +// pair(piecewise_construct_t, tuple<Args1...> first_args, +// tuple<Args2...> second_args); + +#include <tuple> +#include <type_traits> +#include <utility> + +#include "archetypes.hpp" + + +int main() { + using NonThrowingConvert = NonThrowingTypes::ConvertingType; + using ThrowingConvert = NonTrivialTypes::ConvertingType; + static_assert(!std::is_nothrow_constructible<std::pair<ThrowingConvert, ThrowingConvert>, + std::piecewise_construct_t, std::tuple<int, int>, std::tuple<long, long>>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<NonThrowingConvert, ThrowingConvert>, + std::piecewise_construct_t, std::tuple<int, int>, std::tuple<long, long>>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ThrowingConvert, NonThrowingConvert>, + std::piecewise_construct_t, std::tuple<int, int>, std::tuple<long, long>>::value, ""); + static_assert( std::is_nothrow_constructible<std::pair<NonThrowingConvert, NonThrowingConvert>, + std::piecewise_construct_t, std::tuple<int, int>, std::tuple<long, long>>::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 + +// <utility> + +// template <class T1, class T2> struct pair + +// template <class U, class V> pair(pair<U, V>&& p); + +#include <type_traits> +#include <utility> + + +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<ExplicitT, ExplicitT>, + std::pair<int, int>&&>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitT>, + std::pair<int, int>&&>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitNothrowT>, + std::pair<int, int>&&>::value, ""); + static_assert( std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitNothrowT>, + std::pair<int, int>&&>::value, ""); + } + { // implicit noexcept test + static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitT>, + std::pair<int, int>&&>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitT>, + std::pair<int, int>&&>::value, ""); + static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitNothrowT>, + std::pair<int, int>&&>::value, ""); + static_assert( std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitNothrowT>, + std::pair<int, int>&&>::value, ""); + } +} 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..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<int, double> 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 '2U[L]{0,2} < sizeof...\(_Types\)')?}} "Index out of bounds in std::variant_alternative<>"}} } } 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 <size_t ...Indices> struct make_variant_imp<std::integer_sequence<size_t, Indices...>> { - using type = std::variant<decltype((Indices, char(0)))...>; + template <size_t> using AlwaysChar = char; + using type = std::variant<AlwaysChar<Indices>...>; }; template <size_t N> 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 <class PopulationIterator, class SampleIterator> 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<input_iterator<int *>, output_iterator<int *> >(); 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 <algorithm> +#include <functional> #include <cassert> #include "test_macros.h" 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<void*>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE)); static_assert(std::atomic<std::nullptr_t>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE)); } + +int main() { run(); } 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 + +// <map> + +// template <class Key, class T, class Compare, class Allocator, class Predicate> +// void erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); + +#include <map> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list<int>; +template <typename M> +M make (Init vals) +{ + M ret; + for (int v : vals) + ret[v] = v + 10; + return ret; +} + +template <typename M, typename Pred> +void +test0(Init vals, Pred p, Init expected) +{ + M s = make<M> (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == make<M>(expected)); +} + +template <typename S> +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<S>({}, is1, {}); + + test0<S>({1}, is1, {}); + test0<S>({1}, is2, {1}); + + test0<S>({1,2}, is1, {2}); + test0<S>({1,2}, is2, {1}); + test0<S>({1,2}, is3, {1,2}); + + test0<S>({1,2,3}, is1, {2,3}); + test0<S>({1,2,3}, is2, {1,3}); + test0<S>({1,2,3}, is3, {1,2}); + test0<S>({1,2,3}, is4, {1,2,3}); + + test0<S>({1,2,3}, True, {}); + test0<S>({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test<std::map<int, int>>(); + test<std::map<int, int, std::less<int>, min_allocator<std::pair<const int, int>>>> (); + test<std::map<int, int, std::less<int>, test_allocator<std::pair<const int, int>>>> (); + + test<std::map<long, short>>(); + test<std::map<short, double>>(); +} + 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 + +// <map> + +// template <class Key, class T, class Compare, class Allocator, class Predicate> +// void erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); + +#include <map> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list<int>; +template <typename M> +M make (Init vals) +{ + M ret; + for (int v : vals) + ret.insert(typename M::value_type(v, v + 10)); + return ret; +} + +template <typename M, typename Pred> +void +test0(Init vals, Pred p, Init expected) +{ + M s = make<M> (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == make<M>(expected)); +} + +template <typename S> +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<S>({}, is1, {}); + + test0<S>({1}, is1, {}); + test0<S>({1}, is2, {1}); + + test0<S>({1,2}, is1, {2}); + test0<S>({1,2}, is2, {1}); + test0<S>({1,2}, is3, {1,2}); + test0<S>({1,1}, is1, {}); + test0<S>({1,1}, is3, {1,1}); + + test0<S>({1,2,3}, is1, {2,3}); + test0<S>({1,2,3}, is2, {1,3}); + test0<S>({1,2,3}, is3, {1,2}); + test0<S>({1,2,3}, is4, {1,2,3}); + + test0<S>({1,1,1}, is1, {}); + test0<S>({1,1,1}, is2, {1,1,1}); + test0<S>({1,1,2}, is1, {2}); + test0<S>({1,1,2}, is2, {1,1}); + test0<S>({1,1,2}, is3, {1,1,2}); + test0<S>({1,2,2}, is1, {2,2}); + test0<S>({1,2,2}, is2, {1}); + test0<S>({1,2,2}, is3, {1,2,2}); + + test0<S>({1,2,3}, True, {}); + test0<S>({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test<std::multimap<int, int>>(); + test<std::multimap<int, int, std::less<int>, min_allocator<std::pair<const int, int>>>> (); + test<std::multimap<int, int, std::less<int>, test_allocator<std::pair<const int, int>>>> (); + + test<std::multimap<long, short>>(); + test<std::multimap<short, double>>(); +} 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 + +// <set> + +// template <class T, class Compare, class Allocator, class Predicate> +// void erase_if(multiset<T, Compare, Allocator>& c, Predicate pred); + +#include <set> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class Pred> +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 <typename S> +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<std::multiset<int>>(); + test<std::multiset<int, std::less<int>, min_allocator<int>>> (); + test<std::multiset<int, std::less<int>, test_allocator<int>>> (); + + test<std::multiset<long>>(); + test<std::multiset<double>>(); +} 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 + +// <set> + +// template <class T, class Compare, class Allocator, class Predicate> +// void erase_if(set<T, Compare, Allocator>& c, Predicate pred); + +#include <set> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class Pred> +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 <typename S> +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<std::set<int>>(); + test<std::set<int, std::less<int>, min_allocator<int>>> (); + test<std::set<int, std::less<int>, test_allocator<int>>> (); + + test<std::set<long>>(); + test<std::set<double>>(); +} 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<T, 0> 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<decltype(c.data()), const T*>::value), ""); - assert(p != nullptr); + LIBCPP_ASSERT(p != nullptr); } { typedef std::max_align_t T; typedef std::array<T, 0> C; const C c = {}; const T* p = c.data(); - assert(p != nullptr); + LIBCPP_ASSERT(p != nullptr); std::uintptr_t pint = reinterpret_cast<std::uintptr_t>(p); assert(pint % TEST_ALIGNOF(std::max_align_t) == 0); } @@ -66,6 +66,6 @@ int main() typedef std::array<T, 0> 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<T, 0> 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<T, 0> C; const C c = {}; const T* p = c.data(); - assert(p != nullptr); + LIBCPP_ASSERT(p != nullptr); std::uintptr_t pint = reinterpret_cast<std::uintptr_t>(p); assert(pint % TEST_ALIGNOF(std::max_align_t) == 0); } 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..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<T, 3> 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 '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 c9fe695f9..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<T, 3> 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 '3U[L]{0,2} < 3U[L]{0,2}')?}} "Index out of bounds in std::tuple_element<> (std::array)"}} } } 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 <array> #include <cassert> +#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<T, 0> 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); } } 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 + +// <deque> + +// template <class T, class Allocator, class U> +// void erase(deque<T, Allocator>& c, const U& value); + + +#include <deque> +#include <optional> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class U> +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 <class S> +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<typename S::value_type>; + 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<std::deque<int>>(); + test<std::deque<int, min_allocator<int>>> (); + test<std::deque<int, test_allocator<int>>> (); + + test<std::deque<long>>(); + test<std::deque<double>>(); +} 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 + +// <deque> + +// template <class T, class Allocator, class Predicate> +// void erase_if(deque<T, Allocator>& c, Predicate pred); + +#include <deque> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class Pred> +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 <typename S> +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<std::deque<int>>(); + test<std::deque<int, min_allocator<int>>> (); + test<std::deque<int, test_allocator<int>>> (); + + test<std::deque<long>>(); + test<std::deque<double>>(); +} 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 + +// <forward_list> + +// template <class T, class Allocator, class U> +// void erase(forward_list<T, Allocator>& c, const U& value); + + +#include <forward_list> +#include <optional> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class U> +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 <class S> +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<typename S::value_type>; + 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<std::forward_list<int>>(); + test<std::forward_list<int, min_allocator<int>>> (); + test<std::forward_list<int, test_allocator<int>>> (); + + test<std::forward_list<long>>(); + test<std::forward_list<double>>(); +} 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 + +// <forward_list> + +// template <class T, class Allocator, class Predicate> +// void erase_if(forward_list<T, Allocator>& c, Predicate pred); + +#include <forward_list> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class Pred> +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 <typename S> +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<std::forward_list<int>>(); + test<std::forward_list<int, min_allocator<int>>> (); + test<std::forward_list<int, test_allocator<int>>> (); + + test<std::forward_list<long>>(); + test<std::forward_list<double>>(); +} 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 + +// <list> + +// template <class T, class Allocator, class U> +// void erase(list<T, Allocator>& c, const U& value); + + +#include <list> +#include <optional> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class U> +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 <class S> +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<typename S::value_type>; + 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<std::list<int>>(); + test<std::list<int, min_allocator<int>>> (); + test<std::list<int, test_allocator<int>>> (); + + test<std::list<long>>(); + test<std::list<double>>(); +} 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 + +// <list> + +// template <class T, class Allocator, class Predicate> +// void erase_if(list<T, Allocator>& c, Predicate pred); + +#include <list> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class Pred> +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 <typename S> +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<std::list<int>>(); + test<std::list<int, min_allocator<int>>> (); + test<std::list<int, test_allocator<int>>> (); + + test<std::list<long>>(); + test<std::list<double>>(); +} 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<bool> -// 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<bool> was not changed. + #include <vector> #include <cassert> @@ -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<typename C::allocator_type>::value), "" ); + LIBCPP_STATIC_ASSERT((noexcept(C(typename C::allocator_type())) == std::is_nothrow_copy_constructible<typename C::allocator_type>::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 // <vector> @@ -13,8 +14,9 @@ // noexcept(is_nothrow_default_constructible<allocator_type>::value); // This tests a conforming extension +// For vector<>, this was added to the standard by N4258, +// but vector<bool> was not changed. -// UNSUPPORTED: c++98, c++03 #include <vector> #include <cassert> @@ -40,7 +42,6 @@ int main() typedef std::vector<bool, test_allocator<bool>> C; static_assert(std::is_nothrow_default_constructible<C>::value, ""); } -#endif // _LIBCPP_VERSION { typedef std::vector<bool, other_allocator<bool>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); @@ -49,4 +50,5 @@ int main() typedef std::vector<bool, some_alloc<bool>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); } +#endif // _LIBCPP_VERSION } 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<int> 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<Y*> 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<uint32_t> 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(); } 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> // vector() // noexcept(is_nothrow_default_constructible<allocator_type>::value); -// This tests a conforming extension +// This *was* a conforming extension, but it was adopted in N4258. -// UNSUPPORTED: c++98, c++03 #include <vector> #include <cassert> 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 + +// <vector> + +// template <class T, class Allocator, class U> +// void erase(vector<T, Allocator>& c, const U& value); + + +#include <vector> +#include <optional> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class U> +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 <class S> +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<typename S::value_type>; + 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<std::vector<int>>(); + test<std::vector<int, min_allocator<int>>> (); + test<std::vector<int, test_allocator<int>>> (); + + test<std::vector<long>>(); + test<std::vector<double>>(); +} 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 + +// <vector> + +// template <class T, class Allocator, class Predicate> +// void erase_if(vector<T, Allocator>& c, Predicate pred); + +#include <vector> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class Pred> +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 <typename S> +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<std::vector<int>>(); + test<std::vector<int, min_allocator<int>>> (); + test<std::vector<int, test_allocator<int>>> (); + + test<std::vector<long>>(); + test<std::vector<double>>(); +} 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<Key, int> MapT; typedef MapT::iterator Iter; 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 + +// <unordered_map> + +// template <class Key, class T, class Hash, class Pred, class Allocator, class Predicate> +// void erase_if(unordered_map<Key, T, Hash, Pred, Allocator>& c, Predicate pred); + +#include <unordered_map> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list<int>; +template <typename M> +M make (Init vals) +{ + M ret; + for (int v : vals) + ret[v] = v + 10; + return ret; +} + +template <typename M, typename Pred> +void +test0(Init vals, Pred p, Init expected) +{ + M s = make<M> (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + M e = make<M>(expected); + assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end()))); +} + +template <typename S> +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<S>({}, is1, {}); + + test0<S>({1}, is1, {}); + test0<S>({1}, is2, {1}); + + test0<S>({1,2}, is1, {2}); + test0<S>({1,2}, is2, {1}); + test0<S>({1,2}, is3, {1,2}); + + test0<S>({1,2,3}, is1, {2,3}); + test0<S>({1,2,3}, is2, {1,3}); + test0<S>({1,2,3}, is3, {1,2}); + test0<S>({1,2,3}, is4, {1,2,3}); + + test0<S>({1,2,3}, True, {}); + test0<S>({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test<std::unordered_map<int, int>>(); + test<std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, int>>>> (); + test<std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int, int>>>> (); + + test<std::unordered_map<long, short>>(); + test<std::unordered_map<short, double>>(); +} + 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 <algorithm> #include <unordered_map> #include <string> #include <cassert> #include <cfloat> +#include <cmath> #include <cstddef> #include "test_macros.h" 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 <unordered_map> #include <string> +#include <set> #include <cassert> #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<std::string> 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<std::string> 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 <unordered_map> #include <string> +#include <set> #include <cassert> #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<std::string> 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<std::string> 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/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 + +// <unordered_map> + +// template <class Key, class T, class Hash, class Pred, class Allocator, class Predicate> +// void erase_if(unordered_multimap<Key, T, Hash, Pred, Allocator>& c, Predicate pred); + +#include <unordered_map> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list<int>; +template <typename M> +M make (Init vals) +{ + M ret; + for (int v : vals) + ret.insert(typename M::value_type(v, v + 10)); + return ret; +} + +template <typename M, typename Pred> +void +test0(Init vals, Pred p, Init expected) +{ + M s = make<M> (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + M e = make<M>(expected); + assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end()))); +} + +template <typename S> +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<S>({}, is1, {}); + + test0<S>({1}, is1, {}); + test0<S>({1}, is2, {1}); + + test0<S>({1,2}, is1, {2}); + test0<S>({1,2}, is2, {1}); + test0<S>({1,2}, is3, {1,2}); + test0<S>({1,1}, is1, {}); + test0<S>({1,1}, is3, {1,1}); + + test0<S>({1,2,3}, is1, {2,3}); + test0<S>({1,2,3}, is2, {1,3}); + test0<S>({1,2,3}, is3, {1,2}); + test0<S>({1,2,3}, is4, {1,2,3}); + + test0<S>({1,1,1}, is1, {}); + test0<S>({1,1,1}, is2, {1,1,1}); + test0<S>({1,1,2}, is1, {2}); + test0<S>({1,1,2}, is2, {1,1}); + test0<S>({1,1,2}, is3, {1,1,2}); + test0<S>({1,2,2}, is1, {2,2}); + test0<S>({1,2,2}, is2, {1}); + test0<S>({1,2,2}, is3, {1,2,2}); + + test0<S>({1,2,3}, True, {}); + test0<S>({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test<std::unordered_multimap<int, int>>(); + test<std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, int>>>> (); + test<std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int, int>>>> (); + + test<std::unordered_multimap<long, short>>(); + test<std::unordered_multimap<short, double>>(); +} 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 <unordered_map> #include <string> +#include <set> #include <cassert> #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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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 <unordered_map> #include <string> +#include <set> #include <cassert> #include <cfloat> #include <cmath> @@ -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<std::string> 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<std::string> 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<pair<const Key, T>>> // class unordered_multimap -// void rehash(size_type n); +// void reserve(size_type n); #include <unordered_map> #include <string> +#include <set> #include <cassert> #include "test_macros.h" @@ -26,10 +27,22 @@ template <class C> 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<std::string> 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<std::string> 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 <unordered_map> #include <string> +#include <set> #include <cassert> #include <cstddef> @@ -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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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)); 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 + +// <set> + +// template <class T, class Hash, class Compare, class Allocator, class Predicate> +// void erase_if(unordered_multiset<T, Hash, Compare, Allocator>& c, Predicate pred); + +#include <unordered_set> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list<int>; + +template <typename M> +M make (Init vals) +{ + M ret; + for (int v : vals) + ret.insert(v); + return ret; +} + +template <typename M, typename Pred> +void +test0(Init vals, Pred p, Init expected) +{ + M s = make<M> (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + M e = make<M>(expected); + assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end()))); +} + +template <typename S> +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, {}); + + test0<S>({1}, is1, {}); + test0<S>({1}, is2, {1}); + + test0<S>({1,2}, is1, {2}); + test0<S>({1,2}, is2, {1}); + test0<S>({1,2}, is3, {1,2}); + test0<S>({1,1}, is1, {}); + test0<S>({1,1}, is3, {1,1}); + + test0<S>({1,2,3}, is1, {2,3}); + test0<S>({1,2,3}, is2, {1,3}); + test0<S>({1,2,3}, is3, {1,2}); + test0<S>({1,2,3}, is4, {1,2,3}); + + test0<S>({1,1,1}, is1, {}); + test0<S>({1,1,1}, is2, {1,1,1}); + test0<S>({1,1,2}, is1, {2}); + test0<S>({1,1,2}, is2, {1,1}); + test0<S>({1,1,2}, is3, {1,1,2}); + test0<S>({1,2,2}, is1, {2,2}); + test0<S>({1,2,2}, is2, {1}); + test0<S>({1,2,2}, is3, {1,2,2}); + + test0<S>({1,2,3}, True, {}); + test0<S>({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test<std::unordered_multiset<int>>(); + test<std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>>> (); + test<std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, test_allocator<int>>> (); + + test<std::unordered_multiset<long>>(); + test<std::unordered_multiset<double>>(); +} 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 + +// <unordered_set> + +// template <class T, class Hash, class Compare, class Allocator, class Predicate> +// void erase_if(unorderd_set<T, Hash, Compare, Allocator>& c, Predicate pred); + +#include <unordered_set> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list<int>; + +template <typename M> +M make (Init vals) +{ + M ret; + for (int v : vals) + ret.insert(v); + return ret; +} + +template <typename M, typename Pred> +void +test0(Init vals, Pred p, Init expected) +{ + M s = make<M> (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + M e = make<M>(expected); + assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end()))); +} + + +template <typename S> +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, {}); + + test0<S>({1}, is1, {}); + test0<S>({1}, is2, {1}); + + test0<S>({1,2}, is1, {2}); + test0<S>({1,2}, is2, {1}); + test0<S>({1,2}, is3, {1,2}); + + test0<S>({1,2,3}, is1, {2,3}); + test0<S>({1,2,3}, is2, {1,3}); + test0<S>({1,2,3}, is3, {1,2}); + test0<S>({1,2,3}, is4, {1,2,3}); + + test0<S>({1,2,3}, True, {}); + test0<S>({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test<std::unordered_set<int>>(); + test<std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>>> (); + test<std::unordered_set<int, std::hash<int>, std::equal_to<int>, test_allocator<int>>> (); + + test<std::unordered_set<long>>(); + test<std::unordered_set<double>>(); +} diff --git a/test/std/containers/views/span.cons/default.fail.cpp b/test/std/containers/views/span.cons/default.fail.cpp index e30425cfe..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<int, 2> s; // expected-error@span:* {{static_assert failed "Can't default construct a statically sized span with size > 0"}} + std::span<int, 2> 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<int, 2>'}} 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 <cassert> #include "hexfloat.h" +#include "truncate_fp.h" // convertible to int/float/double/etc template <class T, int N=0> @@ -807,23 +808,31 @@ void test_atanh() assert(atanh(0) == 0); } -void test_cbrt() -{ - static_assert((std::is_same<decltype(cbrt((float)0)), float>::value), ""); - static_assert((std::is_same<decltype(cbrt((bool)0)), double>::value), ""); - static_assert((std::is_same<decltype(cbrt((unsigned short)0)), double>::value), ""); - static_assert((std::is_same<decltype(cbrt((int)0)), double>::value), ""); - static_assert((std::is_same<decltype(cbrt((unsigned int)0)), double>::value), ""); - static_assert((std::is_same<decltype(cbrt((long)0)), double>::value), ""); - static_assert((std::is_same<decltype(cbrt((unsigned long)0)), double>::value), ""); - static_assert((std::is_same<decltype(cbrt((long long)0)), double>::value), ""); - static_assert((std::is_same<decltype(cbrt((unsigned long long)0)), double>::value), ""); - static_assert((std::is_same<decltype(cbrt((double)0)), double>::value), ""); - static_assert((std::is_same<decltype(cbrt((long double)0)), long double>::value), ""); +void test_cbrt() { + static_assert((std::is_same<decltype(cbrt((float) 0)), float>::value), ""); + static_assert((std::is_same<decltype(cbrt((bool) 0)), double>::value), ""); + static_assert((std::is_same<decltype(cbrt((unsigned short) 0)), + double>::value), ""); + static_assert((std::is_same<decltype(cbrt((int) 0)), double>::value), ""); + static_assert((std::is_same<decltype(cbrt((unsigned int) 0)), + double>::value), ""); + static_assert((std::is_same<decltype(cbrt((long) 0)), double>::value), ""); + static_assert((std::is_same<decltype(cbrt((unsigned long) 0)), + double>::value), ""); + static_assert((std::is_same<decltype(cbrt((long long) 0)), double>::value), + ""); + static_assert((std::is_same<decltype(cbrt((unsigned long long) 0)), + double>::value), ""); + static_assert((std::is_same<decltype(cbrt((double) 0)), double>::value), + ""); + static_assert((std::is_same<decltype(cbrt((long double) 0)), + long double>::value), ""); static_assert((std::is_same<decltype(cbrtf(0)), float>::value), ""); static_assert((std::is_same<decltype(cbrtl(0)), long double>::value), ""); - static_assert((std::is_same<decltype(cbrt(Ambiguous())), Ambiguous>::value), ""); - assert(cbrt(1) == 1); + static_assert((std::is_same<decltype(cbrt(Ambiguous())), Ambiguous>::value), + ""); + assert(truncate_fp(cbrt(1)) == 1); + } void test_copysign() 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 // <uchar.h> 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<std::string> const& LHS, std::vector<std::string> 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<std::string> LHSElements; + std::vector<std::string> 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<std::string> 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/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/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 + +// <filesystem> + +#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 + +// <filesystem> + + +#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/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..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<TimeSpec, TimeSpec> 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<TimeSpec, TimeSpec> 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 { @@ -427,7 +430,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 @@ -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<TimeSpec, TimeSpec> 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)); } 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 9030b93a3..5737ab025 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,11 +159,12 @@ 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__) || defined(__ANDROID__) - // 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; - std::error_code expected_ec; +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || \ + defined(__ANDROID__) + // 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; + std::error_code expected_ec; #else // On linux symlink permissions are not supported. The error code should // be 'operation_not_supported' and the symlink permissions should be 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 ace8b7d69..4af824637 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 @@ -79,12 +79,12 @@ TEST_CASE(basic_test) { #endif {"/", "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"}, 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 <string> #include <type_traits> -#include <vector> -#include <iostream> #include <cassert> #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())); +} + +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)); } -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_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() 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 <iomanip> +#include <istream> #include <cassert> #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 <class charT> T9 get_time(struct tm* tmb, const charT* fmt); #include <iomanip> +#include <istream> #include <cassert> #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 <iomanip> +#include <ostream> #include <cassert> #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 <class charT> T10 put_time(const struct tm* tmb, const charT* fmt); #include <iomanip> +#include <ostream> #include <cassert> #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 <istream> +#include <limits> #include <cassert> template <class CharT> 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 <istream> +#include <limits> #include <cassert> template <class CharT> 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 - // <istream> // 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 - // <istream> // basic_istream<charT,traits>& 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..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 @@ -7,13 +7,14 @@ // //===----------------------------------------------------------------------===// +// 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 // 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 // <istream> 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..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 @@ -7,13 +7,14 @@ // //===----------------------------------------------------------------------===// +// 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 // 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 // <istream> 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..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 @@ -7,13 +7,14 @@ // //===----------------------------------------------------------------------===// +// 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 // 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 // <istream> 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..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 @@ -7,13 +7,14 @@ // //===----------------------------------------------------------------------===// +// 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 // 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 // <istream> 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 - // <istream> // basic_istream<charT,traits>& 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 - // <istream> // basic_istream<charT,traits>& 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 - // <istream> // 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 - // <istream> // basic_istream<charT,traits>& 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 // <istream> 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/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 <iomanip> +#include <istream> +#include <ostream> #include <cassert> template <class CharT> 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 <iomanip> +#include <istream> +#include <ostream> #include <cassert> template <class CharT> 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<charT> T4 setfill(charT c); #include <iomanip> +#include <ostream> #include <cassert> template <class CharT> 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 <iomanip> +#include <istream> +#include <ostream> #include <cassert> template <class CharT> 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 <iomanip> +#include <istream> +#include <ostream> #include <cassert> template <class CharT> 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 <iomanip> +#include <istream> +#include <ostream> #include <cassert> template <class CharT> 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.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/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 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/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..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,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:* 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:* 0-1 {{function pointer argument to '__builtin_launder' is not allowed}} } 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 <algorithm> +#include <cassert> #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 <any> +#include <cassert> #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 <array> +#include <cassert> #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..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 @@ -11,6 +11,7 @@ // <atomic> 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 <atomic> +#include <cassert> #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in <atomic> are defined. -#if _TEST_STD_VER > 14 +#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 +# 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 <bit> +#include <cassert> #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 <charconv> +#include <cassert> #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 <chrono> +#include <cassert> #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 <cmath> +#include <cassert> #include "test_macros.h" int main() 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. +// +//===----------------------------------------------------------------------===// +// +// <new> feature macros + +/* Constant Value + __cpp_lib_three_way_comparison 201711L + +*/ + +#include <compare> +#include <cassert> +#include "test_macros.h" + +int main() +{ +// ensure that the macros that are supposed to be defined in <compare> 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/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 <complex> +#include <cassert> #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 <concepts> +#include <cassert> #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 <cstddef> +#include <cassert> #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..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,17 +12,29 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_nonmember_container_access 201411L */ #include <deque> +#include <cassert> #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in <deque> 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/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 <exception> +#include <cassert> #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 <execution> +#include <cassert> #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..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 @@ -11,18 +11,30 @@ // <filesystem> feature macros /* Constant Value + __cpp_lib_char8_t 201811L __cpp_lib_filesystem 201703L */ #include <filesystem> +#include <cassert> #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in <filesystem> are defined. -#if _TEST_STD_VER > 14 +#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 +# 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..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 @@ -19,12 +20,23 @@ */ #include <forward_list> +#include <cassert> #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in <forward_list> 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/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 <functional> +#include <cassert> #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in <functional> 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 <iomanip> +#include <cassert> #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..7ede323ca --- /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. +// +//===----------------------------------------------------------------------===// +// +// <istream> feature macros + +/* Constant Value + __cpp_lib_char8_t 201811L + +*/ + +#include <istream> +#include <cassert> +#include "test_macros.h" + +int main() +{ +// ensure that the macros that are supposed to be defined in <istream> are defined. + +#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 +# 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 <iterator> +#include <cassert> #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..7f1869237 --- /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. +// +//===----------------------------------------------------------------------===// +// +// <limits> feature macros + +/* Constant Value + __cpp_lib_char8_t 201811L + +*/ + +#include <limits> +#include <cassert> +#include "test_macros.h" + +int main() +{ +// ensure that the macros that are supposed to be defined in <limits> are defined. + +#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 +# 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..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 @@ -19,12 +20,23 @@ */ #include <list> +#include <cassert> #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in <list> 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/locale.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp new file mode 100644 index 000000000..602273329 --- /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. +// +//===----------------------------------------------------------------------===// +// +// <locale> feature macros + +/* Constant Value + __cpp_lib_char8_t 201811L + +*/ + +#include <locale> +#include <cassert> +#include "test_macros.h" + +int main() +{ +// ensure that the macros that are supposed to be defined in <locale> are defined. + +#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 +# 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..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 @@ -20,12 +21,23 @@ */ #include <map> +#include <cassert> #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in <map> 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/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 <memory> +#include <cassert> #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 <memory_resource> +#include <cassert> #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 <mutex> +#include <cassert> #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..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,12 +10,14 @@ // <new> feature macros /* Constant Value + __cpp_lib_destroying_delete 201806L __cpp_lib_hardware_interference_size 201703L __cpp_lib_launder 201606L */ #include <new> +#include <cassert> #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 <numeric> +#include <cassert> #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 <optional> +#include <cassert> #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..668b39e32 --- /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. +// +//===----------------------------------------------------------------------===// +// +// <ostream> feature macros + +/* Constant Value + __cpp_lib_char8_t 201811L + +*/ + +#include <ostream> +#include <cassert> +#include "test_macros.h" + +int main() +{ +// ensure that the macros that are supposed to be defined in <ostream> are defined. + +#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 +# 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 <regex> +#include <cassert> #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 <scoped_allocator> +#include <cassert> #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..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 @@ -19,12 +20,23 @@ */ #include <set> +#include <cassert> #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in <set> 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/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 <shared_mutex> +#include <cassert> #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..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,8 @@ /* 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 __cpp_lib_string_view 201606L @@ -19,12 +21,33 @@ */ #include <string> +#include <cassert> #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in <string> 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"); +# 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..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 @@ -11,17 +11,29 @@ // <string_view> feature macros /* Constant Value + __cpp_lib_char8_t 201811L __cpp_lib_string_view 201606L */ #include <string_view> +#include <cassert> #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in <string_view> are defined. +#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 +# 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 <tuple> +#include <cassert> #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 <type_traits> +#include <cassert> #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in <type_traits> 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..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 @@ -19,12 +20,24 @@ */ #include <unordered_map> +#include <cassert> #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in <unordered_map> 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 b8e70636c..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,18 +12,30 @@ /* 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 */ #include <unordered_set> +#include <cassert> #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in <unordered_set> 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/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 <utility> +#include <cassert> #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 <variant> +#include <cassert> #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..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,18 +12,30 @@ /* 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 */ #include <vector> +#include <cassert> #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in <vector> 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/version.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp index e52c188bf..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 @@ -88,13 +90,14 @@ */ #include <version> +#include <cassert> #include "test_macros.h" int main() { // ensure that the macros that are supposed to be defined in <version> 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 +105,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 +113,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 +121,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 +129,16 @@ int main() # 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"); +# 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/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 // <locale> 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 <vector> #include <cassert> #include <cstddef> +#include <cstring> typedef std::codecvt<wchar_t, char, std::mbstate_t> F; 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.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 <locale> #include <ios> #include <cassert> +#include <limits> #include <streambuf> #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<std::ios_base::fmtflags>(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<const char*> iter = f.get(input_iterator<const char*>(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<const char*> iter = f.get(input_iterator<const char*>(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<const char*> iter = f.get(input_iterator<const char*>(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<const char*> iter = f.get(input_iterator<const char*>(str), 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<short>(); check_limits<unsigned short>(); 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..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 @@ -14,6 +14,7 @@ // iter_type get(iter_type in, iter_type end, ios_base&, // ios_base::iostate& err, unsigned int& v) const; +#include <limits> #include <locale> #include <ios> #include <cassert> @@ -148,7 +149,7 @@ void test_negate() { } } -int main(void) +int main() { test_neg_one<long>(); test_neg_one<long long>(); 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/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 // <locale> 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 // <locale> 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 // <locale> 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 <class T, int N=0> @@ -860,7 +861,7 @@ void test_cbrt() static_assert((std::is_same<decltype(std::cbrtf(0)), float>::value), ""); static_assert((std::is_same<decltype(std::cbrtl(0)), long double>::value), ""); static_assert((std::is_same<decltype(cbrt(Ambiguous())), Ambiguous>::value), ""); - assert(std::cbrt(1) == 1); + assert(truncate_fp(std::cbrt(1)) == 1); } void test_copysign() 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 - // <complex> // template<class T, class charT, class traits> 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 <random> #include <cassert> +#include "truncate_fp.h" + int main() { { @@ -22,35 +24,35 @@ int main() typedef float F; E r; F f = std::generate_canonical<F, 0>(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<F, 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<F, std::numeric_limits<F>::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<F, std::numeric_limits<F>::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<F, std::numeric_limits<F>::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<F, 0>(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<F, 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 double F; E r; F f = std::generate_canonical<F, std::numeric_limits<F>::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<F, std::numeric_limits<F>::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<F, std::numeric_limits<F>::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/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.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/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/test/std/re/re.traits/translate_nocase.pass.cpp b/test/std/re/re.traits/translate_nocase.pass.cpp index 33d365a9e..601da6b86 100644 --- a/test/std/re/re.traits/translate_nocase.pass.cpp +++ b/test/std/re/re.traits/translate_nocase.pass.cpp @@ -16,12 +16,6 @@ // REQUIRES: locale.en_US.UTF-8 -// XFAIL: with_system_cxx_lib=macosx10.7 -// XFAIL: with_system_cxx_lib=macosx10.8 - -// TODO: investigation needed -// XFAIL: linux-gnu - #include <regex> #include <cassert> @@ -47,8 +41,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<wchar_t> t; 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<std::string>(); test_hash_enabled_for_type<std::wstring>(); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test_hash_enabled_for_type<std::u8string>(); +#endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS test_hash_enabled_for_type<std::u16string>(); test_hash_enabled_for_type<std::u32string>(); 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<std::string>(); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test<std::u8string>(); +#endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS test<std::u16string>(); test<std::u32string>(); 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<decltype( "Hi"s), std::string>::value, "" ); -// This is changed by P0482 to return a std::u8string -#if TEST_STD_VER <= 17 - static_assert ( std::is_same<decltype( u8"Hi"s), std::string>::value, "" ); -#endif + static_assert ( std::is_same<decltype( u8"Hi"s), u8string>::value, "" ); static_assert ( std::is_same<decltype( L"Hi"s), std::wstring>::value, "" ); static_assert ( std::is_same<decltype( u"Hi"s), std::u16string>::value, "" ); static_assert ( std::is_same<decltype( U"Hi"s), std::u32string>::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() == 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 = "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 = ""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); + 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")); + 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<char8_t>{}}; + using S = decltype(s1); // what type did we get? + static_assert(std::is_same_v<S::value_type, char8_t>, ""); + static_assert(std::is_same_v<S::traits_type, std::char_traits<char8_t>>, ""); + static_assert(std::is_same_v<S::allocator_type, min_allocator<char8_t>>, ""); + 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<char16_t>{}}; 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<char8_t>{}}; + using S = decltype(s1); // what type did we get? + static_assert(std::is_same_v<S::value_type, char8_t>, ""); + static_assert(std::is_same_v<S::traits_type, std::char_traits<char8_t>>, ""); + static_assert(std::is_same_v<S::allocator_type, min_allocator<char8_t>>, ""); + 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<char16_t>{}}; 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/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 <type_traits> #include <cassert> +#include "test_macros.h" + #ifdef isalnum #error isalnum defined #endif @@ -71,33 +73,34 @@ int main() { - static_assert((std::is_same<decltype(std::isalnum(0)), int>::value), ""); - static_assert((std::is_same<decltype(std::isalpha(0)), int>::value), ""); - static_assert((std::is_same<decltype(std::isblank(0)), int>::value), ""); - static_assert((std::is_same<decltype(std::iscntrl(0)), int>::value), ""); - static_assert((std::is_same<decltype(std::isdigit(0)), int>::value), ""); - static_assert((std::is_same<decltype(std::isgraph(0)), int>::value), ""); - static_assert((std::is_same<decltype(std::islower(0)), int>::value), ""); - static_assert((std::is_same<decltype(std::isprint(0)), int>::value), ""); - static_assert((std::is_same<decltype(std::ispunct(0)), int>::value), ""); - static_assert((std::is_same<decltype(std::isspace(0)), int>::value), ""); - static_assert((std::is_same<decltype(std::isupper(0)), int>::value), ""); - static_assert((std::is_same<decltype(std::isxdigit(0)), int>::value), ""); - static_assert((std::is_same<decltype(std::tolower(0)), int>::value), ""); - static_assert((std::is_same<decltype(std::toupper(0)), int>::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 <cstring> #include <type_traits> +#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<decltype(std::memcpy(vp, vpc, s)), void*>::value), ""); - static_assert((std::is_same<decltype(std::memmove(vp, vpc, s)), void*>::value), ""); - static_assert((std::is_same<decltype(std::strcpy(cp, cpc)), char*>::value), ""); - static_assert((std::is_same<decltype(std::strncpy(cp, cpc, s)), char*>::value), ""); - static_assert((std::is_same<decltype(std::strcat(cp, cpc)), char*>::value), ""); - static_assert((std::is_same<decltype(std::strncat(cp, cpc, s)), char*>::value), ""); - static_assert((std::is_same<decltype(std::memcmp(vpc, vpc, s)), int>::value), ""); - static_assert((std::is_same<decltype(std::strcmp(cpc, cpc)), int>::value), ""); - static_assert((std::is_same<decltype(std::strncmp(cpc, cpc, s)), int>::value), ""); - static_assert((std::is_same<decltype(std::strcoll(cpc, cpc)), int>::value), ""); - static_assert((std::is_same<decltype(std::strxfrm(cp, cpc, s)), std::size_t>::value), ""); - static_assert((std::is_same<decltype(std::memchr(vp, 0, s)), void*>::value), ""); - static_assert((std::is_same<decltype(std::strchr(cp, 0)), char*>::value), ""); - static_assert((std::is_same<decltype(std::strcspn(cpc, cpc)), std::size_t>::value), ""); - static_assert((std::is_same<decltype(std::strpbrk(cp, cpc)), char*>::value), ""); - static_assert((std::is_same<decltype(std::strrchr(cp, 0)), char*>::value), ""); - static_assert((std::is_same<decltype(std::strspn(cpc, cpc)), std::size_t>::value), ""); - static_assert((std::is_same<decltype(std::strstr(cp, cpc)), char*>::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<decltype(std::strtok(cp, cpc)), char*>::value), ""); + ASSERT_SAME_TYPE(char*, decltype(std::strtok(cp, cpc))); #endif - static_assert((std::is_same<decltype(std::memset(vp, 0, s)), void*>::value), ""); - static_assert((std::is_same<decltype(std::strerror(0)), char*>::value), ""); - static_assert((std::is_same<decltype(std::strlen(cpc)), std::size_t>::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<decltype(std::memchr(vpc, 0, s)), const void*>::value), ""); - static_assert((std::is_same<decltype(std::strchr(cpc, 0)), const char*>::value), ""); - static_assert((std::is_same<decltype(std::strpbrk(cpc, cpc)), const char*>::value), ""); - static_assert((std::is_same<decltype(std::strrchr(cpc, 0)), const char*>::value), ""); - static_assert((std::is_same<decltype(std::strstr(cpc, cpc)), const char*>::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 <cuchar> +#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..116da936e 100644 --- a/test/std/strings/c.strings/cwchar.pass.cpp +++ b/test/std/strings/c.strings/cwchar.pass.cpp @@ -10,9 +10,12 @@ // <cwchar> #include <cwchar> +#include <ctime> #include <cstdarg> #include <type_traits> +#include "test_macros.h" + #ifndef NULL #error NULL not defined #endif @@ -50,80 +53,80 @@ int main() ((void)ns); // Prevent unused warning ((void)ws); // Prevent unused warning - static_assert((std::is_same<decltype(std::fwprintf(fp, L"")), int>::value), ""); - static_assert((std::is_same<decltype(std::fwscanf(fp, L"")), int>::value), ""); - static_assert((std::is_same<decltype(std::swprintf(ws, s, L"")), int>::value), ""); - static_assert((std::is_same<decltype(std::swscanf(L"", L"")), int>::value), ""); - static_assert((std::is_same<decltype(std::vfwprintf(fp, L"", va)), int>::value), ""); - static_assert((std::is_same<decltype(std::vfwscanf(fp, L"", va)), int>::value), ""); - static_assert((std::is_same<decltype(std::vswprintf(ws, s, L"", va)), int>::value), ""); - static_assert((std::is_same<decltype(std::vswscanf(L"", L"", va)), int>::value), ""); - static_assert((std::is_same<decltype(std::fgetwc(fp)), std::wint_t>::value), ""); - static_assert((std::is_same<decltype(std::fgetws(ws, 0, fp)), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::fputwc(L' ', fp)), std::wint_t>::value), ""); - static_assert((std::is_same<decltype(std::fputws(L"", fp)), int>::value), ""); - static_assert((std::is_same<decltype(std::fwide(fp, 0)), int>::value), ""); - static_assert((std::is_same<decltype(std::getwc(fp)), std::wint_t>::value), ""); - static_assert((std::is_same<decltype(std::putwc(L' ', fp)), std::wint_t>::value), ""); - static_assert((std::is_same<decltype(std::ungetwc(L' ', fp)), std::wint_t>::value), ""); - static_assert((std::is_same<decltype(std::wcstod(L"", (wchar_t**)0)), double>::value), ""); - static_assert((std::is_same<decltype(std::wcstof(L"", (wchar_t**)0)), float>::value), ""); - static_assert((std::is_same<decltype(std::wcstold(L"", (wchar_t**)0)), long double>::value), ""); - static_assert((std::is_same<decltype(std::wcstol(L"", (wchar_t**)0, 0)), long>::value), ""); - static_assert((std::is_same<decltype(std::wcstoll(L"", (wchar_t**)0, 0)), long long>::value), ""); - static_assert((std::is_same<decltype(std::wcstoul(L"", (wchar_t**)0, 0)), unsigned long>::value), ""); - static_assert((std::is_same<decltype(std::wcstoull(L"", (wchar_t**)0, 0)), unsigned long long>::value), ""); - static_assert((std::is_same<decltype(std::wcscpy(ws, L"")), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wcsncpy(ws, L"", s)), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wcscat(ws, L"")), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wcsncat(ws, L"", s)), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wcscmp(L"", L"")), int>::value), ""); - static_assert((std::is_same<decltype(std::wcscoll(L"", L"")), int>::value), ""); - static_assert((std::is_same<decltype(std::wcsncmp(L"", L"", s)), int>::value), ""); - static_assert((std::is_same<decltype(std::wcsxfrm(ws, L"", s)), std::size_t>::value), ""); - static_assert((std::is_same<decltype(std::wcschr((wchar_t*)0, L' ')), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wcscspn(L"", L"")), std::size_t>::value), ""); - static_assert((std::is_same<decltype(std::wcslen(L"")), std::size_t>::value), ""); - static_assert((std::is_same<decltype(std::wcspbrk((wchar_t*)0, L"")), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wcsrchr((wchar_t*)0, L' ')), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wcsspn(L"", L"")), std::size_t>::value), ""); - static_assert((std::is_same<decltype(std::wcsstr((wchar_t*)0, L"")), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wcstok(ws, L"", (wchar_t**)0)), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wmemchr((wchar_t*)0, L' ', s)), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wmemcmp(L"", L"", s)), int>::value), ""); - static_assert((std::is_same<decltype(std::wmemcpy(ws, L"", s)), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wmemmove(ws, L"", s)), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wmemset(ws, L' ', s)), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wcsftime(ws, s, L"", tm)), std::size_t>::value), ""); - static_assert((std::is_same<decltype(std::btowc(0)), wint_t>::value), ""); - static_assert((std::is_same<decltype(std::wctob(w)), int>::value), ""); - static_assert((std::is_same<decltype(std::mbsinit(&mb)), int>::value), ""); - static_assert((std::is_same<decltype(std::mbrlen("", s, &mb)), std::size_t>::value), ""); - static_assert((std::is_same<decltype(std::mbrtowc(ws, "", s, &mb)), std::size_t>::value), ""); - static_assert((std::is_same<decltype(std::wcrtomb(ns, L' ', &mb)), std::size_t>::value), ""); - static_assert((std::is_same<decltype(std::mbsrtowcs(ws, (const char**)0, s, &mb)), std::size_t>::value), ""); - static_assert((std::is_same<decltype(std::wcsrtombs(ns, (const wchar_t**)0, s, &mb)), std::size_t>::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<decltype(std::wcschr((const wchar_t*)0, L' ')), const wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wcspbrk((const wchar_t*)0, L"")), const wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wcsrchr((const wchar_t*)0, L' ')), const wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wcsstr((const wchar_t*)0, L"")), const wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wmemchr((const wchar_t*)0, L' ', s)), const wchar_t*>::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<decltype(std::getwchar()), std::wint_t>::value), ""); - static_assert((std::is_same<decltype(std::vwscanf(L"", va)), int>::value), ""); - static_assert((std::is_same<decltype(std::wscanf(L"")), int>::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<decltype(std::putwchar(L' ')), std::wint_t>::value), ""); - static_assert((std::is_same<decltype(std::vwprintf(L"", va)), int>::value), ""); - static_assert((std::is_same<decltype(std::wprintf(L"")), int>::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 <cwctype> #include <type_traits> +#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<decltype(std::iswalnum(w)), int>::value), ""); - static_assert((std::is_same<decltype(std::iswalpha(w)), int>::value), ""); - static_assert((std::is_same<decltype(std::iswblank(w)), int>::value), ""); - static_assert((std::is_same<decltype(std::iswcntrl(w)), int>::value), ""); - static_assert((std::is_same<decltype(std::iswdigit(w)), int>::value), ""); - static_assert((std::is_same<decltype(std::iswgraph(w)), int>::value), ""); - static_assert((std::is_same<decltype(std::iswlower(w)), int>::value), ""); - static_assert((std::is_same<decltype(std::iswprint(w)), int>::value), ""); - static_assert((std::is_same<decltype(std::iswpunct(w)), int>::value), ""); - static_assert((std::is_same<decltype(std::iswspace(w)), int>::value), ""); - static_assert((std::is_same<decltype(std::iswupper(w)), int>::value), ""); - static_assert((std::is_same<decltype(std::iswxdigit(w)), int>::value), ""); - static_assert((std::is_same<decltype(std::iswctype(w, wct)), int>::value), ""); - static_assert((std::is_same<decltype(std::wctype("")), std::wctype_t>::value), ""); - static_assert((std::is_same<decltype(std::towlower(w)), std::wint_t>::value), ""); - static_assert((std::is_same<decltype(std::towupper(w)), std::wint_t>::value), ""); - static_assert((std::is_same<decltype(std::towctrans(w, wctr)), std::wint_t>::value), ""); - static_assert((std::is_same<decltype(std::wctrans("")), std::wctrans_t>::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(""))); } 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 +// <string> + +// template<> struct char_traits<char8_t> + +// static constexpr void assign(char_type& c1, const char_type& c2); + +#include <string> +#include <cassert> + +#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<char8_t>::assign(c, u'a'); + return c == u'a'; +} + +int main() +{ + char8_t c = u8'\0'; + std::char_traits<char8_t>::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 + +// <string> + +// template<> struct char_traits<char8_t> + +// static char_type* assign(char_type* s, size_t n, char_type a); + +#include <string> +#include <cassert> + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + char8_t s2[3] = {0}; + assert(std::char_traits<char8_t>::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<char8_t>::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..5ab1c9f0b --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <string> + +// template<> struct char_traits<char8_t> + +// static constexpr int compare(const char_type* s1, const char_type* s2, size_t n); + +#include <string> +#include <cassert> + +#include "test_macros.h" + +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L +constexpr bool test_constexpr() +{ + return std::char_traits<char8_t>::compare(u8"123", u8"223", 3) < 0 + && std::char_traits<char8_t>::compare(u8"223", u8"123", 3) > 0 + && std::char_traits<char8_t>::compare(u8"123", u8"123", 3) == 0; +} + + +int main() +{ + assert(std::char_traits<char8_t>::compare(u8"", u8"", 0) == 0); + assert(std::char_traits<char8_t>::compare(NULL, NULL, 0) == 0); + + assert(std::char_traits<char8_t>::compare(u8"1", u8"1", 1) == 0); + assert(std::char_traits<char8_t>::compare(u8"1", u8"2", 1) < 0); + assert(std::char_traits<char8_t>::compare(u8"2", u8"1", 1) > 0); + + assert(std::char_traits<char8_t>::compare(u8"12", u8"12", 2) == 0); + assert(std::char_traits<char8_t>::compare(u8"12", u8"13", 2) < 0); + assert(std::char_traits<char8_t>::compare(u8"12", u8"22", 2) < 0); + assert(std::char_traits<char8_t>::compare(u8"13", u8"12", 2) > 0); + assert(std::char_traits<char8_t>::compare(u8"22", u8"12", 2) > 0); + + assert(std::char_traits<char8_t>::compare(u8"123", u8"123", 3) == 0); + assert(std::char_traits<char8_t>::compare(u8"123", u8"223", 3) < 0); + assert(std::char_traits<char8_t>::compare(u8"123", u8"133", 3) < 0); + assert(std::char_traits<char8_t>::compare(u8"123", u8"124", 3) < 0); + assert(std::char_traits<char8_t>::compare(u8"223", u8"123", 3) > 0); + assert(std::char_traits<char8_t>::compare(u8"133", u8"123", 3) > 0); + assert(std::char_traits<char8_t>::compare(u8"124", u8"123", 3) > 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/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 + +// <string> + +// template<> struct char_traits<char8_t> + +// static char_type* copy(char_type* s1, const char_type* s2, size_t n); + +#include <string> +#include <cassert> + +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<char8_t>::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<char8_t>::copy(NULL, s1, 0) == NULL); + assert(std::char_traits<char8_t>::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 + +// <string> + +// template<> struct char_traits<char8_t> + +// static constexpr int_type eof(); + +#include <string> +#include <cassert> + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + std::char_traits<char8_t>::int_type i = std::char_traits<char8_t>::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 + +// <string> + +// template<> struct char_traits<char8_t> + +// static constexpr bool eq(char_type c1, char_type c2); + +#include <string> +#include <cassert> + +#include "test_macros.h" + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert( std::char_traits<char8_t>::eq(u8'a', u8'a')); + assert(!std::char_traits<char8_t>::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 + +// <string> + +// template<> struct char_traits<char8_t> + +// static constexpr bool eq_int_type(int_type c1, int_type c2); + +#include <string> +#include <cassert> + +#include "test_macros.h" + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert( std::char_traits<char8_t>::eq_int_type(u8'a', u8'a')); + assert(!std::char_traits<char8_t>::eq_int_type(u8'a', u8'A')); + assert(!std::char_traits<char8_t>::eq_int_type(std::char_traits<char8_t>::eof(), u8'A')); + assert( std::char_traits<char8_t>::eq_int_type(std::char_traits<char8_t>::eof(), + std::char_traits<char8_t>::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 + +// <string> + +// template<> struct char_traits<char8_t> + +// static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); + +#include <string> +#include <cassert> + +#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<char8_t>::find(p, 3, u8'1') == p + && std::char_traits<char8_t>::find(p, 3, u8'2') == p + 1 + && std::char_traits<char8_t>::find(p, 3, u8'3') == p + 2 + && std::char_traits<char8_t>::find(p, 3, u8'4') == nullptr; +} + +int main() +{ + char8_t s1[] = {1, 2, 3}; + assert(std::char_traits<char8_t>::find(s1, 3, char8_t(1)) == s1); + assert(std::char_traits<char8_t>::find(s1, 3, char8_t(2)) == s1+1); + assert(std::char_traits<char8_t>::find(s1, 3, char8_t(3)) == s1+2); + assert(std::char_traits<char8_t>::find(s1, 3, char8_t(4)) == 0); + assert(std::char_traits<char8_t>::find(s1, 3, char8_t(0)) == 0); + assert(std::char_traits<char8_t>::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..f200c2332 --- /dev/null +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/length.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <string> + +// template<> struct char_traits<char8_t> + +// static constexpr size_t length(const char_type* s); + +#include <string> +#include <cassert> + +#include "test_macros.h" + +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L +constexpr bool test_constexpr() +{ + return std::char_traits<char8_t>::length(u8"") == 0 + && std::char_traits<char8_t>::length(u8"abcd") == 4; +} + +int main() +{ + assert(std::char_traits<char8_t>::length(u8"") == 0); + assert(std::char_traits<char8_t>::length(u8"a") == 1); + assert(std::char_traits<char8_t>::length(u8"aa") == 2); + assert(std::char_traits<char8_t>::length(u8"aaa") == 3); + assert(std::char_traits<char8_t>::length(u8"aaaa") == 4); + + static_assert(test_constexpr(), ""); +} +#else +int main() { } +#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 + +// <string> + +// template<> struct char_traits<char8_t> + +// static constexpr bool lt(char_type c1, char_type c2); + +#include <string> +#include <cassert> + +#include "test_macros.h" + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert(!std::char_traits<char8_t>::lt(u8'a', u8'a')); + assert( std::char_traits<char8_t>::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 + +// <string> + +// template<> struct char_traits<char8_t> + +// static char_type* move(char_type* s1, const char_type* s2, size_t n); + +#include <string> +#include <cassert> + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + char8_t s1[] = {1, 2, 3}; + assert(std::char_traits<char8_t>::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<char8_t>::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<char8_t>::move(NULL, s1, 0) == NULL); + assert(std::char_traits<char8_t>::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 + +// <string> + +// template<> struct char_traits<char8_t> + +// static constexpr int_type not_eof(int_type c); + +#include <string> +#include <cassert> + +#include "test_macros.h" + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert(std::char_traits<char8_t>::not_eof(u8'a') == u8'a'); + assert(std::char_traits<char8_t>::not_eof(u8'A') == u8'A'); + assert(std::char_traits<char8_t>::not_eof(0) == 0); + assert(std::char_traits<char8_t>::not_eof(std::char_traits<char8_t>::eof()) != + std::char_traits<char8_t>::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 + +// <string> + +// template<> struct char_traits<char8_t> + +// static constexpr char_type to_char_type(int_type c); + +#include <string> +#include <cassert> + +#include "test_macros.h" + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert(std::char_traits<char8_t>::to_char_type(u8'a') == u8'a'); + assert(std::char_traits<char8_t>::to_char_type(u8'A') == u8'A'); + assert(std::char_traits<char8_t>::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 + +// <string> + +// template<> struct char_traits<char8_t> + +// static constexpr int_type to_int_type(char_type c); + +#include <string> +#include <cassert> + +#include "test_macros.h" + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert(std::char_traits<char8_t>::to_int_type(u8'a') == u8'a'); + assert(std::char_traits<char8_t>::to_int_type(u8'A') == u8'A'); + assert(std::char_traits<char8_t>::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 + +// <string> + +// template<> struct char_traits<char8_t> + +// typedef char8_t char_type; +// typedef unsigned int int_type; +// typedef streamoff off_type; +// typedef u16streampos pos_type; +// typedef mbstate_t state_type; + +#include <string> +#include <type_traits> +#include <cstdint> + +int main() +{ +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + static_assert((std::is_same<std::char_traits<char8_t>::char_type, char8_t>::value), ""); + static_assert((std::is_same<std::char_traits<char8_t>::int_type, unsigned int>::value), ""); + static_assert((std::is_same<std::char_traits<char8_t>::off_type, std::streamoff>::value), ""); + static_assert((std::is_same<std::char_traits<char8_t>::pos_type, std::u16streampos>::value), ""); + static_assert((std::is_same<std::char_traits<char8_t>::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<char> string; +// typedef basic_string<char> string; // typedef basic_string<char16_t> u16string; +// typedef basic_string<char8_t> u8string; // C++20 // typedef basic_string<char32_t> u32string; -// typedef basic_string<wchar_t> wstring; +// typedef basic_string<wchar_t> wstring; #include <string> #include <type_traits> +#include "test_macros.h" + int main() { static_assert((std::is_same<std::string, std::basic_string<char> >::value), ""); static_assert((std::is_same<std::wstring, std::basic_string<wchar_t> >::value), ""); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + static_assert((std::is_same<std::u8string, std::basic_string<char8_t> >::value), ""); +#endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS static_assert((std::is_same<std::u16string, std::basic_string<char16_t> >::value), ""); static_assert((std::is_same<std::u32string, std::basic_string<char32_t> >::value), ""); 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 <limits> #include <string> #include <cassert> #include <sstream> 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 <limits> #include <string> #include <cassert> #include <sstream> 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<string_view> (); - test1<u16string_view> (); - test1<u32string_view> (); - test1<wstring_view> (); + test1<std::string_view> (); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test1<std::u8string_view> (); +#endif + test1<std::u16string_view> (); + test1<std::u32string_view> (); + test1<std::wstring_view> (); 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<std::string_view> ( "1234")); + assert( test<std::string_view> ( "1234")); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + assert( test<std::u8string_view> (u8"1234")); +#endif #if TEST_STD_VER >= 11 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - assert( test<std::u16string_view> (u"1234")); - assert( test<std::u32string_view> (U"1234")); + assert( test<std::u16string_view> ( u"1234")); + assert( test<std::u32string_view> ( U"1234")); #endif #endif - assert( test<std::wstring_view> (L"1234")); + assert( test<std::wstring_view> ( L"1234")); #if TEST_STD_VER > 11 - static_assert( test<std::string_view> ({ "abc", 3}), ""); + static_assert( test<std::string_view> ({ "abc", 3}), ""); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + static_assert( test<std::u8string_view> ({u8"abc", 3}), ""); +#endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - static_assert( test<std::u16string_view> ({u"abc", 3}), ""); - static_assert( test<std::u32string_view> ({U"abc", 3}), ""); + static_assert( test<std::u16string_view> ({ u"abc", 3}), ""); + static_assert( test<std::u32string_view> ({ U"abc", 3}), ""); #endif - static_assert( test<std::wstring_view> ({L"abc", 3}), ""); + static_assert( test<std::wstring_view> ({ 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<string_view> (); - test<u16string_view> (); - test<u32string_view> (); - test<wstring_view> (); + test<std::string_view> (); + test<std::u16string_view> (); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test<std::u8string_view> (); +#endif + test<std::u32string_view> (); + test<std::wstring_view> (); } 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<std::string_view>(); test_hash_enabled_for_type<std::wstring_view>(); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test_hash_enabled_for_type<std::u8string_view>(); +#endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS test_hash_enabled_for_type<std::u16string_view>(); test_hash_enabled_for_type<std::u32string_view>(); 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<std::string_view>(); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test<std::u8string_view>(); +#endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS test<std::u16string_view>(); test<std::u32string_view>(); 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<decltype( "Hi"sv), std::string_view>::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<decltype( u8"Hi"sv), std::string_view>::value, "" ); -#endif + static_assert ( std::is_same<decltype( u8"Hi"sv), u8string_view>::value, "" ); static_assert ( std::is_same<decltype( L"Hi"sv), std::wstring_view>::value, "" ); static_assert ( std::is_same<decltype( u"Hi"sv), std::u16string_view>::value, "" ); static_assert ( std::is_same<decltype( U"Hi"sv), std::u32string_view>::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<std::char_traits<char> >(); test<std::char_traits<wchar_t> >(); +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L + test<std::char_traits<char8_t> >(); +#endif static_assert((std::is_same<std::basic_string_view<char>::traits_type, std::char_traits<char> >::value), ""); } 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 + +// <string> + +// template <class charT, class traits, class Allocator, class U> +// void erase(basic_string<charT, traits, Allocator>& c, const U& value); + + +#include <string> +#include <optional> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class U> +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 <class S> +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<typename S::value_type>; + 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<std::string>(); + test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>> (); + test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>> (); +} 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 + +// <string> + +// template <class charT, class traits, class Allocator, class Predicate> +// void erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); + +#include <string> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class Pred> +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 <typename S> +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<std::string>(); + test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>> (); + test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>> (); +} 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 + // <condition_variable> // 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 + // <condition_variable> // class condition_variable_any; 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 + // <mutex> // template <class Mutex> 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 + // <mutex> // template <class Mutex> class lock_guard; 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 + // <shared_mutex> // template <class Mutex> 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 + // <mutex> // template <class Mutex> 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 + // <mutex> // template <class Mutex> class unique_lock; 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..7b08f3047 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 @@ -183,8 +184,7 @@ struct test_signed : roundtrip_test_base<T> } }; -int -main() +int main() { run<test_basics>(integrals); run<test_signed>(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 ab78ca464..63891b1ee 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 @@ -81,8 +82,7 @@ struct test_signed : to_chars_test_base<T> } }; -int -main() +int main() { run<test_basics>(integrals); run<test_signed>(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/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<sizeof(VT)>::type store; std::allocator_traits<Alloc>::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/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 <limits> #include <memory> #include <new> #include <type_traits> 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<signed char>(); test_is_integral<unsigned char>(); test_is_integral<wchar_t>(); -#if TEST_STD_VER > 17 && defined(__cpp_char8_t) +#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L test_is_integral<char8_t>(); #endif 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 // <optional> 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> -// optional<T>& operator=(const optional<T>& rhs); +// optional<T>& operator=(const optional<T>& rhs); // constexpr in C++20 #include <optional> #include <type_traits> @@ -53,15 +53,19 @@ int main() { { using O = optional<int>; +#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<TrivialTestTypes::TestType>; +#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<T>& operator=(optional<T>&& rhs) // noexcept(is_nothrow_move_assignable<T>::value && -// is_nothrow_move_constructible<T>::value); +// is_nothrow_move_constructible<T>::value); // constexpr in C++20 #include <optional> -#include <type_traits> #include <cassert> +#include <type_traits> +#include <utility> #include "test_macros.h" #include "archetypes.hpp" @@ -51,6 +52,21 @@ struct Y {}; bool X::throw_now = false; int X::alive = 0; + +template <class Tp> +constexpr bool assign_empty(optional<Tp>&& lhs) { + optional<Tp> rhs; + lhs = std::move(rhs); + return !lhs.has_value() && !rhs.has_value(); +} + +template <class Tp> +constexpr bool assign_value(optional<Tp>&& lhs) { + optional<Tp> 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<bool>(opt) == static_cast<bool>(opt2)); assert(*opt == *opt2); } + { + using O = optional<int>; +#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<TrivialTestTypes::TestType>; +#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<optional<X>>::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 -// <optional> - -// constexpr optional(const optional<T>& rhs); -// If is_trivially_copy_constructible_v<T> is true, -// this constructor shall be a constexpr constructor. - -#include <optional> -#include <type_traits> -#include <cassert> - -#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<S>, "" ); - constexpr std::optional<S> o1; - constexpr std::optional<S> 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 + +// <optional> + +// Make sure we properly generate special member functions for optional<T> +// based on the properties of T itself. + +#include <optional> +#include <type_traits> + +#include "archetypes.hpp" + + +template <class T> +struct SpecialMemberTest { + using O = std::optional<T>; + + static_assert(std::is_default_constructible_v<O>, + "optional is always default constructible."); + + static_assert(std::is_copy_constructible_v<O> == std::is_copy_constructible_v<T>, + "optional<T> is copy constructible if and only if T is copy constructible."); + + static_assert(std::is_move_constructible_v<O> == + (std::is_copy_constructible_v<T> || std::is_move_constructible_v<T>), + "optional<T> is move constructible if and only if T is copy or move constructible."); + + static_assert(std::is_copy_assignable_v<O> == + (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>), + "optional<T> is copy assignable if and only if T is both copy " + "constructible and copy assignable."); + + static_assert(std::is_move_assignable_v<O> == + ((std::is_move_constructible_v<T> && std::is_move_assignable_v<T>) || + (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>)), + "optional<T> is move assignable if and only if T is both move constructible and " + "move assignable, or both copy constructible and copy assignable."); +}; + +template <class ...Args> static void sink(Args&&...) {} + +template <class ...TestTypes> +struct DoTestsMetafunction { + DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); } +}; + +int main() { + sink( + ImplicitTypes::ApplyTypes<DoTestsMetafunction>{}, + ExplicitTypes::ApplyTypes<DoTestsMetafunction>{}, + NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{}, + NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{} + ); +} 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 + +// <optional> + +// 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<T>& operator=(const optional& rhs); +// constexpr optional<T>& operator=(optional&& rhs) noexcept(see below); + + +#include <optional> +#include <type_traits> + +#include "archetypes.hpp" + + +constexpr bool implies(bool p, bool q) { + return !p || q; +} + +template <class T> +struct SpecialMemberTest { + using O = std::optional<T>; + + static_assert(implies(std::is_trivially_copy_constructible_v<T>, + std::is_trivially_copy_constructible_v<O>), + "optional<T> is trivially copy constructible if T is trivially copy constructible."); + + static_assert(implies(std::is_trivially_move_constructible_v<T>, + std::is_trivially_move_constructible_v<O>), + "optional<T> is trivially move constructible if T is trivially move constructible"); + + static_assert(implies(std::is_trivially_copy_constructible_v<T> && + std::is_trivially_copy_assignable_v<T> && + std::is_trivially_destructible_v<T>, + + std::is_trivially_copy_assignable_v<O>), + "optional<T> 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<T> && + std::is_trivially_move_assignable_v<T> && + std::is_trivially_destructible_v<T>, + + std::is_trivially_move_assignable_v<O>), + "optional<T> is trivially move assignable if T is " + "trivially move constructible, " + "trivially move assignable, and" + "trivially destructible."); +}; + +template <class ...Args> static void sink(Args&&...) {} + +template <class ...TestTypes> +struct DoTestsMetafunction { + DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); } +}; + +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<DoTestsMetafunction>{}, + ExplicitTypes::ApplyTypes<DoTestsMetafunction>{}, + NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{}, + NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{}, + DoTestsMetafunction<TrivialMoveNonTrivialCopy, TrivialCopyNonTrivialMove>{} + ); +} 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 // <optional> -// 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 T> // constexpr optional<decay_t<T>> make_optional(T&& v); 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; 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 // <chrono> 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 + +// <chrono> +// 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 <chrono> +#include <type_traits> +#include <cassert> + +#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<local_days>()}); + + { + constexpr local_days sd{}; // 1-Jan-1970 was a Thursday + constexpr weekday wd{sd}; + + static_assert( wd.ok(), ""); + static_assert(static_cast<unsigned>(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<unsigned>(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<unsigned>(wd) == 2, ""); + } + + { + local_days sd{days{-(10957+34)}}; // 29-Nov-1939 was a Wednesday + weekday wd{sd}; + + assert( wd.ok()); + assert(static_cast<unsigned>(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 + +// <chrono> +// 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 <chrono> +#include <type_traits> +#include <cassert> + +#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<sys_days>()}); + + { + constexpr sys_days sd{}; // 1-Jan-1970 was a Thursday + constexpr weekday wd{sd}; + + static_assert( wd.ok(), ""); + static_assert(static_cast<unsigned>(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<unsigned>(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<unsigned>(wd) == 2, ""); + } + + { + sys_days sd{days{-(10957+34)}}; // 29-Nov-1939 was a Wednesday + weekday wd{sd}; + + assert( wd.ok()); + assert(static_cast<unsigned>(wd) == 3); + } +} 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 // <chrono> 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: * // <chrono> // 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<const local_days>()}); - assert(false); + ASSERT_NOEXCEPT(year_month_day{std::declval<local_days>()}); + + { + 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: * // <chrono> // 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<const sys_days>()}); - assert(false); + ASSERT_NOEXCEPT(year_month_day{std::declval<sys_days>()}); + { + 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: * // <chrono> // 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<const year_month_day_last>()}); - assert(false); + ASSERT_NOEXCEPT(year_month_day{std::declval<const year_month_day_last>()}); + { + 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..a70fe30fc --- /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 + +// <chrono> +// 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 <chrono> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +void RunTheExample() +{ + using namespace std::chrono; + + 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() +{ + 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<year_month_day>())); + 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..4e263bccc --- /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 + +// <chrono> +// 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 <chrono> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +void RunTheExample() +{ + using namespace std::chrono; + + 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() +{ + 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<year_month_day>())); + 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: * // <chrono> // 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<const year_month_day_last>().day()); -// ASSERT_SAME_TYPE(day, decltype(std::declval<const year_month_day_last>().day())); -// -// static_assert( year_month_day_last{}.day() == day{}, ""); + ASSERT_NOEXCEPT( std::declval<const year_month_day_last>().day()); + ASSERT_SAME_TYPE(day, decltype(std::declval<const year_month_day_last>().day())); + +// 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}, ""); - for (unsigned i = 1; i <= 12; ++i) - { - year_month_day_last ymd(year{1234}, month_day_last{month{i}}); - assert( static_cast<unsigned>(ymd.day()) == i); - } + 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: * // <chrono> // 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<local_days>(std::declval<const year_month_day_last>().year())); -// ASSERT_SAME_TYPE(year, decltype(static_cast<local_days>(std::declval<const year_month_day_last>().year())); - assert(false); + ASSERT_NOEXCEPT( static_cast<local_days>(std::declval<const year_month_day_last>())); + ASSERT_SAME_TYPE(local_days, decltype(static_cast<local_days>(std::declval<const year_month_day_last>()))); + + { // 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: * // <chrono> // 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<sys_days>(std::declval<const year_month_day_last>().year())); -// ASSERT_SAME_TYPE(year, decltype(static_cast<sys_days>(std::declval<const year_month_day_last>().year())); - assert(false); + ASSERT_NOEXCEPT( static_cast<sys_days>(std::declval<const year_month_day_last>())); + ASSERT_SAME_TYPE(sys_days, decltype(static_cast<sys_days>(std::declval<const year_month_day_last>()))); + + { // 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: * // <chrono> // 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<const local_days>()}); - assert(false); + ASSERT_NOEXCEPT(year_month_weekday{std::declval<const local_days>()}); + + { + 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: * // <chrono> // 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<const sys_days>()}); - assert(false); + ASSERT_NOEXCEPT(year_month_weekday{std::declval<const sys_days>()}); + + { + 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: * - -// <chrono> -// 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 <chrono> -#include <type_traits> -#include <cassert> - -#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<const year_month_weekday_last>()}); - -} 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 + +// <chrono> +// 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 <chrono> +#include <type_traits> +#include <cassert> + +#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<year_month_weekday>())); + + { + 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 + +// <chrono> +// 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 <chrono> +#include <type_traits> +#include <cassert> + +#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<year_month_weekday>())); + + { + 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: * // <chrono> // 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<local_days>(std::declval<const year_month_day_last>().year())); - ASSERT_SAME_TYPE(year, decltype(static_cast<local_days>(std::declval<const year_month_day_last>().year())); + ASSERT_NOEXCEPT( static_cast<local_days>(std::declval<const year_month_day_last>())); + ASSERT_SAME_TYPE(local_days, decltype(static_cast<local_days>(std::declval<const year_month_day_last>()))); + + { // 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: * // <chrono> -// 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 <chrono> #include <type_traits> @@ -21,16 +21,49 @@ #include "test_macros.h" +#include <iostream> + 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<sys_days>(std::declval<const year_month_weekday_last>())); + ASSERT_SAME_TYPE(sys_days, decltype(static_cast<sys_days>(std::declval<const year_month_weekday_last>()))); + + 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}, ""); + } - ASSERT_NOEXCEPT( static_cast<sys_days>(std::declval<const year_month_day_last>().year())); - ASSERT_SAME_TYPE(year, decltype(static_cast<sys_days>(std::declval<const year_month_day_last>().year())); + { // 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.file/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp new file mode 100644 index 000000000..0b5757f67 --- /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 + +// <chrono> + +// file_clock + +// check clock invariants + +#include <chrono> + +template <class T> +void test(const T &) {} + +int main() +{ + typedef std::chrono::file_clock C; + static_assert((std::is_same<C::rep, C::duration::rep>::value), ""); + static_assert((std::is_same<C::period, C::duration::period>::value), ""); + static_assert((std::is_same<C::duration, C::time_point::duration>::value), ""); + static_assert((std::is_same<C::time_point::clock, C>::value), ""); + static_assert(!C::is_steady, ""); + test(std::chrono::file_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 + +// <chrono> + +// file_time + +#include <chrono> + +#include "test_macros.h" + +template <class Dur> +void test() { + ASSERT_SAME_TYPE(std::chrono::file_time<Dur>, std::chrono::time_point<std::chrono::file_clock, Dur>); +} + +int main() { + test<std::chrono::nanoseconds>(); + test<std::chrono::minutes>(); + test<std::chrono::hours>(); +}
\ 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 + +// <chrono> + +// file_clock + +// static time_point now() noexcept; + +#include <chrono> +#include <cassert> + +#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 + +// <chrono> + +// file_clock + +// rep should be signed + +#include <chrono> +#include <cassert> + +int main() +{ + static_assert(std::is_signed<std::chrono::file_clock::rep>::value, ""); + assert(std::chrono::file_clock::duration::min() < + std::chrono::file_clock::duration::zero()); +} 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) // <chrono> 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) // <chrono> 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) // <chrono> 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 + +// <chrono> + +// struct local_t {}; +// template<class Duration> +// using local_time = time_point<system_clock, Duration>; +// using local_seconds = sys_time<seconds>; +// using local_days = sys_time<days>; + +// [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 <chrono> +#include <cassert> + +#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<minutes>; + using local_days = std::chrono::local_days; + + constexpr std::chrono::month January = std::chrono::January; + + ASSERT_SAME_TYPE(std::chrono::local_time<seconds>, local_seconds); + ASSERT_SAME_TYPE(std::chrono::local_time<days>, local_days); + +// Test the long form, too + ASSERT_SAME_TYPE(std::chrono::time_point<local_t, seconds>, local_seconds); + ASSERT_SAME_TYPE(std::chrono::time_point<local_t, minutes>, local_minutes); + ASSERT_SAME_TYPE(std::chrono::time_point<local_t, days>, 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 + +// <chrono> + +// template<class Duration> +// using sys_time = time_point<system_clock, Duration>; +// using sys_seconds = sys_time<seconds>; +// using sys_days = sys_time<days>; + +// [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 <chrono> +#include <cassert> + +#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<minutes>; + using sys_days = std::chrono::sys_days; + + constexpr std::chrono::month January = std::chrono::January; + + ASSERT_SAME_TYPE(std::chrono::sys_time<seconds>, sys_seconds); + ASSERT_SAME_TYPE(std::chrono::sys_time<days>, sys_days); + +// Test the long form, too + ASSERT_SAME_TYPE(std::chrono::time_point<system_clock, seconds>, sys_seconds); + ASSERT_SAME_TYPE(std::chrono::time_point<system_clock, minutes>, sys_minutes); + ASSERT_SAME_TYPE(std::chrono::time_point<system_clock, days>, 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); +} 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 <cassert> #include "test_macros.h" +#include "truncate_fp.h" int main() { @@ -41,7 +42,7 @@ int main() { std::chrono::duration<int, std::ratio<2, 3> > s1(30); std::chrono::duration<double, std::ratio<3, 5> > s2(5); - assert(s1 / s2 == 20./3); + assert(s1 / s2 == truncate_fp(20./3)); } #if TEST_STD_VER >= 11 { 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 <class D> void test() { - LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values<typename D::rep>::max()); + LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values<typename D::rep>::max()); #if TEST_STD_VER > 17 - ASSERT_NOEXCEPT( std::chrono::duration_values<typename D::rep>::max()); + ASSERT_NOEXCEPT( std::chrono::duration_values<typename D::rep>::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 <class D> void test() { - LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values<typename D::rep>::zero()); + LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values<typename D::rep>::zero()); #if TEST_STD_VER > 17 - ASSERT_NOEXCEPT( std::chrono::duration_values<typename D::rep>::zero()); + ASSERT_NOEXCEPT( std::chrono::duration_values<typename D::rep>::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<Clock, Duration> 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())); } 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<void()> f(x); 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 <memory> #include <tuple> #include <utility> #include <cassert> 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 <functional> #include <tuple> #include <string> #include <cassert> 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... Types> class tuple; // template <class... Types> -// class tuple_size<tuple<Types...>> +// struct tuple_size<tuple<Types...>> // : public integral_constant<size_t, sizeof...(Types)> { }; // UNSUPPORTED: c++98, c++03 @@ -26,19 +26,19 @@ struct Dummy2 {}; struct Dummy3 {}; template <> -class std::tuple_size<Dummy1> { +struct std::tuple_size<Dummy1> { public: static size_t value; }; template <> -class std::tuple_size<Dummy2> { +struct std::tuple_size<Dummy2> { public: static void value() {} }; template <> -class std::tuple_size<Dummy3> {}; +struct std::tuple_size<Dummy3> {}; 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... Types> class tuple; // template <class... Types> -// class tuple_size<tuple<Types...>> +// struct tuple_size<tuple<Types...>> // : public integral_constant<size_t, sizeof...(Types)> { }; // XFAIL: gcc-4.9 @@ -31,7 +31,7 @@ struct Dummy1 {}; struct Dummy2 {}; namespace std { -template <> class tuple_size<Dummy1> : public integral_constant<size_t, 0> {}; +template <> struct tuple_size<Dummy1> : public integral_constant<size_t, 0> {}; } template <class T> 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... Types> class tuple; // template <class... Types> -// class tuple_size<tuple<Types...>> +// struct tuple_size<tuple<Types...>> // : public integral_constant<size_t, sizeof...(Types)> { }; // UNSUPPORTED: c++98, c++03, c++11, c++14 @@ -129,7 +129,7 @@ void test_before_tuple_size_specialization() { } template <> -class std::tuple_size<Test> { +struct std::tuple_size<Test> { public: static const size_t value = 1; }; 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 <typeindex> +#include <type_traits> #include <cassert> int main() 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<Args1...> first_args, // tuple<Args2...> second_args); -#include <utility> -#include <tuple> #include <cassert> +#include <tuple> +#include <utility> + int main() { 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 ...Types> class variant; -// variant& operator=(variant const&); +// variant& operator=(variant const&); // constexpr in C++20 #include <cassert> #include <string> @@ -240,7 +240,8 @@ void test_copy_assignment_sfinae() { static_assert(!std::is_copy_assignable<V>::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<int, long>; static_assert(std::is_trivially_copy_assignable<V>::value, ""); @@ -262,6 +263,7 @@ void test_copy_assignment_sfinae() { using V = std::variant<int, CopyOnly>; static_assert(std::is_trivially_copy_assignable<V>::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<int> 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<long> 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 <size_t NewIdx, class ValueType> -constexpr bool test_constexpr_assign_extension_imp( +constexpr bool test_constexpr_assign_imp( std::variant<long, void*, int>&& v, ValueType&& new_value) { const std::variant<long, void*, int> cp( @@ -572,15 +578,17 @@ constexpr bool test_constexpr_assign_extension_imp( std::get<NewIdx>(v) == std::get<NewIdx>(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<long, void*, int>; static_assert(std::is_trivially_copyable<V>::value, ""); static_assert(std::is_trivially_copy_assignable<V>::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 ...Types> class variant; -// variant& operator=(variant&&) noexcept(see below); +// variant& operator=(variant&&) noexcept(see below); // constexpr in C++20 #include <cassert> #include <string> @@ -206,7 +206,8 @@ void test_move_assignment_sfinae() { static_assert(!std::is_move_assignable<V>::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<int, long>; static_assert(std::is_trivially_move_assignable<V>::value, ""); @@ -232,6 +233,7 @@ void test_move_assignment_sfinae() { using V = std::variant<int, CopyOnly>; static_assert(std::is_trivially_move_assignable<V>::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<int> 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<long> 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 <size_t NewIdx, class ValueType> -constexpr bool test_constexpr_assign_extension_imp( +constexpr bool test_constexpr_assign_imp( std::variant<long, void*, int>&& v, ValueType&& new_value) { std::variant<long, void*, int> v2( @@ -488,15 +494,17 @@ constexpr bool test_constexpr_assign_extension_imp( std::get<NewIdx>(v) == std::get<NewIdx>(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<long, void*, int>; static_assert(std::is_trivially_copyable<V>::value, ""); static_assert(std::is_trivially_move_assignable<V>::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/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 @@ // <variant> -// 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 ...Types> class variant; 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 ...Types> class variant; -// variant(variant const&); +// variant(variant const&); // constexpr in C++20 #include <cassert> #include <type_traits> @@ -126,7 +126,8 @@ void test_copy_ctor_sfinae() { static_assert(!std::is_copy_constructible<V>::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<int, long>; static_assert(std::is_trivially_copy_constructible<V>::value, ""); @@ -144,6 +145,7 @@ void test_copy_ctor_sfinae() { using V = std::variant<int, TCopyNTMove>; static_assert(std::is_trivially_copy_constructible<V>::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<int> 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 <size_t Idx> -constexpr bool test_constexpr_copy_ctor_extension_imp( - std::variant<long, void*, const int> const& v) -{ +constexpr bool test_constexpr_copy_ctor_imp(std::variant<long, void*, const int> const& v) { auto v2 = v; return v2.index() == v.index() && v2.index() == Idx && std::get<Idx>(v2) == std::get<Idx>(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<long, void*, const int>; #ifdef TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE static_assert(std::is_trivially_destructible<V>::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<V>::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/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 @@ // <variant> -// 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 ...Types> 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 @@ // <variant> -// 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 ...Types> class variant; 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 ...Types> class variant; -// variant(variant&&) noexcept(see below); +// variant(variant&&) noexcept(see below); // constexpr in C++20 #include <cassert> #include <string> @@ -147,7 +147,8 @@ void test_move_ctor_sfinae() { static_assert(!std::is_move_constructible<V>::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<int, long>; static_assert(std::is_trivially_move_constructible<V>::value, ""); @@ -165,6 +166,7 @@ void test_move_ctor_sfinae() { using V = std::variant<int, TMoveNTCopy>; static_assert(std::is_trivially_move_constructible<V>::value, ""); } +#endif // > C++17 } template <typename T> @@ -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<int> 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 <size_t Idx> -constexpr bool test_constexpr_ctor_extension_imp( - std::variant<long, void*, const int> const& v) -{ +constexpr bool test_constexpr_ctor_imp(std::variant<long, void*, const int> 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<Idx>(v2) == std::get<Idx>(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<long, void*, const int>; #ifdef TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE static_assert(std::is_trivially_destructible<V>::value, ""); @@ -323,9 +326,10 @@ void test_constexpr_move_ctor_extension() { static_assert(std::is_trivially_copyable<V>::value, ""); #endif // TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE static_assert(std::is_trivially_move_constructible<V>::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/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 { @@ -242,11 +241,17 @@ namespace NonLiteralTypes { } //============================================================================// +// 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 <class ...Args> - DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(Args&&...) {} + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(Args&&...) DEFINE_NOEXCEPT {} template <class Arg> - 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 diff --git a/test/support/filesystem_dynamic_test_helper.py b/test/support/filesystem_dynamic_test_helper.py index 081e678b6..078958274 100644 --- a/test/support/filesystem_dynamic_test_helper.py +++ b/test/support/filesystem_dynamic_test_helper.py @@ -1,10 +1,12 @@ import sys import os +import socket 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') @@ -75,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__': 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 <cstdlib> #include <cstddef> #include <cassert> +#include <climits> #include "test_macros.h" @@ -131,6 +132,59 @@ public: friend bool operator!=(malloc_allocator x, malloc_allocator y) {return !(x == y);} }; +template <class T> +struct cpp03_allocator : bare_allocator<T> +{ + 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 <class T> bool cpp03_allocator<T>::construct_called = false; + +template <class T> +struct cpp03_overload_allocator : bare_allocator<T> +{ + 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<T>()); + } + 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 <class T> bool cpp03_overload_allocator<T>::construct_called = false; + #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; +} 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 <<EOM +$(basename ${0}) [-h|--help] --libcxx-root <LIBCXX-ROOT> --libcxxabi-root <LIBCXXABI-ROOT> --std <STD> --arch <ARCHITECTURE> --deployment-target <TARGET> --sdk-version <SDK-VERSION> [--lit-args <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 "@@@@@@" 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 <<EOM +$(basename ${0}) [-h|--help] --libcxx-root <LIBCXX-ROOT> --libcxxabi-root <LIBCXXABI-ROOT> --std <STD> --arch <ARCHITECTURE> [--lit-args <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 "@@@@@@" 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..f47ddcd24 --- /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 +/libcxx/utils/docker/scripts/run_buildbot.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 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 <arne@twobeer.de> Billy Robert O'Neal III <billy.oneal@gmail.com> <bion@microsoft.com> Chris Kennelly <ckennelly@google.com> <ckennelly@ckennelly.com> Christopher Seymour <chris.j.seymour@hotmail.com> +Cyrille Faucheux <cyrille.faucheux@gmail.com> David Coeurjolly <david.coeurjolly@liris.cnrs.fr> Deniz Evrenci <denizevrenci@gmail.com> Dominic Hamon <dma@stripysock.com> <dominic@google.com> 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 <class Q> int BM_Sequential(benchmark::State& state) { +template <class Q> 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<int> 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<unsigned long>(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<unsigned long>(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<int64_t>& n, const std::vector<double>& time, 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<int>(name_field_width_), + std::string str = FormatString("%-*s %13s %15s %12s", static_cast<int>(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/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 <versionhelpers.h> #include <windows.h> +#include <codecvt> #else #include <fcntl.h> #ifndef BENCHMARK_OS_FUCHSIA @@ -52,6 +53,7 @@ #include <limits> #include <memory> #include <sstream> +#include <locale> #include "check.h" #include "cycleclock.h" @@ -366,6 +368,35 @@ std::vector<CPUInfo::CacheInfo> 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<wchar_t>; + std::wstring_convert<convert_type, wchar_t> 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..5dc951d2b 100644 --- a/utils/google-benchmark/test/output_test_helper.cc +++ b/utils/google-benchmark/test/output_test_helper.cc @@ -4,6 +4,7 @@ #include <iostream> #include <map> #include <memory> +#include <random> #include <sstream> #include <streambuf> @@ -38,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"}, @@ -207,7 +209,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 +440,50 @@ int SubstrCnt(const std::string& haystack, const std::string& pat) { return count; } +static char ToHex(int ch) { + return ch < 10 ? static_cast<char>('0' + ch) + : static_cast<char>('a' + (ch - 10)); +} + +static char RandomHexChar() { + static std::mt19937 rd{std::random_device{}()}; + static std::uniform_int_distribution<int> 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<char*> new_argv(argv, argv + argc); assert(static_cast<decltype(new_argv)::size_type>(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..ec6d51b35 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}, @@ -220,6 +221,18 @@ ADD_CASES(TC_JSONOut, 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 ----------------------- // // ========================================================================= // @@ -521,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( 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 `<prefix><arg>` 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 diff --git a/utils/libcxx/test/config.py b/utils/libcxx/test/config.py index bdedd513c..1aa52ddbb 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) @@ -406,11 +407,10 @@ class Configuration(object): if self.use_deployment: self.add_deployment_feature('with_system_cxx_lib') - # Configure the availability markup checks features. - if self.use_deployment: - self.config.available_features.add('availability_markup') - self.add_deployment_feature('availability_markup') - + # 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') @@ -487,13 +487,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) @@ -574,6 +568,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') @@ -731,37 +729,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 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( - 'unsupported value for "use_stdlib_type": %s' - % use_stdlib_type) + # 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') link_flags_str = self.get_lit_conf('link_flags', '') self.cxx.link_flags += shlex.split(link_flags_str) diff --git a/utils/libcxx/test/target_info.py b/utils/libcxx/test/target_info.py index 2ca09dc5d..32bbb2e11 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] @@ -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) diff --git a/www/cxx2a_status.html b/www/cxx2a_status.html index 349d3c2bf..a5e87ec18 100644 --- a/www/cxx2a_status.html +++ b/www/cxx2a_status.html @@ -115,7 +115,7 @@ <tr><td><a href="https://wg21.link/P0487R1">P0487R1</a></td><td>LWG</td><td>Fixing operator>>(basic_istream&, CharT*) (LWG 2499)</td><td>San Diego</td><td>Complete</td><td>8.0</td></tr> <tr><td><a href="https://wg21.link/P0591R4">P0591R4</a></td><td>LWG</td><td>Utility functions to implement uses-allocator construction</td><td>San Diego</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P0595R2">P0595R2</a></td><td>CWG</td><td>P0595R2 std::is_constant_evaluated()</td><td>San Diego</td><td><i> </i></td><td></td></tr> - <tr><td><a href="https://wg21.link/P0602R4">P0602R4</a></td><td>LWG</td><td>variant and optional should propagate copy/move triviality</td><td>San Diego</td><td><i> </i></td><td></td></tr> + <tr><td><a href="https://wg21.link/P0602R4">P0602R4</a></td><td>LWG</td><td>variant and optional should propagate copy/move triviality</td><td>San Diego</td><td>Complete</td><td>8.0</td></tr> <tr><td><a href="https://wg21.link/P0608R3">P0608R3</a></td><td>LWG</td><td>A sane variant converting constructor</td><td>San Diego</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P0655R1">P0655R1</a></td><td>LWG</td><td>visit<R>: Explicit Return Type for visit</td><td>San Diego</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P0771R1">P0771R1</a></td><td>LWG</td><td>std::function move constructor should be noexcept</td><td>San Diego</td><td>Complete</td><td>6.0</td></tr> @@ -131,7 +131,7 @@ <tr><td><a href="https://wg21.link/P1123R0">P1123R0</a></td><td>LWG</td><td>Editorial Guidance for merging P0019r8 and P0528r3</td><td>San Diego</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P1148R0">P1148R0</a></td><td>LWG</td><td>Cleaning up Clause 20</td><td>San Diego</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P1165R1">P1165R1</a></td><td>LWG</td><td>Make stateful allocator propagation more consistent for <tt>operator+(basic_string)</tt></td><td>San Diego</td><td><i> </i></td><td></td></tr> - <tr><td><a href="https://wg21.link/P1209R0">P1209R0</a></td><td>LWG</td><td>Adopt Consistent Container Erasure from Library Fundamentals 2 for C++20</td><td>San Diego</td><td><i> </i></td><td></td></tr> + <tr><td><a href="https://wg21.link/P1209R0">P1209R0</a></td><td>LWG</td><td>Adopt Consistent Container Erasure from Library Fundamentals 2 for C++20</td><td>San Diego</td><td>Complete</td><td>8.0</td></tr> <tr><td><a href="https://wg21.link/P1210R0">P1210R0</a></td><td>LWG</td><td>Completing the Rebase of Library Fundamentals, Version 3, Working Draft</td><td>San Diego</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P1236R1">P1236R1</a></td><td>CWG</td><td>Alternative Wording for P0907R4 Signed Integers are Two's Complement</td><td>San Diego</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P1248R1">P1248R1</a></td><td>LWG</td><td>Remove CommonReference requirement from StrictWeakOrdering (a.k.a Fixing Relations)</td><td>San Diego</td><td><i> </i></td><td></td></tr> @@ -255,11 +255,11 @@ <tr><td><a href="https://wg21.link/LWG2184">2184</a></td><td>Muddled allocator requirements for <tt>match_results</tt> assignments</td><td>San Diego</td><td>Complete</td></tr> <tr><td><a href="https://wg21.link/LWG2412">2412</a></td><td><tt>promise::set_value()</tt> and <tt>promise::get_future()</tt> should not race</td><td>San Diego</td><td></td></tr> <tr><td><a href="https://wg21.link/LWG2499">2499</a></td><td><tt>operator>>(basic_istream&, CharT*)</tt> makes it hard to avoid buffer overflows</td><td>San Diego</td><td>Resolved by P0487R1</td></tr> - <tr><td><a href="https://wg21.link/LWG2682">2682</a></td><td><code>filesystem::copy()</code> won't create a symlink to a directory</td><td>San Diego</td><td></td></tr> + <tr><td><a href="https://wg21.link/LWG2682">2682</a></td><td><code>filesystem::copy()</code> won't create a symlink to a directory</td><td>San Diego</td><td>Nothing to do</td></tr> <tr><td><a href="https://wg21.link/LWG2697">2697</a></td><td>[concurr.ts] Behavior of <tt>future/shared_future</tt> unwrapping constructor when given an invalid <tt>future</tt></td><td>San Diego</td><td></td></tr> <tr><td><a href="https://wg21.link/LWG2797">2797</a></td><td>Trait precondition violations</td><td>San Diego</td><td>Resolved by 1285R0</td></tr> - <tr><td><a href="https://wg21.link/LWG2936">2936</a></td><td>Path comparison is defined in terms of the generic format</td><td>San Diego</td><td></td></tr> - <tr><td><a href="https://wg21.link/LWG2943">2943</a></td><td>Problematic specification of the wide version of <tt>basic_filebuf::open</tt></td><td>San Diego</td><td></td></tr> + <tr><td><a href="https://wg21.link/LWG2936">2936</a></td><td>Path comparison is defined in terms of the generic format</td><td>San Diego</td><td>Complete</td></tr> + <tr><td><a href="https://wg21.link/LWG2943">2943</a></td><td>Problematic specification of the wide version of <tt>basic_filebuf::open</tt></td><td>San Diego</td><td>Nothing to do</td></tr> <tr><td><a href="https://wg21.link/LWG2960">2960</a></td><td>[fund.ts.v3] <tt>nonesuch</tt> is insufficiently useless</td><td>San Diego</td><td></td></tr> <tr><td><a href="https://wg21.link/LWG2995">2995</a></td><td><tt>basic_stringbuf</tt> default constructor forbids it from using SSO capacity</td><td>San Diego</td><td></td></tr> <tr><td><a href="https://wg21.link/LWG2996">2996</a></td><td>Missing rvalue overloads for <tt>shared_ptr</tt> operations</td><td>San Diego</td><td></td></tr> @@ -270,8 +270,8 @@ <tr><td><a href="https://wg21.link/LWG3037">3037</a></td><td><tt>polymorphic_allocator</tt> and incomplete types</td><td>San Diego</td><td></td></tr> <tr><td><a href="https://wg21.link/LWG3038">3038</a></td><td><tt>polymorphic_allocator::allocate</tt> should not allow integer overflow to create vulnerabilities</td><td>San Diego</td><td></td></tr> <tr><td><a href="https://wg21.link/LWG3054">3054</a></td><td><tt>uninitialized_copy</tt> appears to not be able to meet its exception-safety guarantee</td><td>San Diego</td><td></td></tr> - <tr><td><a href="https://wg21.link/LWG3065">3065</a></td><td>LWG 2989 missed that all <tt>path</tt>'s other operators should be hidden friends as well</td><td>San Diego</td><td></td></tr> - <tr><td><a href="https://wg21.link/LWG3096">3096</a></td><td><tt>path::lexically_relative</tt> is confused by trailing slashes</td><td>San Diego</td><td></td></tr> + <tr><td><a href="https://wg21.link/LWG3065">3065</a></td><td>LWG 2989 missed that all <tt>path</tt>'s other operators should be hidden friends as well</td><td>San Diego</td><td>Complete</td></tr> + <tr><td><a href="https://wg21.link/LWG3096">3096</a></td><td><tt>path::lexically_relative</tt> is confused by trailing slashes</td><td>San Diego</td><td>Complete</td></tr> <tr><td><a href="https://wg21.link/LWG3116">3116</a></td><td><tt><i>OUTERMOST_ALLOC_TRAITS</i></tt> needs <tt>remove_reference_t</tt></td><td>San Diego</td><td></td></tr> <tr><td><a href="https://wg21.link/LWG3122">3122</a></td><td><tt>__cpp_lib_chrono_udls</tt> was accidentally dropped</td><td>San Diego</td><td><i>We've already made the update; but we don't support all the test macros. When we do, this will be closed</i></td></tr> <tr><td><a href="https://wg21.link/LWG3127">3127</a></td><td><tt>basic_osyncstream::rdbuf</tt> needs a <tt>const_cast</tt></td><td>San Diego</td><td></td></tr> @@ -282,7 +282,7 @@ <tr><td><a href="https://wg21.link/LWG3132">3132</a></td><td>Library needs to ban macros named <tt>expects</tt> or <tt>ensures</tt></td><td>San Diego</td><td><i>Nothing to do</i></td></tr> <tr><td><a href="https://wg21.link/LWG3134">3134</a></td><td>[fund.ts.v3] LFTSv3 contains extraneous [meta] variable templates that should have been deleted by P09961</td><td>San Diego</td><td>Resolved by P1210R0</td></tr> <tr><td><a href="https://wg21.link/LWG3137">3137</a></td><td>Header for <tt>__cpp_lib_to_chars</tt></td><td>San Diego</td><td><i>We've already made the update; but we don't support all the test macros. When we do, this will be closed</i></td></tr> - <tr><td><a href="https://wg21.link/LWG3145">3145</a></td><td><tt>file_clock</tt> breaks ABI for C++17 implementations</td><td>San Diego</td><td></td></tr> + <tr><td><a href="https://wg21.link/LWG3145">3145</a></td><td><tt>file_clock</tt> breaks ABI for C++17 implementations</td><td>San Diego</td><td>Complete</td></tr> <tr><td><a href="https://wg21.link/LWG3147">3147</a></td><td>Definitions of "likely" and "unlikely" are likely to cause problems</td><td>San Diego</td><td></td></tr> <tr><td><a href="https://wg21.link/LWG3148">3148</a></td><td><tt><concepts></tt> should be freestanding</td><td>San Diego</td><td></td></tr> <tr><td><a href="https://wg21.link/LWG3153">3153</a></td><td><tt>Common</tt> and <tt>common_type</tt> have too little in common</td><td>San Diego</td><td></td></tr> |