aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-06-16 21:04:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-06-16 21:04:04 +0000
commit8462a49537476f8c62bcabfe490226af0d7c1cae (patch)
treeadbbe01182274045b7a8a9085c8f160360b9bea9
parent74c4bc8d0eddcb4786594f1c6b598094fac43859 (diff)
downloadsrc-8462a49537476f8c62bcabfe490226af0d7c1cae.tar.gz
src-8462a49537476f8c62bcabfe490226af0d7c1cae.zip
Vendor import of libc++ trunk r305575:vendor/libc++/libc++-trunk-r305575
Notes
Notes: svn path=/vendor/libc++/dist/; revision=320019 svn path=/vendor/libc++/libc++-trunk-r305575/; revision=320020; tag=vendor/libc++/libc++-trunk-r305575
-rw-r--r--benchmarks/stringstream.bench.cpp38
-rw-r--r--include/__bsd_locale_fallbacks.h1
-rw-r--r--include/__config10
-rw-r--r--include/__functional_038
-rw-r--r--include/__functional_base17
-rw-r--r--include/array1
-rw-r--r--include/experimental/coroutine6
-rw-r--r--include/fstream7
-rw-r--r--include/functional6
-rw-r--r--include/locale77
-rw-r--r--include/memory177
-rw-r--r--include/numeric93
-rw-r--r--include/support/newlib/xlocale.h3
-rw-r--r--include/utility12
-rw-r--r--include/variant2
-rw-r--r--lib/CMakeLists.txt1
-rw-r--r--src/experimental/filesystem/operations.cpp2
-rw-r--r--src/locale.cpp2
-rw-r--r--src/vector.cpp16
-rw-r--r--test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.cxx1z.pass.cpp1
-rw-r--r--test/libcxx/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp1
-rw-r--r--test/libcxx/include_as_c.sh.cpp37
-rw-r--r--test/libcxx/utilities/utility/__is_inplace_index.pass.cpp34
-rw-r--r--test/libcxx/utilities/utility/__is_inplace_type.pass.cpp34
-rw-r--r--test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp25
-rw-r--r--test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.cpp36
-rw-r--r--test/std/containers/associative/map/map.ops/count0.pass.cpp7
-rw-r--r--test/std/containers/associative/map/map.ops/equal_range0.pass.cpp7
-rw-r--r--test/std/containers/associative/map/map.ops/find0.pass.cpp7
-rw-r--r--test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp7
-rw-r--r--test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp7
-rw-r--r--test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp7
-rw-r--r--test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp7
-rw-r--r--test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp7
-rw-r--r--test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp7
-rw-r--r--test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp7
-rw-r--r--test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp35
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp35
-rw-r--r--test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan.pass.cpp (renamed from test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_iter_iter_iter.pass.cpp)0
-rw-r--r--test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_init_op.pass.cpp (renamed from test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_iter_iter_iter_init_op.pass.cpp)0
-rw-r--r--test/std/numerics/numeric.ops/reduce/reduce.pass.cpp63
-rw-r--r--test/std/numerics/numeric.ops/reduce/reduce_init.pass.cpp67
-rw-r--r--test/std/numerics/numeric.ops/reduce/reduce_init_op.pass.cpp74
-rw-r--r--test/std/numerics/numeric.ops/transform.exclusive.scan/transform_exclusive_scan_init_bop_uop.pass.cpp (renamed from test/std/numerics/numeric.ops/transform.exclusive.scan/transform_exclusive_scan_iter_iter_iter_init_bop_uop.pass.cpp)6
-rw-r--r--test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp124
-rw-r--r--test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp95
-rw-r--r--test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp97
-rw-r--r--test/support/allocators.h2
-rw-r--r--test/support/is_transparent.h16
-rw-r--r--utils/libcxx/test/config.py19
50 files changed, 1188 insertions, 162 deletions
diff --git a/benchmarks/stringstream.bench.cpp b/benchmarks/stringstream.bench.cpp
new file mode 100644
index 000000000000..6023cf775bc8
--- /dev/null
+++ b/benchmarks/stringstream.bench.cpp
@@ -0,0 +1,38 @@
+#include "benchmark/benchmark_api.h"
+
+#include <sstream>
+double __attribute__((noinline)) istream_numbers();
+
+double istream_numbers() {
+ const char *a[] = {
+ "-6 69 -71 2.4882e-02 -100 101 -2.00005 5000000 -50000000",
+ "-25 71 7 -9.3262e+01 -100 101 -2.00005 5000000 -50000000",
+ "-14 53 46 -6.7026e-02 -100 101 -2.00005 5000000 -50000000"
+ };
+
+ int a1, a2, a3, a4, a5, a6, a7;
+ double f1 = 0.0, f2 = 0.0, q = 0.0;
+ for (int i=0; i < 3; i++) {
+ std::istringstream s(a[i]);
+ s >> a1
+ >> a2
+ >> a3
+ >> f1
+ >> a4
+ >> a5
+ >> f2
+ >> a6
+ >> a7;
+ q += (a1 + a2 + a3 + a4 + a5 + a6 + a7 + f1 + f2)/1000000;
+ }
+ return q;
+}
+
+static void BM_Istream_numbers(benchmark::State &state) {
+ double i = 0;
+ while (state.KeepRunning())
+ benchmark::DoNotOptimize(i += istream_numbers());
+}
+
+BENCHMARK(BM_Istream_numbers)->RangeMultiplier(2)->Range(1024, 4096);
+BENCHMARK_MAIN()
diff --git a/include/__bsd_locale_fallbacks.h b/include/__bsd_locale_fallbacks.h
index 3425ce659b7e..9489452905c1 100644
--- a/include/__bsd_locale_fallbacks.h
+++ b/include/__bsd_locale_fallbacks.h
@@ -15,6 +15,7 @@
#define _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H
#include <stdlib.h>
+#include <stdarg.h>
#include <memory>
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/include/__config b/include/__config
index 212a2d53136b..fc24a3bc9ba9 100644
--- a/include/__config
+++ b/include/__config
@@ -76,6 +76,9 @@
// its vtable and typeinfo to libc++ rather than having all other libraries
// using that class define their own copies.
#define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
+
+// Enable optimized version of __do_get_(un)signed which avoids redundant copies.
+#define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
#elif _LIBCPP_ABI_VERSION == 1
#if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
// Enable compiling copies of now inline methods into the dylib to support
@@ -289,7 +292,7 @@
# endif
#endif // !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN)
-#if __has_attribute(__no_sanitize__)
+#if __has_attribute(__no_sanitize__) && !defined(_LIBCPP_COMPILER_GCC)
#define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi")))
#else
#define _LIBCPP_NO_CFI
@@ -1132,8 +1135,6 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
# define _LIBCPP_HAS_NO_COROUTINES
#endif
-#endif // __cplusplus
-
// Decide whether to use availability macros.
#if !defined(_LIBCPP_BUILDING_LIBRARY) && \
!defined(_LIBCPP_DISABLE_AVAILABILITY) && \
@@ -1237,4 +1238,7 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
# endif
#endif // defined(_LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO)
+
+#endif // __cplusplus
+
#endif // _LIBCPP_CONFIG
diff --git a/include/__functional_03 b/include/__functional_03
index 1db7082eb3d6..13d8a3d96009 100644
--- a/include/__functional_03
+++ b/include/__functional_03
@@ -704,7 +704,7 @@ function<_Rp()>::target()
{
if (__f_ == 0)
return (_Tp*)0;
- return (_Tp*)__f_->target(typeid(_Tp));
+ return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
}
template<class _Rp>
@@ -980,7 +980,7 @@ function<_Rp(_A0)>::target()
{
if (__f_ == 0)
return (_Tp*)0;
- return (_Tp*)__f_->target(typeid(_Tp));
+ return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
}
template<class _Rp, class _A0>
@@ -1256,7 +1256,7 @@ function<_Rp(_A0, _A1)>::target()
{
if (__f_ == 0)
return (_Tp*)0;
- return (_Tp*)__f_->target(typeid(_Tp));
+ return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
}
template<class _Rp, class _A0, class _A1>
@@ -1532,7 +1532,7 @@ function<_Rp(_A0, _A1, _A2)>::target()
{
if (__f_ == 0)
return (_Tp*)0;
- return (_Tp*)__f_->target(typeid(_Tp));
+ return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
}
template<class _Rp, class _A0, class _A1, class _A2>
diff --git a/include/__functional_base b/include/__functional_base
index 0d2c2fc65015..79017fe759b4 100644
--- a/include/__functional_base
+++ b/include/__functional_base
@@ -548,16 +548,13 @@ template <class _Tp> void cref(const _Tp&&) = delete;
#endif
#if _LIBCPP_STD_VER > 11
-template <class _Tp1, class _Tp2 = void>
-struct __is_transparent
-{
-private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::is_transparent* = 0);
-public:
- static const bool value = sizeof(__test<_Tp1>(0)) == 1;
-};
+template <class _Tp, class, class = void>
+struct __is_transparent : false_type {};
+
+template <class _Tp, class _Up>
+struct __is_transparent<_Tp, _Up,
+ typename __void_t<typename _Tp::is_transparent>::type>
+ : true_type {};
#endif
// allocator_arg_t
diff --git a/include/array b/include/array
index 79f7e0d62c56..12780992e5c4 100644
--- a/include/array
+++ b/include/array
@@ -296,6 +296,7 @@ class _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> >
template <size_t _Ip, class _Tp, size_t _Size>
class _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, array<_Tp, _Size> >
{
+ static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::array)");
public:
typedef _Tp type;
};
diff --git a/include/experimental/coroutine b/include/experimental/coroutine
index 21c1ea566403..ce795ad452c0 100644
--- a/include/experimental/coroutine
+++ b/include/experimental/coroutine
@@ -250,9 +250,11 @@ public:
_LIBCPP_ALWAYS_INLINE
static coroutine_handle from_promise(_Promise& __promise) _NOEXCEPT {
+ typedef typename remove_cv<_Promise>::type _RawPromise;
coroutine_handle __tmp;
- __tmp.__handle_ = __builtin_coro_promise(_VSTD::addressof(__promise),
- __alignof(_Promise), true);
+ __tmp.__handle_ = __builtin_coro_promise(
+ _VSTD::addressof(const_cast<_RawPromise&>(__promise)),
+ __alignof(_Promise), true);
return __tmp;
}
};
diff --git a/include/fstream b/include/fstream
index e41a53af4a0c..ffd569839bd4 100644
--- a/include/fstream
+++ b/include/fstream
@@ -617,7 +617,7 @@ basic_filebuf<_CharT, _Traits>::underflow()
static_cast<size_t>(__extbufend_ - __extbufnext_));
codecvt_base::result __r;
__st_last_ = __st_;
- size_t __nr = fread((void*)__extbufnext_, 1, __nmemb, __file_);
+ size_t __nr = fread((void*) const_cast<char *>(__extbufnext_), 1, __nmemb, __file_);
if (__nr != 0)
{
if (!__cv_)
@@ -630,7 +630,8 @@ basic_filebuf<_CharT, _Traits>::underflow()
this->eback() + __ibs_, __inext);
if (__r == codecvt_base::noconv)
{
- this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
+ this->setg((char_type*)__extbuf_, (char_type*)__extbuf_,
+ (char_type*)const_cast<char *>(__extbufend_));
__c = traits_type::to_int_type(*this->gptr());
}
else if (__inext != this->eback() + __unget_sz)
@@ -722,7 +723,7 @@ basic_filebuf<_CharT, _Traits>::overflow(int_type __c)
return traits_type::eof();
if (__r == codecvt_base::partial)
{
- this->setp((char_type*)__e, this->pptr());
+ this->setp(const_cast<char_type*>(__e), this->pptr());
this->pbump(this->epptr() - this->pbase());
}
}
diff --git a/include/functional b/include/functional
index ea35697d3bbf..83a2e5a39a88 100644
--- a/include/functional
+++ b/include/functional
@@ -1941,8 +1941,8 @@ _Tp*
function<_Rp(_ArgTypes...)>::target() _NOEXCEPT
{
if (__f_ == 0)
- return (_Tp*)0;
- return (_Tp*)__f_->target(typeid(_Tp));
+ return nullptr;
+ return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
}
template<class _Rp, class ..._ArgTypes>
@@ -1951,7 +1951,7 @@ const _Tp*
function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT
{
if (__f_ == 0)
- return (const _Tp*)0;
+ return nullptr;
return (const _Tp*)__f_->target(typeid(_Tp));
}
diff --git a/include/locale b/include/locale
index 6aaa22ccaa15..d30d950c7f85 100644
--- a/include/locale
+++ b/include/locale
@@ -372,19 +372,57 @@ template <class _CharT>
struct __num_get
: protected __num_get_base
{
- static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
_CharT& __thousands_sep);
- static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
- unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
- unsigned* __g, unsigned*& __g_end, _CharT* __atoms);
+
static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp,
char* __a, char*& __a_end,
_CharT __decimal_point, _CharT __thousands_sep,
const string& __grouping, unsigned* __g,
unsigned*& __g_end, unsigned& __dc, _CharT* __atoms);
+#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
+ static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
+ static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
+ unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
+ unsigned* __g, unsigned*& __g_end, _CharT* __atoms);
+
+#else
+ static string __stage2_int_prep(ios_base& __iob, _CharT& __thousands_sep)
+ {
+ locale __loc = __iob.getloc();
+ const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+ __thousands_sep = __np.thousands_sep();
+ return __np.grouping();
+ }
+
+ const _CharT* __do_widen(ios_base& __iob, _CharT* __atoms) const
+ {
+ return __do_widen_p(__iob, __atoms);
+ }
+
+
+ static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
+ unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
+ unsigned* __g, unsigned*& __g_end, const _CharT* __atoms);
+private:
+ template<typename T>
+ const T* __do_widen_p(ios_base& __iob, T* __atoms) const
+ {
+ locale __loc = __iob.getloc();
+ use_facet<ctype<T> >(__loc).widen(__src, __src + 26, __atoms);
+ return __atoms;
+ }
+
+ const char* __do_widen_p(ios_base& __iob, char* __atoms) const
+ {
+ (void)__iob;
+ (void)__atoms;
+ return __src;
+ }
+#endif
};
+#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
template <class _CharT>
string
__num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep)
@@ -395,6 +433,7 @@ __num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& _
__thousands_sep = __np.thousands_sep();
return __np.grouping();
}
+#endif
template <class _CharT>
string
@@ -411,9 +450,16 @@ __num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT&
template <class _CharT>
int
+#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
unsigned* __g, unsigned*& __g_end, _CharT* __atoms)
+#else
+__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
+ unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
+ unsigned* __g, unsigned*& __g_end, const _CharT* __atoms)
+
+#endif
{
if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25]))
{
@@ -849,9 +895,16 @@ num_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e,
// Stage 1
int __base = this->__get_base(__iob);
// Stage 2
- char_type __atoms[26];
char_type __thousands_sep;
+ const int __atoms_size = 26;
+#ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
+ char_type __atoms1[__atoms_size];
+ const char_type *__atoms = this->__do_widen(__iob, __atoms1);
+ string __grouping = this->__stage2_int_prep(__iob, __thousands_sep);
+#else
+ char_type __atoms[__atoms_size];
string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
+#endif
string __buf;
__buf.resize(__buf.capacity());
char* __a = &__buf[0];
@@ -899,9 +952,16 @@ num_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e,
// Stage 1
int __base = this->__get_base(__iob);
// Stage 2
- char_type __atoms[26];
char_type __thousands_sep;
+ const int __atoms_size = 26;
+#ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
+ char_type __atoms1[__atoms_size];
+ const char_type *__atoms = this->__do_widen(__iob, __atoms1);
+ string __grouping = this->__stage2_int_prep(__iob, __thousands_sep);
+#else
+ char_type __atoms[__atoms_size];
string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
+#endif
string __buf;
__buf.resize(__buf.capacity());
char* __a = &__buf[0];
@@ -3960,7 +4020,8 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
this->egptr(), __inext);
if (__r == codecvt_base::noconv)
{
- this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
+ this->setg((char_type*)__extbuf_, (char_type*)__extbuf_,
+ (char_type*) const_cast<char *>(__extbufend_));
__c = *this->gptr();
}
else if (__inext != this->eback() + __unget_sz)
@@ -4048,7 +4109,7 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
return traits_type::eof();
if (__r == codecvt_base::partial)
{
- this->setp((char_type*)__e, this->pptr());
+ this->setp(const_cast<char_type *>(__e), this->pptr());
this->pbump(this->epptr() - this->pbase());
}
}
diff --git a/include/memory b/include/memory
index 711551d5732d..22706d029d5f 100644
--- a/include/memory
+++ b/include/memory
@@ -720,16 +720,12 @@ public:
// pointer_traits
+template <class _Tp, class = void>
+struct __has_element_type : false_type {};
+
template <class _Tp>
-struct __has_element_type
-{
-private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::element_type* = 0);
-public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
+struct __has_element_type<_Tp,
+ typename __void_t<typename _Tp::element_type>::type> : true_type {};
template <class _Ptr, bool = __has_element_type<_Ptr>::value>
struct __pointer_traits_element_type;
@@ -808,16 +804,12 @@ struct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1, _A2>, false>
#endif // _LIBCPP_HAS_NO_VARIADICS
+template <class _Tp, class = void>
+struct __has_difference_type : false_type {};
+
template <class _Tp>
-struct __has_difference_type
-{
-private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::difference_type* = 0);
-public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
+struct __has_difference_type<_Tp,
+ typename __void_t<typename _Tp::difference_type>::type> : true_type {};
template <class _Ptr, bool = __has_difference_type<_Ptr>::value>
struct __pointer_traits_difference_type
@@ -998,17 +990,12 @@ struct __rebind_pointer {
// allocator_traits
-struct __has_pointer_type_imp
-{
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::pointer* = 0);
-};
+template <class _Tp, class = void>
+struct __has_pointer_type : false_type {};
template <class _Tp>
-struct __has_pointer_type
- : public integral_constant<bool, sizeof(__has_pointer_type_imp::__test<_Tp>(0)) == 1>
-{
-};
+struct __has_pointer_type<_Tp,
+ typename __void_t<typename _Tp::pointer>::type> : true_type {};
namespace __pointer_type_imp
{
@@ -1033,16 +1020,12 @@ struct __pointer_type
typedef typename __pointer_type_imp::__pointer_type<_Tp, typename remove_reference<_Dp>::type>::type type;
};
+template <class _Tp, class = void>
+struct __has_const_pointer : false_type {};
+
template <class _Tp>
-struct __has_const_pointer
-{
-private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::const_pointer* = 0);
-public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
+struct __has_const_pointer<_Tp,
+ typename __void_t<typename _Tp::const_pointer>::type> : true_type {};
template <class _Tp, class _Ptr, class _Alloc, bool = __has_const_pointer<_Alloc>::value>
struct __const_pointer
@@ -1060,16 +1043,12 @@ struct __const_pointer<_Tp, _Ptr, _Alloc, false>
#endif
};
+template <class _Tp, class = void>
+struct __has_void_pointer : false_type {};
+
template <class _Tp>
-struct __has_void_pointer
-{
-private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::void_pointer* = 0);
-public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
+struct __has_void_pointer<_Tp,
+ typename __void_t<typename _Tp::void_pointer>::type> : true_type {};
template <class _Ptr, class _Alloc, bool = __has_void_pointer<_Alloc>::value>
struct __void_pointer
@@ -1087,16 +1066,12 @@ struct __void_pointer<_Ptr, _Alloc, false>
#endif
};
+template <class _Tp, class = void>
+struct __has_const_void_pointer : false_type {};
+
template <class _Tp>
-struct __has_const_void_pointer
-{
-private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::const_void_pointer* = 0);
-public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
+struct __has_const_void_pointer<_Tp,
+ typename __void_t<typename _Tp::const_void_pointer>::type> : true_type {};
template <class _Ptr, class _Alloc, bool = __has_const_void_pointer<_Alloc>::value>
struct __const_void_pointer
@@ -1130,16 +1105,12 @@ __to_raw_pointer(_Pointer __p) _NOEXCEPT
return _VSTD::__to_raw_pointer(__p.operator->());
}
+template <class _Tp, class = void>
+struct __has_size_type : false_type {};
+
template <class _Tp>
-struct __has_size_type
-{
-private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::size_type* = 0);
-public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
+struct __has_size_type<_Tp,
+ typename __void_t<typename _Tp::size_type>::type> : true_type {};
template <class _Alloc, class _DiffType, bool = __has_size_type<_Alloc>::value>
struct __size_type
@@ -1153,16 +1124,13 @@ struct __size_type<_Alloc, _DiffType, true>
typedef typename _Alloc::size_type type;
};
+template <class _Tp, class = void>
+struct __has_propagate_on_container_copy_assignment : false_type {};
+
template <class _Tp>
-struct __has_propagate_on_container_copy_assignment
-{
-private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::propagate_on_container_copy_assignment* = 0);
-public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
+struct __has_propagate_on_container_copy_assignment<_Tp,
+ typename __void_t<typename _Tp::propagate_on_container_copy_assignment>::type>
+ : true_type {};
template <class _Alloc, bool = __has_propagate_on_container_copy_assignment<_Alloc>::value>
struct __propagate_on_container_copy_assignment
@@ -1176,16 +1144,13 @@ struct __propagate_on_container_copy_assignment<_Alloc, true>
typedef typename _Alloc::propagate_on_container_copy_assignment type;
};
+template <class _Tp, class = void>
+struct __has_propagate_on_container_move_assignment : false_type {};
+
template <class _Tp>
-struct __has_propagate_on_container_move_assignment
-{
-private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::propagate_on_container_move_assignment* = 0);
-public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
+struct __has_propagate_on_container_move_assignment<_Tp,
+ typename __void_t<typename _Tp::propagate_on_container_move_assignment>::type>
+ : true_type {};
template <class _Alloc, bool = __has_propagate_on_container_move_assignment<_Alloc>::value>
struct __propagate_on_container_move_assignment
@@ -1199,16 +1164,13 @@ struct __propagate_on_container_move_assignment<_Alloc, true>
typedef typename _Alloc::propagate_on_container_move_assignment type;
};
+template <class _Tp, class = void>
+struct __has_propagate_on_container_swap : false_type {};
+
template <class _Tp>
-struct __has_propagate_on_container_swap
-{
-private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::propagate_on_container_swap* = 0);
-public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
+struct __has_propagate_on_container_swap<_Tp,
+ typename __void_t<typename _Tp::propagate_on_container_swap>::type>
+ : true_type {};
template <class _Alloc, bool = __has_propagate_on_container_swap<_Alloc>::value>
struct __propagate_on_container_swap
@@ -1222,16 +1184,13 @@ struct __propagate_on_container_swap<_Alloc, true>
typedef typename _Alloc::propagate_on_container_swap type;
};
+template <class _Tp, class = void>
+struct __has_is_always_equal : false_type {};
+
template <class _Tp>
-struct __has_is_always_equal
-{
-private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::is_always_equal* = 0);
-public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
+struct __has_is_always_equal<_Tp,
+ typename __void_t<typename _Tp::is_always_equal>::type>
+ : true_type {};
template <class _Alloc, bool = __has_is_always_equal<_Alloc>::value>
struct __is_always_equal
@@ -1884,7 +1843,7 @@ public:
return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));
}
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT
- {_VSTD::__libcpp_deallocate((void*)__p);}
+ {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p));}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
{return size_type(~0) / sizeof(_Tp);}
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
@@ -1900,7 +1859,7 @@ public:
void
construct(pointer __p)
{
- ::new((void*)__p) _Tp();
+ ::new((void*) const_cast<_Tp *>(__p)) _Tp();
}
# if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
@@ -1909,14 +1868,14 @@ public:
void
construct(pointer __p, _A0& __a0)
{
- ::new((void*)__p) _Tp(__a0);
+ ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0);
}
template <class _A0>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, const _A0& __a0)
{
- ::new((void*)__p) _Tp(__a0);
+ ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0);
}
# endif // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
template <class _A0, class _A1>
@@ -1924,28 +1883,28 @@ public:
void
construct(pointer __p, _A0& __a0, _A1& __a1)
{
- ::new((void*)__p) _Tp(__a0, __a1);
+ ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
}
template <class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, const _A0& __a0, _A1& __a1)
{
- ::new((void*)__p) _Tp(__a0, __a1);
+ ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
}
template <class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, _A0& __a0, const _A1& __a1)
{
- ::new((void*)__p) _Tp(__a0, __a1);
+ ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
}
template <class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, const _A0& __a0, const _A1& __a1)
{
- ::new((void*)__p) _Tp(__a0, __a1);
+ ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
}
#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
_LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
@@ -3890,7 +3849,9 @@ public:
template <class _Dp>
_LIBCPP_INLINE_VISIBILITY
_Dp* __get_deleter() const _NOEXCEPT
- {return (_Dp*)(__cntrl_ ? __cntrl_->__get_deleter(typeid(_Dp)) : 0);}
+ {return static_cast<_Dp*>(__cntrl_
+ ? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
+ : nullptr);}
#endif // _LIBCPP_NO_RTTI
#ifndef _LIBCPP_HAS_NO_VARIADICS
diff --git a/include/numeric b/include/numeric
index a84fb862b667..39e81934dfa1 100644
--- a/include/numeric
+++ b/include/numeric
@@ -25,6 +25,18 @@ template <class InputIterator, class T, class BinaryOperation>
T
accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);
+template<class InputIterator>
+ typename iterator_traits<InputIterator>::value_type
+ reduce(InputIterator first, InputIterator last); // C++17
+
+template<class InputIterator, class T>
+ T
+ reduce(InputIterator first, InputIterator last, T init); // C++17
+
+template<class InputIterator, class T, class BinaryOperation>
+ T
+ reduce(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); // C++17
+
template <class InputIterator1, class InputIterator2, class T>
T
inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init);
@@ -34,6 +46,23 @@ template <class InputIterator1, class InputIterator2, class T, class BinaryOpera
inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,
T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2);
+
+template<class InputIterator1, class InputIterator2, class T>
+ T
+ transform_reduce(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, T init); // C++17
+
+template<class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2>
+ T
+ transform_reduce(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, T init,
+ BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); // C++17
+
+template<class InputIterator, class T, class BinaryOperation, class UnaryOperation>
+ T
+ transform_reduce(InputIterator first, InputIterator last, T init,
+ BinaryOperation binary_op, UnaryOperation unary_op); // C++17
+
template <class InputIterator, class OutputIterator>
OutputIterator
partial_sum(InputIterator first, InputIterator last, OutputIterator result);
@@ -114,6 +143,35 @@ accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOpe
return __init;
}
+#if _LIBCPP_STD_VER > 14
+template <class _InputIterator, class _Tp, class _BinaryOp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+reduce(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOp __b)
+{
+ for (; __first != __last; ++__first)
+ __init = __b(__init, *__first);
+ return __init;
+}
+
+template <class _InputIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+reduce(_InputIterator __first, _InputIterator __last, _Tp __init)
+{
+ return _VSTD::reduce(__first, __last, __init, _VSTD::plus<>());
+}
+
+template <class _InputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename iterator_traits<_InputIterator>::value_type
+reduce(_InputIterator __first, _InputIterator __last)
+{
+ return _VSTD::reduce(__first, __last,
+ typename iterator_traits<_InputIterator>::value_type{});
+}
+#endif
+
template <class _InputIterator1, class _InputIterator2, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
@@ -135,6 +193,41 @@ inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2
return __init;
}
+#if _LIBCPP_STD_VER > 14
+template <class _InputIterator, class _Tp, class _BinaryOp, class _UnaryOp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+transform_reduce(_InputIterator __first, _InputIterator __last,
+ _Tp __init, _BinaryOp __b, _UnaryOp __u)
+{
+ for (; __first != __last; ++__first)
+ __init = __b(__init, __u(*__first));
+ return __init;
+}
+
+template <class _InputIterator1, class _InputIterator2,
+ class _Tp, class _BinaryOp1, class _BinaryOp2>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
+ _InputIterator2 __first2, _Tp __init, _BinaryOp1 __b1, _BinaryOp2 __b2)
+{
+ for (; __first1 != __last1; ++__first1, (void) ++__first2)
+ __init = __b1(__init, __b2(*__first1, *__first2));
+ return __init;
+}
+
+template <class _InputIterator1, class _InputIterator2, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
+ _InputIterator2 __first2, _Tp __init)
+{
+ return _VSTD::transform_reduce(__first1, __last1, __first2, __init,
+ _VSTD::plus<>(), _VSTD::multiplies<>());
+}
+#endif
+
template <class _InputIterator, class _OutputIterator>
inline _LIBCPP_INLINE_VISIBILITY
_OutputIterator
diff --git a/include/support/newlib/xlocale.h b/include/support/newlib/xlocale.h
index 4e4b23be8d6b..4b7e9b7495a0 100644
--- a/include/support/newlib/xlocale.h
+++ b/include/support/newlib/xlocale.h
@@ -16,7 +16,10 @@
#include <clocale>
#include <cwctype>
#include <ctype.h>
+#if !defined(__NEWLIB__) || __NEWLIB__ < 2 || \
+ __NEWLIB__ == 2 && __NEWLIB_MINOR__ < 5
#include <support/xlocale/__nop_locale_mgmt.h>
+#endif
#include <support/xlocale/__posix_l_fallback.h>
#include <support/xlocale/__strtonum_fallback.h>
diff --git a/include/utility b/include/utility
index be73207133b5..00e3cd208ecb 100644
--- a/include/utility
+++ b/include/utility
@@ -653,6 +653,12 @@ template <class _T1, class _T2>
class _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> >
: public integral_constant<size_t, 2> {};
+template <size_t _Ip, class _T1, class _T2>
+class _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> >
+{
+ static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>");
+};
+
template <class _T1, class _T2>
class _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> >
{
@@ -924,6 +930,12 @@ template <class _Tp> struct __is_inplace_type_imp<in_place_type_t<_Tp>> : true_t
template <class _Tp>
using __is_inplace_type = __is_inplace_type_imp<__uncvref_t<_Tp>>;
+template <class _Tp> struct __is_inplace_index_imp : false_type {};
+template <size_t _Idx> struct __is_inplace_index_imp<in_place_index_t<_Idx>> : true_type {};
+
+template <class _Tp>
+using __is_inplace_index = __is_inplace_index_imp<__uncvref_t<_Tp>>;
+
#endif // _LIBCPP_STD_VER > 14
template <class _Arg, class _Result>
diff --git a/include/variant b/include/variant
index 8505f3262a18..8711ef6eb387 100644
--- a/include/variant
+++ b/include/variant
@@ -278,7 +278,7 @@ struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const volatile _Tp>
template <size_t _Ip, class... _Types>
struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> {
- static_assert(_Ip < sizeof...(_Types));
+ static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>");
using type = __type_pack_element<_Ip, _Types...>;
};
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index fe45f5ac0fe5..f04ef82a83d6 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -1,6 +1,7 @@
set(LIBCXX_LIB_CMAKEFILES_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}" PARENT_SCOPE)
# Get sources
+# FIXME: Don't use glob here
file(GLOB LIBCXX_SOURCES ../src/*.cpp)
if(WIN32)
file(GLOB LIBCXX_WIN32_SOURCES ../src/support/win32/*.cpp)
diff --git a/src/experimental/filesystem/operations.cpp b/src/experimental/filesystem/operations.cpp
index 2856ae453a6b..e9bc0eb6e30e 100644
--- a/src/experimental/filesystem/operations.cpp
+++ b/src/experimental/filesystem/operations.cpp
@@ -842,7 +842,7 @@ void __rename(const path& from, const path& to, std::error_code *ec) {
}
void __resize_file(const path& p, std::uintmax_t size, std::error_code *ec) {
- if (::truncate(p.c_str(), static_cast<long>(size)) == -1)
+ if (::truncate(p.c_str(), static_cast<::off_t>(size)) == -1)
set_or_throw(ec, "resize_file", p);
else if (ec)
ec->clear();
diff --git a/src/locale.cpp b/src/locale.cpp
index 3d61fbede58a..3b4c83a09007 100644
--- a/src/locale.cpp
+++ b/src/locale.cpp
@@ -6158,6 +6158,4 @@ template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t,
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __vector_base_common<true>;
-
_LIBCPP_END_NAMESPACE_STD
diff --git a/src/vector.cpp b/src/vector.cpp
new file mode 100644
index 000000000000..300adaed5f47
--- /dev/null
+++ b/src/vector.cpp
@@ -0,0 +1,16 @@
+//===------------------------- vector.cpp ---------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "vector"
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __vector_base_common<true>;
+
+_LIBCPP_END_NAMESPACE_STD
diff --git a/test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.cxx1z.pass.cpp b/test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.cxx1z.pass.cpp
index ef3ef7519d69..28a9281b49c2 100644
--- a/test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.cxx1z.pass.cpp
+++ b/test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.cxx1z.pass.cpp
@@ -23,6 +23,7 @@
// However, for backwards compatibility, if _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
// is defined before including <algorithm>, then random_shuffle will be restored.
+// MODULES_DEFINES: _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
#define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
#include <algorithm>
diff --git a/test/libcxx/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp b/test/libcxx/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp
index 9b846939313b..f06dbb927acb 100644
--- a/test/libcxx/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp
+++ b/test/libcxx/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp
@@ -14,6 +14,7 @@
// However, for backwards compatibility, if _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
// is defined before including <functional>, then they will be restored.
+// MODULES_DEFINES: _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
#define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
#include <functional>
diff --git a/test/libcxx/include_as_c.sh.cpp b/test/libcxx/include_as_c.sh.cpp
new file mode 100644
index 000000000000..db50d835ec1f
--- /dev/null
+++ b/test/libcxx/include_as_c.sh.cpp
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// Test that the C wrapper headers can be included when compiling them as C.
+
+// NOTE: It's not common or recommended to have libc++ in the header search
+// path when compiling C files, but it does happen often enough.
+
+// RUN: %cxx -c -xc %s -fsyntax-only %flags %compile_flags -std=c99
+
+#include <complex.h>
+#include <ctype.h>
+#include <errno.h>
+#include <float.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <locale.h>
+#include <math.h>
+#include <setjmp.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tgmath.h>
+#include <wchar.h>
+#include <wctype.h>
+
+int main() {}
diff --git a/test/libcxx/utilities/utility/__is_inplace_index.pass.cpp b/test/libcxx/utilities/utility/__is_inplace_index.pass.cpp
new file mode 100644
index 000000000000..073cfac075f3
--- /dev/null
+++ b/test/libcxx/utilities/utility/__is_inplace_index.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
+
+// template <class _Tp> using __is_inplace_index
+
+#include <utility>
+
+struct S {};
+
+int main() {
+ using I = std::in_place_index_t<0>;
+ static_assert( std::__is_inplace_index<I>::value, "");
+ static_assert( std::__is_inplace_index<const I>::value, "");
+ static_assert( std::__is_inplace_index<const volatile I>::value, "");
+ static_assert( std::__is_inplace_index<I&>::value, "");
+ static_assert( std::__is_inplace_index<const I&>::value, "");
+ static_assert( std::__is_inplace_index<const volatile I&>::value, "");
+ static_assert( std::__is_inplace_index<I&&>::value, "");
+ static_assert( std::__is_inplace_index<const I&&>::value, "");
+ static_assert( std::__is_inplace_index<const volatile I&&>::value, "");
+ static_assert(!std::__is_inplace_index<std::in_place_type_t<int>>::value, "");
+ static_assert(!std::__is_inplace_index<std::in_place_t>::value, "");
+ static_assert(!std::__is_inplace_index<void>::value, "");
+ static_assert(!std::__is_inplace_index<int>::value, "");
+ static_assert(!std::__is_inplace_index<S>::value, "");
+}
diff --git a/test/libcxx/utilities/utility/__is_inplace_type.pass.cpp b/test/libcxx/utilities/utility/__is_inplace_type.pass.cpp
new file mode 100644
index 000000000000..54e22a0939da
--- /dev/null
+++ b/test/libcxx/utilities/utility/__is_inplace_type.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
+
+// template <class _Tp> using __is_inplace_type
+
+#include <utility>
+
+struct S {};
+
+int main() {
+ using T = std::in_place_type_t<int>;
+ static_assert( std::__is_inplace_type<T>::value, "");
+ static_assert( std::__is_inplace_type<const T>::value, "");
+ static_assert( std::__is_inplace_type<const volatile T>::value, "");
+ static_assert( std::__is_inplace_type<T&>::value, "");
+ static_assert( std::__is_inplace_type<const T&>::value, "");
+ static_assert( std::__is_inplace_type<const volatile T&>::value, "");
+ static_assert( std::__is_inplace_type<T&&>::value, "");
+ static_assert( std::__is_inplace_type<const T&&>::value, "");
+ static_assert( std::__is_inplace_type<const volatile T&&>::value, "");
+ static_assert(!std::__is_inplace_type<std::in_place_index_t<0>>::value, "");
+ static_assert(!std::__is_inplace_type<std::in_place_t>::value, "");
+ static_assert(!std::__is_inplace_type<void>::value, "");
+ static_assert(!std::__is_inplace_type<int>::value, "");
+ static_assert(!std::__is_inplace_type<S>::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
new file mode 100644
index 000000000000..2a92240a63d2
--- /dev/null
+++ b/test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// tuple_element<I, pair<T1, T2> >::type
+
+#include <utility>
+
+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>>"}}
+ }
+}
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
new file mode 100644
index 000000000000..f39a445b98af
--- /dev/null
+++ b/test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <variant>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+
+// template <size_t I, class T> struct variant_alternative; // undefined
+// template <size_t I, class T> struct variant_alternative<I, const T>;
+// template <size_t I, class T> struct variant_alternative<I, volatile T>;
+// template <size_t I, class T> struct variant_alternative<I, const volatile T>;
+// template <size_t I, class T>
+// using variant_alternative_t = typename variant_alternative<I, T>::type;
+//
+// template <size_t I, class... Types>
+// struct variant_alternative<I, variant<Types...>>;
+
+
+#include <variant>
+#include <cassert>
+
+
+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<>"}}
+ }
+}
diff --git a/test/std/containers/associative/map/map.ops/count0.pass.cpp b/test/std/containers/associative/map/map.ops/count0.pass.cpp
index 0278343006a8..1fa8c4a70bd9 100644
--- a/test/std/containers/associative/map/map.ops/count0.pass.cpp
+++ b/test/std/containers/associative/map/map.ops/count0.pass.cpp
@@ -28,7 +28,12 @@
int main()
{
+ {
typedef std::map<int, double, transparent_less> M;
-
M().count(C2Int{5});
+ }
+ {
+ typedef std::map<int, double, transparent_less_not_referenceable> M;
+ M().count(C2Int{5});
+ }
}
diff --git a/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp b/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp
index 3b98426868e4..c254fb6a7db7 100644
--- a/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp
+++ b/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp
@@ -28,7 +28,12 @@
int main()
{
+ {
typedef std::map<int, double, transparent_less> M;
-
M().equal_range(C2Int{5});
+ }
+ {
+ typedef std::map<int, double, transparent_less_not_referenceable> M;
+ M().equal_range(C2Int{5});
+ }
}
diff --git a/test/std/containers/associative/map/map.ops/find0.pass.cpp b/test/std/containers/associative/map/map.ops/find0.pass.cpp
index d7de579d8b44..76fe9242a476 100644
--- a/test/std/containers/associative/map/map.ops/find0.pass.cpp
+++ b/test/std/containers/associative/map/map.ops/find0.pass.cpp
@@ -28,7 +28,12 @@
int main()
{
+ {
typedef std::map<int, double, transparent_less> M;
-
M().find(C2Int{5});
+ }
+ {
+ typedef std::map<int, double, transparent_less_not_referenceable> M;
+ M().find(C2Int{5});
+ }
}
diff --git a/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp b/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp
index ea121df73002..de7a545b6497 100644
--- a/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp
+++ b/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp
@@ -28,7 +28,12 @@
int main()
{
+ {
typedef std::map<int, double, transparent_less> M;
-
M().lower_bound(C2Int{5});
+ }
+ {
+ typedef std::map<int, double, transparent_less_not_referenceable> M;
+ M().lower_bound(C2Int{5});
+ }
}
diff --git a/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp b/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp
index 2e597b85cf0c..94508d284fd2 100644
--- a/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp
+++ b/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp
@@ -28,7 +28,12 @@
int main()
{
+ {
typedef std::map<int, double, transparent_less> M;
-
M().upper_bound(C2Int{5});
+ }
+ {
+ typedef std::map<int, double, transparent_less_not_referenceable> M;
+ M().upper_bound(C2Int{5});
+ }
}
diff --git a/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp
index b993f4f89087..289d405739ac 100644
--- a/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp
+++ b/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp
@@ -28,7 +28,12 @@
int main()
{
+ {
typedef std::multimap<int, double, transparent_less> M;
-
M().count(C2Int{5});
+ }
+ {
+ typedef std::multimap<int, double, transparent_less_not_referenceable> M;
+ M().count(C2Int{5});
+ }
}
diff --git a/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp
index a3a51e6ccbf9..8cdd3c03372f 100644
--- a/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp
+++ b/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp
@@ -28,7 +28,12 @@
int main()
{
+ {
typedef std::multimap<int, double, transparent_less> M;
-
M().equal_range(C2Int{5});
+ }
+ {
+ typedef std::multimap<int, double, transparent_less_not_referenceable> M;
+ M().equal_range(C2Int{5});
+ }
}
diff --git a/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp
index 03a6e1883051..a06ec4d702d5 100644
--- a/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp
+++ b/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp
@@ -28,7 +28,12 @@
int main()
{
+ {
typedef std::multimap<int, double, transparent_less> M;
-
M().find(C2Int{5});
+ }
+ {
+ typedef std::multimap<int, double, transparent_less_not_referenceable> M;
+ M().find(C2Int{5});
+ }
}
diff --git a/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp
index 77927bb5abed..1000aa772b31 100644
--- a/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp
+++ b/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp
@@ -28,7 +28,12 @@
int main()
{
+ {
typedef std::multimap<int, double, transparent_less> M;
-
M().lower_bound(C2Int{5});
+ }
+ {
+ typedef std::multimap<int, double, transparent_less_not_referenceable> M;
+ M().lower_bound(C2Int{5});
+ }
}
diff --git a/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp
index 3f6852d085c3..1a572e9c5070 100644
--- a/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp
+++ b/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp
@@ -28,7 +28,12 @@
int main()
{
+ {
typedef std::multimap<int, double, transparent_less> M;
-
M().upper_bound(C2Int{5});
+ }
+ {
+ typedef std::multimap<int, double, transparent_less_not_referenceable> M;
+ M().upper_bound(C2Int{5});
+ }
}
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
new file mode 100644
index 000000000000..c9fe695f9cbd
--- /dev/null
+++ b/test/std/containers/sequences/array/array.tuple/tuple_element.fail.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <array>
+
+// tuple_element<I, array<T, N> >::type
+
+// Prevent -Warray-bounds from issuing a diagnostic when testing with clang verify.
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Warray-bounds"
+#endif
+
+#include <array>
+#include <cassert>
+
+
+// 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"
+
+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)"}}
+ }
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp
index 4a61047a830a..f996886c4ca7 100644
--- a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp
@@ -28,6 +28,39 @@
namespace coro = std::experimental;
+struct MyCoro {
+ struct promise_type {
+ void unhandled_exception() {}
+ void return_void() {}
+ coro::suspend_never initial_suspend() { return {}; }
+ coro::suspend_never final_suspend() { return {}; }
+ MyCoro get_return_object() {
+ do_runtime_test();
+ return {};
+ }
+ void do_runtime_test() {
+ // Test that a coroutine_handle<const T> can be created from a const
+ // promise_type and that it represents the same coroutine as
+ // coroutine_handle<T>
+ using CH = coro::coroutine_handle<promise_type>;
+ using CCH = coro::coroutine_handle<const promise_type>;
+ const auto &cthis = *this;
+ CH h = CH::from_promise(*this);
+ CCH h2 = CCH::from_promise(*this);
+ CCH h3 = CCH::from_promise(cthis);
+ assert(&h.promise() == this);
+ assert(&h2.promise() == this);
+ assert(&h3.promise() == this);
+ assert(h.address() == h2.address());
+ assert(h2.address() == h3.address());
+ }
+ };
+};
+
+MyCoro do_runtime_test() {
+ co_await coro::suspend_never{};
+}
+
template <class Promise>
void do_test(coro::coroutine_handle<Promise>&& H) {
@@ -46,4 +79,6 @@ void do_test(coro::coroutine_handle<Promise>&& H) {
int main()
{
do_test(coro::coroutine_handle<int>{});
+ do_test(coro::coroutine_handle<const int>{});
+ do_runtime_test();
}
diff --git a/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_iter_iter_iter.pass.cpp b/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan.pass.cpp
index 6fdd288e2d6a..6fdd288e2d6a 100644
--- a/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_iter_iter_iter.pass.cpp
+++ b/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan.pass.cpp
diff --git a/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_iter_iter_iter_init_op.pass.cpp b/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_init_op.pass.cpp
index ba1673fe467f..ba1673fe467f 100644
--- a/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_iter_iter_iter_init_op.pass.cpp
+++ b/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_init_op.pass.cpp
diff --git a/test/std/numerics/numeric.ops/reduce/reduce.pass.cpp b/test/std/numerics/numeric.ops/reduce/reduce.pass.cpp
new file mode 100644
index 000000000000..aa055e70d4f8
--- /dev/null
+++ b/test/std/numerics/numeric.ops/reduce/reduce.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <numeric>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// template<class InputIterator>
+// typename iterator_traits<InputIterator>::value_type
+// reduce(InputIterator first, InputIterator last);
+
+#include <numeric>
+#include <cassert>
+
+#include "test_iterators.h"
+
+template <class Iter, class T>
+void
+test(Iter first, Iter last, T x)
+{
+ static_assert( std::is_same_v<typename std::iterator_traits<decltype(first)>::value_type,
+ decltype(std::reduce(first, last))> );
+ assert(std::reduce(first, last) == x);
+}
+
+template <class Iter>
+void
+test()
+{
+ int ia[] = {1, 2, 3, 4, 5, 6};
+ unsigned sa = sizeof(ia) / sizeof(ia[0]);
+ test(Iter(ia), Iter(ia), 0);
+ test(Iter(ia), Iter(ia+1), 1);
+ test(Iter(ia), Iter(ia+2), 3);
+ test(Iter(ia), Iter(ia+sa), 21);
+}
+
+template <typename T>
+void test_return_type()
+{
+ T *p = nullptr;
+ static_assert( std::is_same_v<T, decltype(std::reduce(p, p))> );
+}
+
+int main()
+{
+ test_return_type<char>();
+ test_return_type<int>();
+ test_return_type<unsigned long>();
+ test_return_type<float>();
+ test_return_type<double>();
+
+ test<input_iterator<const int*> >();
+ test<forward_iterator<const int*> >();
+ test<bidirectional_iterator<const int*> >();
+ test<random_access_iterator<const int*> >();
+ test<const int*>();
+}
diff --git a/test/std/numerics/numeric.ops/reduce/reduce_init.pass.cpp b/test/std/numerics/numeric.ops/reduce/reduce_init.pass.cpp
new file mode 100644
index 000000000000..480ead11c734
--- /dev/null
+++ b/test/std/numerics/numeric.ops/reduce/reduce_init.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <numeric>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// template<class InputIterator, class T>
+// T reduce(InputIterator first, InputIterator last, T init);
+
+#include <numeric>
+#include <cassert>
+
+#include "test_iterators.h"
+
+template <class Iter, class T>
+void
+test(Iter first, Iter last, T init, T x)
+{
+ static_assert( std::is_same_v<T, decltype(std::reduce(first, last, init))> );
+ assert(std::reduce(first, last, init) == x);
+}
+
+template <class Iter>
+void
+test()
+{
+ int ia[] = {1, 2, 3, 4, 5, 6};
+ unsigned sa = sizeof(ia) / sizeof(ia[0]);
+ test(Iter(ia), Iter(ia), 0, 0);
+ test(Iter(ia), Iter(ia), 1, 1);
+ test(Iter(ia), Iter(ia+1), 0, 1);
+ test(Iter(ia), Iter(ia+1), 2, 3);
+ test(Iter(ia), Iter(ia+2), 0, 3);
+ test(Iter(ia), Iter(ia+2), 3, 6);
+ test(Iter(ia), Iter(ia+sa), 0, 21);
+ test(Iter(ia), Iter(ia+sa), 4, 25);
+}
+
+template <typename T, typename Init>
+void test_return_type()
+{
+ T *p = nullptr;
+ static_assert( std::is_same_v<Init, decltype(std::reduce(p, p, Init{}))> );
+}
+
+int main()
+{
+ test_return_type<char, int>();
+ test_return_type<int, int>();
+ test_return_type<int, unsigned long>();
+ test_return_type<float, int>();
+ test_return_type<short, float>();
+ test_return_type<double, char>();
+ test_return_type<char, double>();
+
+ test<input_iterator<const int*> >();
+ test<forward_iterator<const int*> >();
+ test<bidirectional_iterator<const int*> >();
+ test<random_access_iterator<const int*> >();
+ test<const int*>();
+}
diff --git a/test/std/numerics/numeric.ops/reduce/reduce_init_op.pass.cpp b/test/std/numerics/numeric.ops/reduce/reduce_init_op.pass.cpp
new file mode 100644
index 000000000000..5238a1f2ed5b
--- /dev/null
+++ b/test/std/numerics/numeric.ops/reduce/reduce_init_op.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <numeric>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// template<class InputIterator, class T, class BinaryOperation>
+// T reduce(InputIterator first, InputIterator last, T init, BinaryOperation op);
+
+#include <numeric>
+#include <cassert>
+
+#include "test_iterators.h"
+
+template <class Iter, class T, class Op>
+void
+test(Iter first, Iter last, T init, Op op, T x)
+{
+ static_assert( std::is_same_v<T, decltype(std::reduce(first, last, init, op))>, "" );
+ assert(std::reduce(first, last, init, op) == x);
+}
+
+template <class Iter>
+void
+test()
+{
+ int ia[] = {1, 2, 3, 4, 5, 6};
+ unsigned sa = sizeof(ia) / sizeof(ia[0]);
+ test(Iter(ia), Iter(ia), 0, std::plus<>(), 0);
+ test(Iter(ia), Iter(ia), 1, std::multiplies<>(), 1);
+ test(Iter(ia), Iter(ia+1), 0, std::plus<>(), 1);
+ test(Iter(ia), Iter(ia+1), 2, std::multiplies<>(), 2);
+ test(Iter(ia), Iter(ia+2), 0, std::plus<>(), 3);
+ test(Iter(ia), Iter(ia+2), 3, std::multiplies<>(), 6);
+ test(Iter(ia), Iter(ia+sa), 0, std::plus<>(), 21);
+ test(Iter(ia), Iter(ia+sa), 4, std::multiplies<>(), 2880);
+}
+
+template <typename T, typename Init>
+void test_return_type()
+{
+ T *p = nullptr;
+ static_assert( std::is_same_v<Init, decltype(std::reduce(p, p, Init{}, std::plus<>()))>, "" );
+}
+
+int main()
+{
+ test_return_type<char, int>();
+ test_return_type<int, int>();
+ test_return_type<int, unsigned long>();
+ test_return_type<float, int>();
+ test_return_type<short, float>();
+ test_return_type<double, char>();
+ test_return_type<char, double>();
+
+ test<input_iterator<const int*> >();
+ test<forward_iterator<const int*> >();
+ test<bidirectional_iterator<const int*> >();
+ test<random_access_iterator<const int*> >();
+ test<const int*>();
+
+// Make sure the math is done using the correct type
+ {
+ auto v = {1, 2, 3, 4, 5, 6, 7, 8};
+ unsigned res = std::reduce(v.begin(), v.end(), 1U, std::multiplies<>());
+ assert(res == 40320); // 8! will not fit into a char
+ }
+}
diff --git a/test/std/numerics/numeric.ops/transform.exclusive.scan/transform_exclusive_scan_iter_iter_iter_init_bop_uop.pass.cpp b/test/std/numerics/numeric.ops/transform.exclusive.scan/transform_exclusive_scan_init_bop_uop.pass.cpp
index 3bfb336a03f9..2370e9ea9137 100644
--- a/test/std/numerics/numeric.ops/transform.exclusive.scan/transform_exclusive_scan_iter_iter_iter_init_bop_uop.pass.cpp
+++ b/test/std/numerics/numeric.ops/transform.exclusive.scan/transform_exclusive_scan_init_bop_uop.pass.cpp
@@ -122,6 +122,12 @@ void basic_tests()
assert(v[i] == 40 + triangle(i));
}
+ {
+ std::vector<int> v, res;
+ std::transform_exclusive_scan(v.begin(), v.end(), std::back_inserter(res), 40, std::plus<>(), identity<>());
+ assert(res.empty());
+ }
+
// Make sure that the calculations are done using the init typedef
{
std::vector<unsigned char> v(10);
diff --git a/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp b/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
new file mode 100644
index 000000000000..c283f3e29722
--- /dev/null
+++ b/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
@@ -0,0 +1,124 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <numeric>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// template <class InputIterator1, class T,
+// class BinaryOperation, class UnaryOperation>
+// T transform_reduce(InputIterator1 first1, InputIterator1 last1,
+// T init, BinaryOperation binary_op, UnaryOperation unary_op);
+//
+
+#include <numeric>
+#include <cassert>
+
+#include "test_iterators.h"
+
+template <class _Tp = void>
+struct identity : std::unary_function<_Tp, _Tp>
+{
+ constexpr const _Tp& operator()(const _Tp& __x) const { return __x;}
+};
+
+template <>
+struct identity<void>
+{
+ template <class _Tp>
+ constexpr auto operator()(_Tp&& __x) const
+ _NOEXCEPT_(noexcept(_VSTD::forward<_Tp>(__x)))
+ -> decltype (_VSTD::forward<_Tp>(__x))
+ { return _VSTD::forward<_Tp>(__x); }
+};
+
+
+template <class _Tp = void>
+struct twice
+{
+ constexpr const _Tp operator()(const _Tp& __x) const noexcept { return 2 * __x; }
+};
+
+template <>
+struct twice<void>
+{
+ template <class _Tp>
+ constexpr auto operator()(const _Tp& __x) const
+ _NOEXCEPT_(noexcept(2 * __x))
+ -> decltype (2 * __x)
+ { return 2 * __x; }
+};
+
+template <class Iter1, class T, class BOp, class UOp>
+void
+test(Iter1 first1, Iter1 last1, T init, BOp bOp, UOp uOp, T x)
+{
+ static_assert( std::is_same_v<T,
+ decltype(std::transform_reduce(first1, last1, init, bOp, uOp))> );
+ assert(std::transform_reduce(first1, last1, init, bOp, uOp) == x);
+}
+
+template <class Iter>
+void
+test()
+{
+ int ia[] = {1, 2, 3, 4, 5, 6};
+ unsigned sa = sizeof(ia) / sizeof(ia[0]);
+
+ test(Iter(ia), Iter(ia), 0, std::plus<>(), identity<>(), 0);
+ test(Iter(ia), Iter(ia), 1, std::multiplies<>(), identity<>(), 1);
+ test(Iter(ia), Iter(ia+1), 0, std::multiplies<>(), identity<>(), 0);
+ test(Iter(ia), Iter(ia+1), 2, std::plus<>(), identity<>(), 3);
+ test(Iter(ia), Iter(ia+2), 0, std::plus<>(), identity<>(), 3);
+ test(Iter(ia), Iter(ia+2), 3, std::multiplies<>(), identity<>(), 6);
+ test(Iter(ia), Iter(ia+sa), 4, std::multiplies<>(), identity<>(), 2880);
+ test(Iter(ia), Iter(ia+sa), 4, std::plus<>(), identity<>(), 25);
+
+ test(Iter(ia), Iter(ia), 0, std::plus<>(), twice<>(), 0);
+ test(Iter(ia), Iter(ia), 1, std::multiplies<>(), twice<>(), 1);
+ test(Iter(ia), Iter(ia+1), 0, std::multiplies<>(), twice<>(), 0);
+ test(Iter(ia), Iter(ia+1), 2, std::plus<>(), twice<>(), 4);
+ test(Iter(ia), Iter(ia+2), 0, std::plus<>(), twice<>(), 6);
+ test(Iter(ia), Iter(ia+2), 3, std::multiplies<>(), twice<>(), 24);
+ test(Iter(ia), Iter(ia+sa), 4, std::multiplies<>(), twice<>(), 184320); // 64 * 2880
+ test(Iter(ia), Iter(ia+sa), 4, std::plus<>(), twice<>(), 46);
+}
+
+template <typename T, typename Init>
+void test_return_type()
+{
+ T *p = nullptr;
+ static_assert( std::is_same_v<Init,
+ decltype(std::transform_reduce(p, p, Init{}, std::plus<>(), identity<>()))> );
+}
+
+int main()
+{
+ test_return_type<char, int>();
+ test_return_type<int, int>();
+ test_return_type<int, unsigned long>();
+ test_return_type<float, int>();
+ test_return_type<short, float>();
+ test_return_type<double, char>();
+ test_return_type<char, double>();
+
+// All the iterator categories
+ test<input_iterator <const int*> >();
+ test<forward_iterator <const int*> >();
+ test<bidirectional_iterator<const int*> >();
+ test<random_access_iterator<const int*> >();
+ test<const int*>();
+ test< int*>();
+
+// Make sure the math is done using the correct type
+ {
+ auto v = {1, 2, 3, 4, 5, 6};
+ unsigned res = std::transform_reduce(v.begin(), v.end(), 1U, std::multiplies<>(), twice<>());
+ assert(res == 46080); // 6! * 64 will not fit into a char
+ }
+}
diff --git a/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp b/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
new file mode 100644
index 000000000000..f36b7d49410b
--- /dev/null
+++ b/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <numeric>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// template <class InputIterator1, class InputIterator2, class T>
+// T transform_reduce(InputIterator1 first1, InputIterator1 last1,
+// InputIterator2 first2, T init);
+
+
+#include <numeric>
+#include <cassert>
+
+#include "test_iterators.h"
+
+template <class Iter1, class Iter2, class T>
+void
+test(Iter1 first1, Iter1 last1, Iter2 first2, T init, T x)
+{
+ static_assert( std::is_same_v<T,
+ decltype(std::transform_reduce(first1, last1, first2, init))> );
+ assert(std::transform_reduce(first1, last1, first2, init) == x);
+}
+
+template <class SIter, class UIter>
+void
+test()
+{
+ int ia[] = {1, 2, 3, 4, 5, 6};
+ unsigned int ua[] = {2, 4, 6, 8, 10,12};
+ unsigned sa = sizeof(ia) / sizeof(ia[0]);
+ assert(sa == sizeof(ua) / sizeof(ua[0])); // just to be sure
+
+ test(SIter(ia), SIter(ia), UIter(ua), 0, 0);
+ test(UIter(ua), UIter(ua), SIter(ia), 1, 1);
+ test(SIter(ia), SIter(ia+1), UIter(ua), 0, 2);
+ test(UIter(ua), UIter(ua+1), SIter(ia), 2, 4);
+ test(SIter(ia), SIter(ia+2), UIter(ua), 0, 10);
+ test(UIter(ua), UIter(ua+2), SIter(ia), 3, 13);
+ test(SIter(ia), SIter(ia+sa), UIter(ua), 0, 182);
+ test(UIter(ua), UIter(ua+sa), SIter(ia), 4, 186);
+}
+
+template <typename T, typename Init>
+void test_return_type()
+{
+ T *p = nullptr;
+ static_assert( std::is_same_v<Init,
+ decltype(std::transform_reduce(p, p, p, Init{}))> );
+}
+
+int main()
+{
+ test_return_type<char, int>();
+ test_return_type<int, int>();
+ test_return_type<int, unsigned long>();
+ test_return_type<float, int>();
+ test_return_type<short, float>();
+ test_return_type<double, char>();
+ test_return_type<char, double>();
+
+// All the iterator categories
+ test<input_iterator <const int*>, input_iterator <const unsigned int*> >();
+ test<input_iterator <const int*>, forward_iterator <const unsigned int*> >();
+ test<input_iterator <const int*>, bidirectional_iterator<const unsigned int*> >();
+ test<input_iterator <const int*>, random_access_iterator<const unsigned int*> >();
+
+ test<forward_iterator <const int*>, input_iterator <const unsigned int*> >();
+ test<forward_iterator <const int*>, forward_iterator <const unsigned int*> >();
+ test<forward_iterator <const int*>, bidirectional_iterator<const unsigned int*> >();
+ test<forward_iterator <const int*>, random_access_iterator<const unsigned int*> >();
+
+ test<bidirectional_iterator<const int*>, input_iterator <const unsigned int*> >();
+ test<bidirectional_iterator<const int*>, forward_iterator <const unsigned int*> >();
+ test<bidirectional_iterator<const int*>, bidirectional_iterator<const unsigned int*> >();
+ test<bidirectional_iterator<const int*>, random_access_iterator<const unsigned int*> >();
+
+ test<random_access_iterator<const int*>, input_iterator <const unsigned int*> >();
+ test<random_access_iterator<const int*>, forward_iterator <const unsigned int*> >();
+ test<random_access_iterator<const int*>, bidirectional_iterator<const unsigned int*> >();
+ test<random_access_iterator<const int*>, random_access_iterator<const unsigned int*> >();
+
+// just plain pointers (const vs. non-const, too)
+ test<const int*, const unsigned int *>();
+ test<const int*, unsigned int *>();
+ test< int*, const unsigned int *>();
+ test< int*, unsigned int *>();
+}
diff --git a/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp b/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
new file mode 100644
index 000000000000..b1b53293b991
--- /dev/null
+++ b/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <numeric>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// template <class InputIterator1, class InputIterator2, class T,
+// class BinaryOperation1, class BinaryOperation2>
+// T transform_reduce(InputIterator1 first1, InputIterator1 last1,
+// InputIterator2 first2, T init,
+// BinaryOperation1 binary_op1, BinaryOperation2 binary_op2);
+//
+
+#include <numeric>
+#include <cassert>
+
+#include "test_iterators.h"
+
+template <class Iter1, class Iter2, class T, class Op1, class Op2>
+void
+test(Iter1 first1, Iter1 last1, Iter2 first2, T init, Op1 op1, Op2 op2, T x)
+{
+ static_assert( std::is_same_v<T,
+ decltype(std::transform_reduce(first1, last1, first2, init, op1, op2))> );
+ assert(std::transform_reduce(first1, last1, first2, init, op1, op2) == x);
+}
+
+template <class SIter, class UIter>
+void
+test()
+{
+ int ia[] = {1, 2, 3, 4, 5, 6};
+ unsigned int ua[] = {2, 4, 6, 8, 10,12};
+ unsigned sa = sizeof(ia) / sizeof(ia[0]);
+ assert(sa == sizeof(ua) / sizeof(ua[0])); // just to be sure
+
+ test(SIter(ia), SIter(ia), UIter(ua), 0, std::plus<>(), std::multiplies<>(), 0);
+ test(UIter(ua), UIter(ua), SIter(ia), 1, std::multiplies<>(), std::plus<>(), 1);
+ test(SIter(ia), SIter(ia+1), UIter(ua), 0, std::multiplies<>(), std::plus<>(), 0);
+ test(UIter(ua), UIter(ua+1), SIter(ia), 2, std::plus<>(), std::multiplies<>(), 4);
+ test(SIter(ia), SIter(ia+2), UIter(ua), 0, std::plus<>(), std::multiplies<>(), 10);
+ test(UIter(ua), UIter(ua+2), SIter(ia), 3, std::multiplies<>(), std::plus<>(), 54);
+ test(SIter(ia), SIter(ia+sa), UIter(ua), 4, std::multiplies<>(), std::plus<>(), 2099520);
+ test(UIter(ua), UIter(ua+sa), SIter(ia), 4, std::plus<>(), std::multiplies<>(), 186);
+}
+
+template <typename T, typename Init>
+void test_return_type()
+{
+ T *p = nullptr;
+ static_assert( std::is_same_v<Init,
+ decltype(std::transform_reduce(p, p, p, Init{}, std::plus<>(), std::multiplies<>()))> );
+}
+
+int main()
+{
+ test_return_type<char, int>();
+ test_return_type<int, int>();
+ test_return_type<int, unsigned long>();
+ test_return_type<float, int>();
+ test_return_type<short, float>();
+ test_return_type<double, char>();
+ test_return_type<char, double>();
+
+// All the iterator categories
+ test<input_iterator <const int*>, input_iterator <const unsigned int*> >();
+ test<input_iterator <const int*>, forward_iterator <const unsigned int*> >();
+ test<input_iterator <const int*>, bidirectional_iterator<const unsigned int*> >();
+ test<input_iterator <const int*>, random_access_iterator<const unsigned int*> >();
+
+ test<forward_iterator <const int*>, input_iterator <const unsigned int*> >();
+ test<forward_iterator <const int*>, forward_iterator <const unsigned int*> >();
+ test<forward_iterator <const int*>, bidirectional_iterator<const unsigned int*> >();
+ test<forward_iterator <const int*>, random_access_iterator<const unsigned int*> >();
+
+ test<bidirectional_iterator<const int*>, input_iterator <const unsigned int*> >();
+ test<bidirectional_iterator<const int*>, forward_iterator <const unsigned int*> >();
+ test<bidirectional_iterator<const int*>, bidirectional_iterator<const unsigned int*> >();
+ test<bidirectional_iterator<const int*>, random_access_iterator<const unsigned int*> >();
+
+ test<random_access_iterator<const int*>, input_iterator <const unsigned int*> >();
+ test<random_access_iterator<const int*>, forward_iterator <const unsigned int*> >();
+ test<random_access_iterator<const int*>, bidirectional_iterator<const unsigned int*> >();
+ test<random_access_iterator<const int*>, random_access_iterator<const unsigned int*> >();
+
+// just plain pointers (const vs. non-const, too)
+ test<const int*, const unsigned int *>();
+ test<const int*, unsigned int *>();
+ test< int*, const unsigned int *>();
+ test< int*, unsigned int *>();
+}
diff --git a/test/support/allocators.h b/test/support/allocators.h
index b1eea8d0b683..00e9a0c13ce7 100644
--- a/test/support/allocators.h
+++ b/test/support/allocators.h
@@ -104,7 +104,7 @@ public:
T* allocate(std::size_t, const void* hint)
{
allocate_called = true;
- return (T*)hint;
+ return (T*) const_cast<void *>(hint);
}
};
diff --git a/test/support/is_transparent.h b/test/support/is_transparent.h
index 541689314b8b..f7cdbbc14ccd 100644
--- a/test/support/is_transparent.h
+++ b/test/support/is_transparent.h
@@ -22,7 +22,17 @@ struct transparent_less
noexcept(noexcept(std::forward<T>(t) < std::forward<U>(u)))
-> decltype (std::forward<T>(t) < std::forward<U>(u))
{ return std::forward<T>(t) < std::forward<U>(u); }
- typedef void is_transparent; // correct
+ using is_transparent = void; // correct
+};
+
+struct transparent_less_not_referenceable
+{
+ template <class T, class U>
+ constexpr auto operator()(T&& t, U&& u) const
+ noexcept(noexcept(std::forward<T>(t) < std::forward<U>(u)))
+ -> decltype (std::forward<T>(t) < std::forward<U>(u))
+ { return std::forward<T>(t) < std::forward<U>(u); }
+ using is_transparent = void () const &; // it's a type; a weird one, but a type
};
struct transparent_less_no_type
@@ -33,7 +43,7 @@ struct transparent_less_no_type
-> decltype (std::forward<T>(t) < std::forward<U>(u))
{ return std::forward<T>(t) < std::forward<U>(u); }
private:
-// typedef void is_transparent; // error - should exist
+// using is_transparent = void; // error - should exist
};
struct transparent_less_private
@@ -44,7 +54,7 @@ struct transparent_less_private
-> decltype (std::forward<T>(t) < std::forward<U>(u))
{ return std::forward<T>(t) < std::forward<U>(u); }
private:
- typedef void is_transparent; // error - should be accessible
+ using is_transparent = void; // error - should be accessible
};
struct transparent_less_not_a_type
diff --git a/utils/libcxx/test/config.py b/utils/libcxx/test/config.py
index 0fbc2cf4ea62..96b3df55ede7 100644
--- a/utils/libcxx/test/config.py
+++ b/utils/libcxx/test/config.py
@@ -108,6 +108,11 @@ class Configuration(object):
return check_value(val, env_var)
return check_value(conf_val, name)
+ def get_modules_enabled(self):
+ return self.get_lit_bool('enable_modules',
+ default=False,
+ env_var='LIBCXX_ENABLE_MODULES')
+
def make_static_lib_name(self, name):
"""Return the full filename for the specified library name"""
if self.is_windows:
@@ -631,9 +636,19 @@ class Configuration(object):
# The __config_site header should be non-empty. Otherwise it should
# have never been emitted by CMake.
assert len(feature_macros) > 0
+ # FIXME: This is a hack that should be fixed using module maps (or something)
+ # If modules are enabled then we have to lift all of the definitions
+ # in __config_site onto the command line.
+ modules_enabled = self.get_modules_enabled()
+ self.cxx.compile_flags += ['-Wno-macro-redefined']
# Transform each macro name into the feature name used in the tests.
# Ex. _LIBCPP_HAS_NO_THREADS -> libcpp-has-no-threads
for m in feature_macros:
+ if modules_enabled:
+ define = '-D%s' % m
+ if feature_macros[m]:
+ define += '=%s' % (feature_macros[m])
+ self.cxx.compile_flags += [define]
if m == '_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS':
continue
if m == '_LIBCPP_ABI_VERSION':
@@ -976,9 +991,7 @@ class Configuration(object):
if platform.system() != 'Darwin':
modules_flags += ['-Xclang', '-fmodules-local-submodule-visibility']
supports_modules = self.cxx.hasCompileFlag(modules_flags)
- enable_modules = self.get_lit_bool('enable_modules',
- default=False,
- env_var='LIBCXX_ENABLE_MODULES')
+ enable_modules = self.get_modules_enabled()
if enable_modules and not supports_modules:
self.lit_config.fatal(
'-fmodules is enabled but not supported by the compiler')