summaryrefslogtreecommitdiff
path: root/test/support
diff options
context:
space:
mode:
Diffstat (limited to 'test/support')
-rw-r--r--test/support/Counter.h52
-rw-r--r--test/support/DefaultOnly.h35
-rw-r--r--test/support/MoveOnly.h50
-rw-r--r--test/support/allocators.h185
-rw-r--r--test/support/asan_testing.h37
-rw-r--r--test/support/cmpxchg_loop.h51
-rw-r--r--test/support/constexpr_char_traits.hpp138
-rw-r--r--test/support/count_new.hpp206
-rw-r--r--test/support/counting_predicates.hpp46
-rw-r--r--test/support/hexfloat.h38
-rw-r--r--test/support/is_transparent.h73
-rw-r--r--test/support/min_allocator.h291
-rw-r--r--test/support/nasty_containers.hpp282
-rw-r--r--test/support/nasty_macros.hpp32
-rw-r--r--test/support/nothing_to_do.pass.cpp14
-rw-r--r--test/support/platform_support.h98
-rw-r--r--test/support/private_constructor.hpp31
-rw-r--r--test/support/test_allocator.h226
-rw-r--r--test/support/test_iterators.h329
-rw-r--r--test/support/test_macros.h83
-rw-r--r--test/support/tracked_value.h50
-rw-r--r--test/support/user_defined_integral.hpp44
22 files changed, 2391 insertions, 0 deletions
diff --git a/test/support/Counter.h b/test/support/Counter.h
new file mode 100644
index 0000000000000..2bc3642f50594
--- /dev/null
+++ b/test/support/Counter.h
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef COUNTER_H
+#define COUNTER_H
+
+#include <functional> // for std::hash
+
+struct Counter_base { static int gConstructed; };
+
+template <typename T>
+class Counter : public Counter_base
+{
+public:
+ Counter() : data_() { ++gConstructed; }
+ Counter(const T &data) : data_(data) { ++gConstructed; }
+ Counter(const Counter& rhs) : data_(rhs.data_) { ++gConstructed; }
+ Counter& operator=(const Counter& rhs) { ++gConstructed; data_ = rhs.data_; return *this; }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ Counter(Counter&& rhs) : data_(std::move(rhs.data_)) { ++gConstructed; }
+ Counter& operator=(Counter&& rhs) { ++gConstructed; data_ = std::move(rhs.data_); return *this; }
+#endif
+ ~Counter() { --gConstructed; }
+
+ const T& get() const {return data_;}
+
+ bool operator==(const Counter& x) const {return data_ == x.data_;}
+ bool operator< (const Counter& x) const {return data_ < x.data_;}
+
+private:
+ T data_;
+};
+
+int Counter_base::gConstructed = 0;
+
+namespace std {
+
+template <class T>
+struct hash<Counter<T> >
+ : public std::unary_function<Counter<T>, std::size_t>
+{
+ std::size_t operator()(const Counter<T>& x) const {return std::hash<T>(x.get());}
+};
+}
+
+#endif
diff --git a/test/support/DefaultOnly.h b/test/support/DefaultOnly.h
new file mode 100644
index 0000000000000..a3d4303f8158a
--- /dev/null
+++ b/test/support/DefaultOnly.h
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DEFAULTONLY_H
+#define DEFAULTONLY_H
+
+#include <cassert>
+
+class DefaultOnly
+{
+ int data_;
+
+ DefaultOnly(const DefaultOnly&);
+ DefaultOnly& operator=(const DefaultOnly&);
+public:
+ static int count;
+
+ DefaultOnly() : data_(-1) {++count;}
+ ~DefaultOnly() {data_ = 0; --count;}
+
+ friend bool operator==(const DefaultOnly& x, const DefaultOnly& y)
+ {return x.data_ == y.data_;}
+ friend bool operator< (const DefaultOnly& x, const DefaultOnly& y)
+ {return x.data_ < y.data_;}
+};
+
+int DefaultOnly::count = 0;
+
+#endif // DEFAULTONLY_H
diff --git a/test/support/MoveOnly.h b/test/support/MoveOnly.h
new file mode 100644
index 0000000000000..e4d9f64956023
--- /dev/null
+++ b/test/support/MoveOnly.h
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MOVEONLY_H
+#define MOVEONLY_H
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#include <cstddef>
+#include <functional>
+
+class MoveOnly
+{
+ MoveOnly(const MoveOnly&);
+ MoveOnly& operator=(const MoveOnly&);
+
+ int data_;
+public:
+ MoveOnly(int data = 1) : data_(data) {}
+ MoveOnly(MoveOnly&& x)
+ : data_(x.data_) {x.data_ = 0;}
+ MoveOnly& operator=(MoveOnly&& x)
+ {data_ = x.data_; x.data_ = 0; return *this;}
+
+ int get() const {return data_;}
+
+ bool operator==(const MoveOnly& x) const {return data_ == x.data_;}
+ bool operator< (const MoveOnly& x) const {return data_ < x.data_;}
+};
+
+namespace std {
+
+template <>
+struct hash<MoveOnly>
+ : public std::unary_function<MoveOnly, std::size_t>
+{
+ std::size_t operator()(const MoveOnly& x) const {return x.get();}
+};
+
+}
+
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#endif // MOVEONLY_H
diff --git a/test/support/allocators.h b/test/support/allocators.h
new file mode 100644
index 0000000000000..b7aba12e21fda
--- /dev/null
+++ b/test/support/allocators.h
@@ -0,0 +1,185 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ALLOCATORS_H
+#define ALLOCATORS_H
+
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class T>
+class A1
+{
+ int id_;
+public:
+ explicit A1(int id = 0) TEST_NOEXCEPT : id_(id) {}
+
+ typedef T value_type;
+
+ int id() const {return id_;}
+
+ static bool copy_called;
+ static bool move_called;
+ static bool allocate_called;
+ static std::pair<T*, std::size_t> deallocate_called;
+
+ A1(const A1& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;}
+ A1(A1&& a) TEST_NOEXCEPT : id_(a.id()) {move_called = true;}
+
+ template <class U>
+ A1(const A1<U>& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;}
+ template <class U>
+ A1(A1<U>&& a) TEST_NOEXCEPT : id_(a.id()) {move_called = true;}
+
+ T* allocate(std::size_t n)
+ {
+ allocate_called = true;
+ return (T*)n;
+ }
+
+ void deallocate(T* p, std::size_t n)
+ {
+ deallocate_called = std::pair<T*, std::size_t>(p, n);
+ }
+
+ std::size_t max_size() const {return id_;}
+};
+
+template <class T> bool A1<T>::copy_called = false;
+template <class T> bool A1<T>::move_called = false;
+template <class T> bool A1<T>::allocate_called = false;
+template <class T> std::pair<T*, std::size_t> A1<T>::deallocate_called;
+
+template <class T, class U>
+inline
+bool operator==(const A1<T>& x, const A1<U>& y)
+{
+ return x.id() == y.id();
+}
+
+template <class T, class U>
+inline
+bool operator!=(const A1<T>& x, const A1<U>& y)
+{
+ return !(x == y);
+}
+
+template <class T>
+class A2
+{
+ int id_;
+public:
+ explicit A2(int id = 0) TEST_NOEXCEPT : id_(id) {}
+
+ typedef T value_type;
+
+ typedef unsigned size_type;
+ typedef int difference_type;
+
+ typedef std::true_type propagate_on_container_move_assignment;
+
+ int id() const {return id_;}
+
+ static bool copy_called;
+ static bool move_called;
+ static bool allocate_called;
+
+ A2(const A2& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;}
+ A2(A2&& a) TEST_NOEXCEPT : id_(a.id()) {move_called = true;}
+
+ T* allocate(std::size_t n, const void* hint)
+ {
+ allocate_called = true;
+ return (T*)hint;
+ }
+};
+
+template <class T> bool A2<T>::copy_called = false;
+template <class T> bool A2<T>::move_called = false;
+template <class T> bool A2<T>::allocate_called = false;
+
+template <class T, class U>
+inline
+bool operator==(const A2<T>& x, const A2<U>& y)
+{
+ return x.id() == y.id();
+}
+
+template <class T, class U>
+inline
+bool operator!=(const A2<T>& x, const A2<U>& y)
+{
+ return !(x == y);
+}
+
+template <class T>
+class A3
+{
+ int id_;
+public:
+ explicit A3(int id = 0) TEST_NOEXCEPT : id_(id) {}
+
+ typedef T value_type;
+
+ typedef std::true_type propagate_on_container_copy_assignment;
+ typedef std::true_type propagate_on_container_swap;
+
+ int id() const {return id_;}
+
+ static bool copy_called;
+ static bool move_called;
+ static bool constructed;
+ static bool destroy_called;
+
+ A3(const A3& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;}
+ A3(A3&& a) TEST_NOEXCEPT: id_(a.id()) {move_called = true;}
+
+ template <class U, class ...Args>
+ void construct(U* p, Args&& ...args)
+ {
+ ::new (p) U(std::forward<Args>(args)...);
+ constructed = true;
+ }
+
+ template <class U>
+ void destroy(U* p)
+ {
+ p->~U();
+ destroy_called = true;
+ }
+
+ A3 select_on_container_copy_construction() const {return A3(-1);}
+};
+
+template <class T> bool A3<T>::copy_called = false;
+template <class T> bool A3<T>::move_called = false;
+template <class T> bool A3<T>::constructed = false;
+template <class T> bool A3<T>::destroy_called = false;
+
+template <class T, class U>
+inline
+bool operator==(const A3<T>& x, const A3<U>& y)
+{
+ return x.id() == y.id();
+}
+
+template <class T, class U>
+inline
+bool operator!=(const A3<T>& x, const A3<U>& y)
+{
+ return !(x == y);
+}
+
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#endif // ALLOCATORS_H
diff --git a/test/support/asan_testing.h b/test/support/asan_testing.h
new file mode 100644
index 0000000000000..45ad04b1bb2ca
--- /dev/null
+++ b/test/support/asan_testing.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ASAN_TESTING_H
+#define ASAN_TESTING_H
+
+#include <__config>
+
+#ifndef _LIBCPP_HAS_NO_ASAN
+extern "C" int __sanitizer_verify_contiguous_container
+ ( const void *beg, const void *mid, const void *end );
+
+template <typename T, typename Alloc>
+bool is_contiguous_container_asan_correct ( const std::vector<T, Alloc> &c )
+{
+ if ( std::is_same<Alloc, std::allocator<T> >::value && c.data() != NULL)
+ return __sanitizer_verify_contiguous_container (
+ c.data(), c.data() + c.size(), c.data() + c.capacity()) != 0;
+ return true;
+}
+
+#else
+template <typename T, typename Alloc>
+bool is_contiguous_container_asan_correct ( const std::vector<T, Alloc> &c )
+{
+ return true;
+}
+#endif
+
+
+#endif // ASAN_TESTING_H
diff --git a/test/support/cmpxchg_loop.h b/test/support/cmpxchg_loop.h
new file mode 100644
index 0000000000000..c39e3fb12f676
--- /dev/null
+++ b/test/support/cmpxchg_loop.h
@@ -0,0 +1,51 @@
+#include <atomic>
+
+template <class A, class T>
+bool cmpxchg_weak_loop(A& atomic, T& expected, T desired) {
+ for (int i = 0; i < 10; i++) {
+ if (atomic.compare_exchange_weak(expected, desired) == true) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+template <class A, class T>
+bool cmpxchg_weak_loop(A& atomic, T& expected, T desired,
+ std::memory_order success,
+ std::memory_order failure) {
+ for (int i = 0; i < 10; i++) {
+ if (atomic.compare_exchange_weak(expected, desired, success,
+ failure) == true) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+template <class A, class T>
+bool c_cmpxchg_weak_loop(A* atomic, T* expected, T desired) {
+ for (int i = 0; i < 10; i++) {
+ if (std::atomic_compare_exchange_weak(atomic, expected, desired) == true) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+template <class A, class T>
+bool c_cmpxchg_weak_loop(A* atomic, T* expected, T desired,
+ std::memory_order success,
+ std::memory_order failure) {
+ for (int i = 0; i < 10; i++) {
+ if (std::atomic_compare_exchange_weak_explicit(atomic, expected, desired,
+ success, failure) == true) {
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/test/support/constexpr_char_traits.hpp b/test/support/constexpr_char_traits.hpp
new file mode 100644
index 0000000000000..b069c90076a2c
--- /dev/null
+++ b/test/support/constexpr_char_traits.hpp
@@ -0,0 +1,138 @@
+// -*- C++ -*-
+//===-------_------------ constexpr_char_traits ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _CONSTEXPR_CHAR_TRAITS
+#define _CONSTEXPR_CHAR_TRAITS
+
+#include <__config>
+#include <string>
+
+
+template <class _CharT>
+struct constexpr_char_traits
+{
+ typedef _CharT char_type;
+ typedef int int_type;
+ typedef std::streamoff off_type;
+ typedef std::streampos pos_type;
+ typedef std::mbstate_t state_type;
+
+ static _LIBCPP_CONSTEXPR_AFTER_CXX11 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
+ {__c1 = __c2;}
+
+ static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+ {return __c1 == __c2;}
+
+ static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+ {return __c1 < __c2;}
+
+ static _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(const char_type* __s1, const char_type* __s2, size_t __n);
+ static _LIBCPP_CONSTEXPR_AFTER_CXX11 size_t length(const char_type* __s);
+ static _LIBCPP_CONSTEXPR_AFTER_CXX11 const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
+ static _LIBCPP_CONSTEXPR_AFTER_CXX11 char_type* move(char_type* __s1, const char_type* __s2, size_t __n);
+ static _LIBCPP_CONSTEXPR_AFTER_CXX11 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n);
+ static _LIBCPP_CONSTEXPR_AFTER_CXX11 char_type* assign(char_type* __s, size_t __n, char_type __a);
+
+ static _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
+ {return eq_int_type(__c, eof()) ? ~eof() : __c;}
+
+ static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+ {return char_type(__c);}
+
+ static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+ {return int_type(__c);}
+
+ static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+ {return __c1 == __c2;}
+
+ static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
+ {return int_type(EOF);}
+};
+
+
+template <class _CharT>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 int
+constexpr_char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
+{
+ for (; __n; --__n, ++__s1, ++__s2)
+ {
+ if (lt(*__s1, *__s2))
+ return -1;
+ if (lt(*__s2, *__s1))
+ return 1;
+ }
+ return 0;
+}
+
+template <class _CharT>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 size_t
+constexpr_char_traits<_CharT>::length(const char_type* __s)
+{
+ size_t __len = 0;
+ for (; !eq(*__s, char_type(0)); ++__s)
+ ++__len;
+ return __len;
+}
+
+template <class _CharT>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT*
+constexpr_char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
+{
+ for (; __n; --__n)
+ {
+ if (eq(*__s, __a))
+ return __s;
+ ++__s;
+ }
+ return 0;
+}
+
+template <class _CharT>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _CharT*
+constexpr_char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
+{
+ char_type* __r = __s1;
+ if (__s1 < __s2)
+ {
+ for (; __n; --__n, ++__s1, ++__s2)
+ assign(*__s1, *__s2);
+ }
+ else if (__s2 < __s1)
+ {
+ __s1 += __n;
+ __s2 += __n;
+ for (; __n; --__n)
+ assign(*--__s1, *--__s2);
+ }
+ return __r;
+}
+
+template <class _CharT>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _CharT*
+constexpr_char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
+{
+ _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+ char_type* __r = __s1;
+ for (; __n; --__n, ++__s1, ++__s2)
+ assign(*__s1, *__s2);
+ return __r;
+}
+
+template <class _CharT>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _CharT*
+constexpr_char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
+{
+ char_type* __r = __s;
+ for (; __n; --__n, ++__s)
+ assign(*__s, __a);
+ return __r;
+}
+
+#endif // _CONSTEXPR_CHAR_TRAITS
diff --git a/test/support/count_new.hpp b/test/support/count_new.hpp
new file mode 100644
index 0000000000000..ddaf036f7d169
--- /dev/null
+++ b/test/support/count_new.hpp
@@ -0,0 +1,206 @@
+#ifndef COUNT_NEW_HPP
+#define COUNT_NEW_HPP
+
+# include <cstdlib>
+# include <cassert>
+# include <new>
+
+#ifndef __has_feature
+# define __has_feature(x) 0
+#endif
+
+#if __has_feature(address_sanitizer) \
+ || __has_feature(memory_sanitizer) \
+ || __has_feature(thread_sanitizer)
+#define DISABLE_NEW_COUNT
+#endif
+
+class MemCounter
+{
+public:
+ // Make MemCounter super hard to accidentally construct or copy.
+ class MemCounterCtorArg_ {};
+ explicit MemCounter(MemCounterCtorArg_) { reset(); }
+
+private:
+ MemCounter(MemCounter const &);
+ MemCounter & operator=(MemCounter const &);
+
+public:
+ // All checks return true when disable_checking is enabled.
+ static const bool disable_checking;
+
+ int outstanding_new;
+ int new_called;
+ int delete_called;
+ int last_new_size;
+
+ int outstanding_array_new;
+ int new_array_called;
+ int delete_array_called;
+ int last_new_array_size;
+
+public:
+ void newCalled(std::size_t s)
+ {
+ assert(s);
+ ++new_called;
+ ++outstanding_new;
+ last_new_size = s;
+ }
+
+ void deleteCalled(void * p)
+ {
+ assert(p);
+ --outstanding_new;
+ ++delete_called;
+ }
+
+ void newArrayCalled(std::size_t s)
+ {
+ assert(s);
+ ++outstanding_array_new;
+ ++new_array_called;
+ last_new_array_size = s;
+ }
+
+ void deleteArrayCalled(void * p)
+ {
+ assert(p);
+ --outstanding_array_new;
+ ++delete_array_called;
+ }
+
+ void reset()
+ {
+ outstanding_new = 0;
+ new_called = 0;
+ delete_called = 0;
+ last_new_size = 0;
+
+ outstanding_array_new = 0;
+ new_array_called = 0;
+ delete_array_called = 0;
+ last_new_array_size = 0;
+ }
+
+public:
+ bool checkOutstandingNewEq(int n) const
+ {
+ return disable_checking || n == outstanding_new;
+ }
+
+ bool checkOutstandingNewNotEq(int n) const
+ {
+ return disable_checking || n != outstanding_new;
+ }
+
+ bool checkNewCalledEq(int n) const
+ {
+ return disable_checking || n == new_called;
+ }
+
+ bool checkNewCalledNotEq(int n) const
+ {
+ return disable_checking || n != new_called;
+ }
+
+ bool checkDeleteCalledEq(int n) const
+ {
+ return disable_checking || n == delete_called;
+ }
+
+ bool checkDeleteCalledNotEq(int n) const
+ {
+ return disable_checking || n != delete_called;
+ }
+
+ bool checkLastNewSizeEq(int n) const
+ {
+ return disable_checking || n == last_new_size;
+ }
+
+ bool checkLastNewSizeNotEq(int n) const
+ {
+ return disable_checking || n != last_new_size;
+ }
+
+ bool checkOutstandingArrayNewEq(int n) const
+ {
+ return disable_checking || n == outstanding_array_new;
+ }
+
+ bool checkOutstandingArrayNewNotEq(int n) const
+ {
+ return disable_checking || n != outstanding_array_new;
+ }
+
+ bool checkNewArrayCalledEq(int n) const
+ {
+ return disable_checking || n == new_array_called;
+ }
+
+ bool checkNewArrayCalledNotEq(int n) const
+ {
+ return disable_checking || n != new_array_called;
+ }
+
+ bool checkDeleteArrayCalledEq(int n) const
+ {
+ return disable_checking || n == delete_array_called;
+ }
+
+ bool checkDeleteArrayCalledNotEq(int n) const
+ {
+ return disable_checking || n != delete_array_called;
+ }
+
+ bool checkLastNewArraySizeEq(int n) const
+ {
+ return disable_checking || n == last_new_array_size;
+ }
+
+ bool checkLastNewArraySizeNotEq(int n) const
+ {
+ return disable_checking || n != last_new_array_size;
+ }
+};
+
+#ifdef DISABLE_NEW_COUNT
+ const bool MemCounter::disable_checking = true;
+#else
+ const bool MemCounter::disable_checking = false;
+#endif
+
+MemCounter globalMemCounter((MemCounter::MemCounterCtorArg_()));
+
+#ifndef DISABLE_NEW_COUNT
+void* operator new(std::size_t s) throw(std::bad_alloc)
+{
+ globalMemCounter.newCalled(s);
+ return std::malloc(s);
+}
+
+void operator delete(void* p) throw()
+{
+ globalMemCounter.deleteCalled(p);
+ std::free(p);
+}
+
+
+void* operator new[](std::size_t s) throw(std::bad_alloc)
+{
+ globalMemCounter.newArrayCalled(s);
+ return operator new(s);
+}
+
+
+void operator delete[](void* p) throw()
+{
+ globalMemCounter.deleteArrayCalled(p);
+ operator delete(p);
+}
+
+#endif // DISABLE_NEW_COUNT
+
+#endif /* COUNT_NEW_HPP */
diff --git a/test/support/counting_predicates.hpp b/test/support/counting_predicates.hpp
new file mode 100644
index 0000000000000..aab6a9785772c
--- /dev/null
+++ b/test/support/counting_predicates.hpp
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __COUNTING_PREDICATES_H
+#define __COUNTING_PREDICATES_H
+
+
+template <typename Predicate, typename Arg>
+struct unary_counting_predicate : public std::unary_function<Arg, bool> {
+public:
+ unary_counting_predicate(Predicate p) : p_(p), count_(0) {}
+ ~unary_counting_predicate() {}
+
+ bool operator () (const Arg &a) const { ++count_; return p_(a); }
+ size_t count() const { return count_; }
+ void reset() { count_ = 0; }
+
+private:
+ Predicate p_;
+ mutable size_t count_;
+ };
+
+
+template <typename Predicate, typename Arg1, typename Arg2=Arg1>
+struct binary_counting_predicate : public std::binary_function<Arg1, Arg2, bool> {
+public:
+
+ binary_counting_predicate ( Predicate p ) : p_(p), count_(0) {}
+ ~binary_counting_predicate() {}
+
+ bool operator () (const Arg1 &a1, const Arg2 &a2) const { ++count_; return p_(a1, a2); }
+ size_t count() const { return count_; }
+ void reset() { count_ = 0; }
+
+private:
+ Predicate p_;
+ mutable size_t count_;
+ };
+
+#endif // __COUNTING_PREDICATES_H
diff --git a/test/support/hexfloat.h b/test/support/hexfloat.h
new file mode 100644
index 0000000000000..7ef093714fed0
--- /dev/null
+++ b/test/support/hexfloat.h
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// Define a hexfloat literal emulator since we can't depend on being able to
+// for hexfloat literals
+
+// 0x10.F5p-10 == hexfloat<double>(0x10, 0xF5, -10)
+
+#ifndef HEXFLOAT_H
+#define HEXFLOAT_H
+
+#include <algorithm>
+#include <cmath>
+#include <climits>
+
+template <class T>
+class hexfloat
+{
+ T value_;
+public:
+ hexfloat(long long m1, unsigned long long m0, int exp)
+ {
+ const std::size_t n = sizeof(unsigned long long) * CHAR_BIT;
+ int s = m1 < 0 ? -1 : 1;
+ value_ = std::ldexp(m1 + s * std::ldexp(T(m0), -static_cast<int>(n -
+ std::__clz(m0)/4*4)), exp);
+ }
+
+ operator T() const {return value_;}
+};
+
+#endif
diff --git a/test/support/is_transparent.h b/test/support/is_transparent.h
new file mode 100644
index 0000000000000..58255248abc9c
--- /dev/null
+++ b/test/support/is_transparent.h
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TRANSPARENT_H
+#define TRANSPARENT_H
+
+// testing transparent
+#if _LIBCPP_STD_VER > 11
+
+struct transparent_less
+{
+ 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); }
+ typedef void is_transparent; // correct
+};
+
+struct transparent_less_no_type
+{
+ 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); }
+private:
+// typedef void is_transparent; // error - should exist
+};
+
+struct transparent_less_private
+{
+ 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); }
+private:
+ typedef void is_transparent; // error - should be accessible
+};
+
+struct transparent_less_not_a_type
+{
+ 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); }
+
+ int is_transparent; // error - should be a type
+};
+
+struct C2Int { // comparable to int
+ C2Int() : i_(0) {}
+ C2Int(int i): i_(i) {}
+ int get () const { return i_; }
+private:
+ int i_;
+ };
+
+bool operator <(int rhs, const C2Int& lhs) { return rhs < lhs.get(); }
+bool operator <(const C2Int& rhs, const C2Int& lhs) { return rhs.get() < lhs.get(); }
+bool operator <(const C2Int& rhs, int lhs) { return rhs.get() < lhs; }
+
+#endif
+
+#endif // TRANSPARENT_H
diff --git a/test/support/min_allocator.h b/test/support/min_allocator.h
new file mode 100644
index 0000000000000..5e3ae5d2a136b
--- /dev/null
+++ b/test/support/min_allocator.h
@@ -0,0 +1,291 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MIN_ALLOCATOR_H
+#define MIN_ALLOCATOR_H
+
+#include <cstddef>
+
+#include "test_macros.h"
+
+template <class T>
+class bare_allocator
+{
+public:
+ typedef T value_type;
+
+ bare_allocator() TEST_NOEXCEPT {}
+
+ template <class U>
+ bare_allocator(bare_allocator<U>) TEST_NOEXCEPT {}
+
+ T* allocate(std::size_t n)
+ {
+ return static_cast<T*>(::operator new(n*sizeof(T)));
+ }
+
+ void deallocate(T* p, std::size_t)
+ {
+ return ::operator delete(static_cast<void*>(p));
+ }
+
+ friend bool operator==(bare_allocator, bare_allocator) {return true;}
+ friend bool operator!=(bare_allocator x, bare_allocator y) {return !(x == y);}
+};
+
+
+#if __cplusplus >= 201103L
+
+#include <memory>
+
+template <class T> class min_pointer;
+template <class T> class min_pointer<const T>;
+template <> class min_pointer<void>;
+template <> class min_pointer<const void>;
+template <class T> class min_allocator;
+
+template <>
+class min_pointer<const void>
+{
+ const void* ptr_;
+public:
+ min_pointer() TEST_NOEXCEPT = default;
+ min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
+ template <class T>
+ min_pointer(min_pointer<T> p) TEST_NOEXCEPT : ptr_(p.ptr_) {}
+
+ explicit operator bool() const {return ptr_ != nullptr;}
+
+ friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
+ friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
+ template <class U> friend class min_pointer;
+};
+
+template <>
+class min_pointer<void>
+{
+ void* ptr_;
+public:
+ min_pointer() TEST_NOEXCEPT = default;
+ min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
+ template <class T,
+ class = typename std::enable_if
+ <
+ !std::is_const<T>::value
+ >::type
+ >
+ min_pointer(min_pointer<T> p) TEST_NOEXCEPT : ptr_(p.ptr_) {}
+
+ explicit operator bool() const {return ptr_ != nullptr;}
+
+ friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
+ friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
+ template <class U> friend class min_pointer;
+};
+
+template <class T>
+class min_pointer
+{
+ T* ptr_;
+
+ explicit min_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {}
+public:
+ min_pointer() TEST_NOEXCEPT = default;
+ min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
+ explicit min_pointer(min_pointer<void> p) TEST_NOEXCEPT : ptr_(static_cast<T*>(p.ptr_)) {}
+
+ explicit operator bool() const {return ptr_ != nullptr;}
+
+ typedef std::ptrdiff_t difference_type;
+ typedef T& reference;
+ typedef T* pointer;
+ typedef T value_type;
+ typedef std::random_access_iterator_tag iterator_category;
+
+ reference operator*() const {return *ptr_;}
+ pointer operator->() const {return ptr_;}
+
+ min_pointer& operator++() {++ptr_; return *this;}
+ min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;}
+
+ min_pointer& operator--() {--ptr_; return *this;}
+ min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;}
+
+ min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;}
+ min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;}
+
+ min_pointer operator+(difference_type n) const
+ {
+ min_pointer tmp(*this);
+ tmp += n;
+ return tmp;
+ }
+
+ friend min_pointer operator+(difference_type n, min_pointer x)
+ {
+ return x + n;
+ }
+
+ min_pointer operator-(difference_type n) const
+ {
+ min_pointer tmp(*this);
+ tmp -= n;
+ return tmp;
+ }
+
+ friend difference_type operator-(min_pointer x, min_pointer y)
+ {
+ return x.ptr_ - y.ptr_;
+ }
+
+ reference operator[](difference_type n) const {return ptr_[n];}
+
+ friend bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;}
+ friend bool operator> (min_pointer x, min_pointer y) {return y < x;}
+ friend bool operator<=(min_pointer x, min_pointer y) {return !(y < x);}
+ friend bool operator>=(min_pointer x, min_pointer y) {return !(x < y);}
+
+ static min_pointer pointer_to(T& t) {return min_pointer(std::addressof(t));}
+
+ friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
+ friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
+ template <class U> friend class min_pointer;
+ template <class U> friend class min_allocator;
+};
+
+template <class T>
+class min_pointer<const T>
+{
+ const T* ptr_;
+
+ explicit min_pointer(const T* p) : ptr_(p) {}
+public:
+ min_pointer() TEST_NOEXCEPT = default;
+ min_pointer(std::nullptr_t) : ptr_(nullptr) {}
+ min_pointer(min_pointer<T> p) : ptr_(p.ptr_) {}
+ explicit min_pointer(min_pointer<const void> p) : ptr_(static_cast<const T*>(p.ptr_)) {}
+
+ explicit operator bool() const {return ptr_ != nullptr;}
+
+ typedef std::ptrdiff_t difference_type;
+ typedef const T& reference;
+ typedef const T* pointer;
+ typedef const T value_type;
+ typedef std::random_access_iterator_tag iterator_category;
+
+ reference operator*() const {return *ptr_;}
+ pointer operator->() const {return ptr_;}
+
+ min_pointer& operator++() {++ptr_; return *this;}
+ min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;}
+
+ min_pointer& operator--() {--ptr_; return *this;}
+ min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;}
+
+ min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;}
+ min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;}
+
+ min_pointer operator+(difference_type n) const
+ {
+ min_pointer tmp(*this);
+ tmp += n;
+ return tmp;
+ }
+
+ friend min_pointer operator+(difference_type n, min_pointer x)
+ {
+ return x + n;
+ }
+
+ min_pointer operator-(difference_type n) const
+ {
+ min_pointer tmp(*this);
+ tmp -= n;
+ return tmp;
+ }
+
+ friend difference_type operator-(min_pointer x, min_pointer y)
+ {
+ return x.ptr_ - y.ptr_;
+ }
+
+ reference operator[](difference_type n) const {return ptr_[n];}
+
+ friend bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;}
+ friend bool operator> (min_pointer x, min_pointer y) {return y < x;}
+ friend bool operator<=(min_pointer x, min_pointer y) {return !(y < x);}
+ friend bool operator>=(min_pointer x, min_pointer y) {return !(x < y);}
+
+ static min_pointer pointer_to(const T& t) {return min_pointer(std::addressof(t));}
+
+ friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
+ friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
+ template <class U> friend class min_pointer;
+};
+
+template <class T>
+inline
+bool
+operator==(min_pointer<T> x, std::nullptr_t)
+{
+ return !static_cast<bool>(x);
+}
+
+template <class T>
+inline
+bool
+operator==(std::nullptr_t, min_pointer<T> x)
+{
+ return !static_cast<bool>(x);
+}
+
+template <class T>
+inline
+bool
+operator!=(min_pointer<T> x, std::nullptr_t)
+{
+ return static_cast<bool>(x);
+}
+
+template <class T>
+inline
+bool
+operator!=(std::nullptr_t, min_pointer<T> x)
+{
+ return static_cast<bool>(x);
+}
+
+template <class T>
+class min_allocator
+{
+public:
+ typedef T value_type;
+ typedef min_pointer<T> pointer;
+
+ min_allocator() = default;
+ template <class U>
+ min_allocator(min_allocator<U>) {}
+
+ pointer allocate(std::ptrdiff_t n)
+ {
+ return pointer(static_cast<T*>(::operator new(n*sizeof(T))));
+ }
+
+ void deallocate(pointer p, std::ptrdiff_t)
+ {
+ return ::operator delete(p.ptr_);
+ }
+
+ friend bool operator==(min_allocator, min_allocator) {return true;}
+ friend bool operator!=(min_allocator x, min_allocator y) {return !(x == y);}
+};
+
+#endif // __cplusplus >= 201103L
+
+#endif // MIN_ALLOCATOR_H
diff --git a/test/support/nasty_containers.hpp b/test/support/nasty_containers.hpp
new file mode 100644
index 0000000000000..5a2e19505424b
--- /dev/null
+++ b/test/support/nasty_containers.hpp
@@ -0,0 +1,282 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef NASTY_VECTOR_H
+#define NASTY_VECTOR_H
+
+#include <vector>
+#include <list>
+
+template <class T>
+class nasty_vector
+{
+public:
+ typedef typename std::vector<T> nested_container;
+ typedef typename nested_container::value_type value_type;
+ typedef typename nested_container::reference reference;
+ typedef typename nested_container::const_reference const_reference;
+ typedef typename nested_container::iterator iterator;
+ typedef typename nested_container::const_iterator const_iterator;
+
+ typedef typename nested_container::size_type size_type;
+ typedef typename nested_container::difference_type difference_type;
+ typedef typename nested_container::pointer pointer;
+ typedef typename nested_container::const_pointer const_pointer;
+
+ typedef typename nested_container::reverse_iterator reverse_iterator;
+ typedef typename nested_container::const_reverse_iterator const_reverse_iterator;
+
+ nasty_vector() : v_() {}
+ explicit nasty_vector(size_type n) : v_(n) {}
+ nasty_vector(size_type n, const value_type& value) : v_(n, value) {}
+ template <class InputIterator> nasty_vector(InputIterator first, InputIterator last) : v_(first, last) {}
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+ nasty_vector(std::initializer_list<value_type> il) : v_(il) {}
+#endif
+ ~nasty_vector() {}
+
+ template <class InputIterator>
+ void assign(InputIterator first, InputIterator last) { v_.assign(first, last); }
+ void assign(size_type n, const value_type& u) { v_.assign(n, u); }
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+ void assign(std::initializer_list<value_type> il) { v_.assign(il); }
+#endif
+
+ iterator begin() _NOEXCEPT { return v_.begin(); }
+ const_iterator begin() const _NOEXCEPT { return v_.begin(); }
+ iterator end() _NOEXCEPT { return v_.end(); }
+ const_iterator end() const _NOEXCEPT { return v_.end(); }
+
+ reverse_iterator rbegin() _NOEXCEPT { return v_.rbegin(); }
+ const_reverse_iterator rbegin() const _NOEXCEPT { return v_.rbegin(); }
+ reverse_iterator rend() _NOEXCEPT { return v_.rend(); }
+ const_reverse_iterator rend() const _NOEXCEPT { return v_.rend(); }
+
+ const_iterator cbegin() const _NOEXCEPT { return v_.cbegin(); }
+ const_iterator cend() const _NOEXCEPT { return v_.cend(); }
+ const_reverse_iterator crbegin() const _NOEXCEPT { return v_.crbegin(); }
+ const_reverse_iterator crend() const _NOEXCEPT { return v_.crend(); }
+
+ size_type size() const _NOEXCEPT { return v_.size(); }
+ size_type max_size() const _NOEXCEPT { return v_.max_size(); }
+ size_type capacity() const _NOEXCEPT { return v_.capacity(); }
+ bool empty() const _NOEXCEPT { return v_.empty(); }
+ void reserve(size_type n) { v_.reserve(n); };
+ void shrink_to_fit() _NOEXCEPT { v_.shrink_to_fit(); }
+
+ reference operator[](size_type n) { return v_[n]; }
+ const_reference operator[](size_type n) const { return v_[n]; }
+ reference at(size_type n) { return v_.at(n); }
+ const_reference at(size_type n) const { return v_.at(n); }
+
+ reference front() { return v_.front(); }
+ const_reference front() const { return v_.front(); }
+ reference back() { return v_.back(); }
+ const_reference back() const { return v_.back(); }
+
+ value_type* data() _NOEXCEPT { return v_.data(); }
+ const value_type* data() const _NOEXCEPT { return v_.data(); }
+
+ void push_back(const value_type& x) { v_.push_back(x); }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ void push_back(value_type&& x) { v_.push_back(std::forward<value_type&&>(x)); }
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+ template <class... Args>
+ void emplace_back(Args&&... args) { v_.emplace_back(std::forward<Args>(args)...); }
+#endif
+#endif
+ void pop_back() { v_.pop_back(); }
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+ template <class... Args> iterator emplace(const_iterator pos, Args&&... args)
+ { return v_.emplace(pos, std::forward<Args>(args)...); }
+#endif
+#endif
+
+ iterator insert(const_iterator pos, const value_type& x) { return v_.insert(pos, x); }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ iterator insert(const_iterator pos, value_type&& x) { return v_.insert(pos, std::forward<value_type>(x)); }
+#endif
+ iterator insert(const_iterator pos, size_type n, const value_type& x) { return v_.insert(pos, n, x); }
+ template <class InputIterator>
+ iterator insert(const_iterator pos, InputIterator first, InputIterator last)
+ { return v_.insert(pos, first, last); }
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+ iterator insert(const_iterator pos, std::initializer_list<value_type> il) { return v_.insert(pos, il); }
+#endif
+
+ iterator erase(const_iterator pos) { return v_.erase(pos); }
+ iterator erase(const_iterator first, const_iterator last) { return v_.erase(first, last); }
+
+ void clear() _NOEXCEPT { v_.clear(); }
+
+ void resize(size_type sz) { v_.resize(sz); }
+ void resize(size_type sz, const value_type& c) { v_.resize(sz, c); }
+
+ void swap(nasty_vector &nv) _NOEXCEPT_(std::__is_nothrow_swappable<nested_container>::value)
+ { v_.swap(nv.v_); }
+
+ nasty_vector *operator &() { return nullptr; } // nasty
+ const nasty_vector *operator &() const { return nullptr; } // nasty
+
+ nested_container v_;
+};
+
+template <class T>
+bool operator==(const nasty_vector<T>& x, const nasty_vector<T>& y) { return x.v_ == y.v_; }
+
+template <class T>
+class nasty_list
+{
+public:
+
+ typedef typename std::list<T> nested_container;
+ typedef typename nested_container::value_type value_type;
+ typedef typename nested_container::reference reference;
+ typedef typename nested_container::const_reference const_reference;
+ typedef typename nested_container::iterator iterator;
+ typedef typename nested_container::const_iterator const_iterator;
+
+ typedef typename nested_container::size_type size_type;
+ typedef typename nested_container::difference_type difference_type;
+ typedef typename nested_container::pointer pointer;
+ typedef typename nested_container::const_pointer const_pointer;
+
+ typedef typename nested_container::reverse_iterator reverse_iterator;
+ typedef typename nested_container::const_reverse_iterator const_reverse_iterator;
+
+ nasty_list() : l_() {}
+ explicit nasty_list(size_type n) : l_(n) {}
+ nasty_list(size_type n, const value_type& value) : l_(n,value) {}
+ template <class Iter>
+ nasty_list(Iter first, Iter last) : l_(first, last) {}
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+ nasty_list(std::initializer_list<value_type> il) : l_(il) {}
+#endif
+
+ ~nasty_list() {}
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+ nasty_list& operator=(std::initializer_list<value_type> il) { l_ = il; return *this; }
+#endif
+ template <class Iter>
+ void assign(Iter first, Iter last) { l_.assign(first, last); }
+ void assign(size_type n, const value_type& t) { l_.assign(n, t); }
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+ void assign(std::initializer_list<value_type> il) { l_.assign(il); }
+#endif
+
+
+ iterator begin() _NOEXCEPT { return l_.begin(); }
+ const_iterator begin() const _NOEXCEPT { return l_.begin(); }
+ iterator end() _NOEXCEPT { return l_.end(); }
+ const_iterator end() const _NOEXCEPT { return l_.end(); }
+
+ reverse_iterator rbegin() _NOEXCEPT { return l_.rbegin(); }
+ const_reverse_iterator rbegin() const _NOEXCEPT { return l_.rbegin(); }
+ reverse_iterator rend() _NOEXCEPT { return l_.rend(); }
+ const_reverse_iterator rend() const _NOEXCEPT { return l_.rend(); }
+
+ const_iterator cbegin() const _NOEXCEPT { return l_.cbegin(); }
+ const_iterator cend() const _NOEXCEPT { return l_.cend(); }
+ const_reverse_iterator crbegin() const _NOEXCEPT { return l_.crbegin(); }
+ const_reverse_iterator crend() const _NOEXCEPT { return l_.crend(); }
+
+ reference front() { return l_.front(); }
+ const_reference front() const { return l_.front(); }
+ reference back() { return l_.back(); }
+ const_reference back() const { return l_.back(); }
+
+ size_type size() const _NOEXCEPT { return l_.size(); }
+ size_type max_size() const _NOEXCEPT { return l_.max_size(); }
+ bool empty() const _NOEXCEPT { return l_.empty(); }
+
+ void push_front(const value_type& x) { l_.push_front(x); }
+ void push_back(const value_type& x) { l_.push_back(x); }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ void push_back(value_type&& x) { l_.push_back(std::forward<value_type&&>(x)); }
+ void push_front(value_type&& x) { l_.push_back(std::forward<value_type&&>(x)); }
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+ template <class... Args>
+ void emplace_back(Args&&... args) { l_.emplace_back(std::forward<Args>(args)...); }
+ template <class... Args>
+ void emplace_front(Args&&... args) { l_.emplace_front(std::forward<Args>(args)...); }
+#endif
+#endif
+ void pop_front() { l_.pop_front(); }
+ void pop_back() { l_.pop_back(); }
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+ template <class... Args> iterator emplace(const_iterator pos, Args&&... args)
+ { return l_.emplace(pos, std::forward<Args>(args)...); }
+#endif
+#endif
+
+ iterator insert(const_iterator pos, const value_type& x) { return l_.insert(pos, x); }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ iterator insert(const_iterator pos, value_type&& x) { return l_.insert(pos, std::forward<value_type>(x)); }
+#endif
+ iterator insert(const_iterator pos, size_type n, const value_type& x) { return l_.insert(pos, n, x); }
+ template <class InputIterator>
+ iterator insert(const_iterator pos, InputIterator first, InputIterator last)
+ { return l_.insert(pos, first, last); }
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+ iterator insert(const_iterator pos, std::initializer_list<value_type> il) { return l_.insert(pos, il); }
+#endif
+
+ iterator erase(const_iterator pos) { return l_.erase(pos); }
+ iterator erase(const_iterator pos, const_iterator last) { return l_.erase(pos, last); }
+
+ void resize(size_type sz) { l_.resize(); }
+ void resize(size_type sz, const value_type& c) { l_.resize(c); }
+
+ void swap(nasty_list &nl) _NOEXCEPT_(std::__is_nothrow_swappable<nested_container>::value)
+ { l_.swap(nl.l_); }
+
+ void clear() _NOEXCEPT { l_.clear(); }
+
+// void splice(const_iterator position, list& x);
+// void splice(const_iterator position, list&& x);
+// void splice(const_iterator position, list& x, const_iterator i);
+// void splice(const_iterator position, list&& x, const_iterator i);
+// void splice(const_iterator position, list& x, const_iterator first,
+// const_iterator last);
+// void splice(const_iterator position, list&& x, const_iterator first,
+// const_iterator last);
+//
+// void remove(const value_type& value);
+// template <class Pred> void remove_if(Pred pred);
+// void unique();
+// template <class BinaryPredicate>
+// void unique(BinaryPredicate binary_pred);
+// void merge(list& x);
+// void merge(list&& x);
+// template <class Compare>
+// void merge(list& x, Compare comp);
+// template <class Compare>
+// void merge(list&& x, Compare comp);
+// void sort();
+// template <class Compare>
+// void sort(Compare comp);
+// void reverse() noexcept;
+
+ nasty_list *operator &() { return nullptr; } // nasty
+ const nasty_list *operator &() const { return nullptr; } // nasty
+
+ nested_container l_;
+};
+
+template <class T>
+bool operator==(const nasty_list<T>& x, const nasty_list<T>& y) { return x.l_ == y.l_; }
+
+#endif
diff --git a/test/support/nasty_macros.hpp b/test/support/nasty_macros.hpp
new file mode 100644
index 0000000000000..2738e47eac9fc
--- /dev/null
+++ b/test/support/nasty_macros.hpp
@@ -0,0 +1,32 @@
+#ifndef SUPPORT_NASTY_MACROS_HPP
+#define SUPPORT_NASTY_MACROS_HPP
+
+#define NASTY_MACRO This should not be expanded!!!
+#define _A NASTY_MACRO
+#define _B NASTY_MACRO
+#define _C NASTY_MACRO
+#define _D NASTY_MACRO
+#define _E NASTY_MACRO
+#define _F NASTY_MACRO
+#define _G NASTY_MACRO
+#define _H NASTY_MACRO
+#define _I NASTY_MACRO
+#define _J NASTY_MACRO
+#define _K NASTY_MACRO
+#define _L NASTY_MACRO
+#define _M NASTY_MACRO
+#define _N NASTY_MACRO
+#define _O NASTY_MACRO
+#define _P NASTY_MACRO
+#define _Q NASTY_MACRO
+#define _R NASTY_MACRO
+#define _S NASTY_MACRO
+#define _T NASTY_MACRO
+#define _U NASTY_MACRO
+#define _V NASTY_MACRO
+#define _W NASTY_MACRO
+#define _X NASTY_MACRO
+#define _Y NASTY_MACRO
+#define _Z NASTY_MACRO
+
+#endif // SUPPORT_NASTY_MACROS_HPP
diff --git a/test/support/nothing_to_do.pass.cpp b/test/support/nothing_to_do.pass.cpp
new file mode 100644
index 0000000000000..9125fe194f46d
--- /dev/null
+++ b/test/support/nothing_to_do.pass.cpp
@@ -0,0 +1,14 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
+
diff --git a/test/support/platform_support.h b/test/support/platform_support.h
new file mode 100644
index 0000000000000..233e721ff5155
--- /dev/null
+++ b/test/support/platform_support.h
@@ -0,0 +1,98 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// Define a bunch of macros that can be used in the tests instead of
+// implementation defined assumptions:
+// - locale names
+// - floating point number string output
+
+#ifndef PLATFORM_SUPPORT_H
+#define PLATFORM_SUPPORT_H
+
+#include <__config>
+
+// locale names
+#ifdef _WIN32
+// WARNING: Windows does not support UTF-8 codepages.
+// Locales are "converted" using http://docs.moodle.org/dev/Table_of_locales
+#define LOCALE_en_US_UTF_8 "English_United States.1252"
+#define LOCALE_cs_CZ_ISO8859_2 "Czech_Czech Republic.1250"
+#define LOCALE_fr_FR_UTF_8 "French_France.1252"
+#define LOCALE_fr_CA_ISO8859_1 "French_Canada.1252"
+#define LOCALE_ru_RU_UTF_8 "Russian_Russia.1251"
+#define LOCALE_zh_CN_UTF_8 "Chinese_China.936"
+#elif defined(__CloudABI__)
+// Timezones are integrated into locales through LC_TIMEZONE_MASK on
+// CloudABI. LC_ALL_MASK can only be used if a timezone has also been
+// provided. UTC should be all right.
+#define LOCALE_en_US_UTF_8 "en_US.UTF-8@UTC"
+#define LOCALE_fr_FR_UTF_8 "fr_FR.UTF-8@UTC"
+#define LOCALE_fr_CA_ISO8859_1 "fr_CA.ISO-8859-1@UTC"
+#define LOCALE_cs_CZ_ISO8859_2 "cs_CZ.ISO-8859-2@UTC"
+#define LOCALE_ru_RU_UTF_8 "ru_RU.UTF-8@UTC"
+#define LOCALE_zh_CN_UTF_8 "zh_CN.UTF-8@UTC"
+#else
+#define LOCALE_en_US_UTF_8 "en_US.UTF-8"
+#define LOCALE_fr_FR_UTF_8 "fr_FR.UTF-8"
+#ifdef __linux__
+#define LOCALE_fr_CA_ISO8859_1 "fr_CA.ISO-8859-1"
+#define LOCALE_cs_CZ_ISO8859_2 "cs_CZ.ISO-8859-2"
+#else
+#define LOCALE_fr_CA_ISO8859_1 "fr_CA.ISO8859-1"
+#define LOCALE_cs_CZ_ISO8859_2 "cs_CZ.ISO8859-2"
+#endif
+#define LOCALE_ru_RU_UTF_8 "ru_RU.UTF-8"
+#define LOCALE_zh_CN_UTF_8 "zh_CN.UTF-8"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
+#include <io.h> // _mktemp
+#else
+#include <unistd.h> // close
+#endif
+
+#if defined(_NEWLIB_VERSION) && defined(__STRICT_ANSI__)
+// Newlib provies this, but in the header it's under __STRICT_ANSI__
+extern "C" {
+ int mkstemp(char*);
+}
+#endif
+
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
+inline
+std::string
+get_temp_file_name()
+{
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
+ char Path[MAX_PATH+1];
+ char FN[MAX_PATH+1];
+ do { } while (0 == GetTempPath(MAX_PATH+1, Path));
+ do { } while (0 == GetTempFileName(Path, "libcxx", 0, FN));
+ return FN;
+#else
+ std::string Name;
+ int FD = -1;
+ do {
+ Name = "libcxx.XXXXXX";
+ FD = mkstemp(&Name[0]);
+ if (FD == -1 && errno == EINVAL) {
+ perror("mkstemp");
+ abort();
+ }
+ } while (FD == -1);
+ close(FD);
+ return Name;
+#endif
+}
+#endif // _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
+
+#endif // PLATFORM_SUPPORT_H
diff --git a/test/support/private_constructor.hpp b/test/support/private_constructor.hpp
new file mode 100644
index 0000000000000..a9fcf6897233a
--- /dev/null
+++ b/test/support/private_constructor.hpp
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __PRIVATE_CONSTRUCTOR__H
+#define __PRIVATE_CONSTRUCTOR__H
+
+#include <iostream>
+
+struct PrivateConstructor {
+
+ PrivateConstructor static make ( int v ) { return PrivateConstructor(v); }
+ int get () const { return val; }
+private:
+ PrivateConstructor ( int v ) : val(v) {}
+ int val;
+ };
+
+bool operator < ( const PrivateConstructor &lhs, const PrivateConstructor &rhs ) { return lhs.get() < rhs.get(); }
+
+bool operator < ( const PrivateConstructor &lhs, int rhs ) { return lhs.get() < rhs; }
+bool operator < ( int lhs, const PrivateConstructor &rhs ) { return lhs < rhs.get(); }
+
+std::ostream & operator << ( std::ostream &os, const PrivateConstructor &foo ) { return os << foo.get (); }
+
+#endif
diff --git a/test/support/test_allocator.h b/test/support/test_allocator.h
new file mode 100644
index 0000000000000..47ef1d5567843
--- /dev/null
+++ b/test/support/test_allocator.h
@@ -0,0 +1,226 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_ALLOCATOR_H
+#define TEST_ALLOCATOR_H
+
+#include <cstddef>
+#include <type_traits>
+#include <cstdlib>
+#include <new>
+#include <climits>
+#include <cassert>
+
+#include "test_macros.h"
+
+class test_alloc_base
+{
+protected:
+ static int time_to_throw;
+public:
+ static int throw_after;
+ static int count;
+ static int alloc_count;
+};
+
+int test_alloc_base::count = 0;
+int test_alloc_base::time_to_throw = 0;
+int test_alloc_base::alloc_count = 0;
+int test_alloc_base::throw_after = INT_MAX;
+
+template <class T>
+class test_allocator
+ : public test_alloc_base
+{
+ int data_;
+
+ template <class U> friend class test_allocator;
+public:
+
+ typedef unsigned size_type;
+ typedef int difference_type;
+ typedef T value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef typename std::add_lvalue_reference<value_type>::type reference;
+ typedef typename std::add_lvalue_reference<const value_type>::type const_reference;
+
+ template <class U> struct rebind {typedef test_allocator<U> other;};
+
+ test_allocator() throw() : data_(0) {++count;}
+ explicit test_allocator(int i) throw() : data_(i) {++count;}
+ test_allocator(const test_allocator& a) throw()
+ : data_(a.data_) {++count;}
+ template <class U> test_allocator(const test_allocator<U>& a) throw()
+ : data_(a.data_) {++count;}
+ ~test_allocator() throw() {assert(data_ >= 0); --count; data_ = -1;}
+ pointer address(reference x) const {return &x;}
+ const_pointer address(const_reference x) const {return &x;}
+ pointer allocate(size_type n, const void* = 0)
+ {
+ assert(data_ >= 0);
+ if (time_to_throw >= throw_after) {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ throw std::bad_alloc();
+#else
+ std::terminate();
+#endif
+ }
+ ++time_to_throw;
+ ++alloc_count;
+ return (pointer)::operator new(n * sizeof(T));
+ }
+ void deallocate(pointer p, size_type n)
+ {assert(data_ >= 0); --alloc_count; ::operator delete((void*)p);}
+ size_type max_size() const throw()
+ {return UINT_MAX / sizeof(T);}
+ void construct(pointer p, const T& val)
+ {::new(p) T(val);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ void construct(pointer p, T&& val)
+ {::new(p) T(std::move(val));}
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ void destroy(pointer p) {p->~T();}
+
+ friend bool operator==(const test_allocator& x, const test_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const test_allocator& x, const test_allocator& y)
+ {return !(x == y);}
+};
+
+template <class T>
+class non_default_test_allocator
+ : public test_alloc_base
+{
+ int data_;
+
+ template <class U> friend class non_default_test_allocator;
+public:
+
+ typedef unsigned size_type;
+ typedef int difference_type;
+ typedef T value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef typename std::add_lvalue_reference<value_type>::type reference;
+ typedef typename std::add_lvalue_reference<const value_type>::type const_reference;
+
+ template <class U> struct rebind {typedef non_default_test_allocator<U> other;};
+
+// non_default_test_allocator() throw() : data_(0) {++count;}
+ explicit non_default_test_allocator(int i) throw() : data_(i) {++count;}
+ non_default_test_allocator(const non_default_test_allocator& a) throw()
+ : data_(a.data_) {++count;}
+ template <class U> non_default_test_allocator(const non_default_test_allocator<U>& a) throw()
+ : data_(a.data_) {++count;}
+ ~non_default_test_allocator() throw() {assert(data_ >= 0); --count; data_ = -1;}
+ pointer address(reference x) const {return &x;}
+ const_pointer address(const_reference x) const {return &x;}
+ pointer allocate(size_type n, const void* = 0)
+ {
+ assert(data_ >= 0);
+ if (time_to_throw >= throw_after) {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ throw std::bad_alloc();
+#else
+ std::terminate();
+#endif
+ }
+ ++time_to_throw;
+ ++alloc_count;
+ return (pointer)::operator new (n * sizeof(T));
+ }
+ void deallocate(pointer p, size_type n)
+ {assert(data_ >= 0); --alloc_count; ::operator delete((void*)p); }
+ size_type max_size() const throw()
+ {return UINT_MAX / sizeof(T);}
+ void construct(pointer p, const T& val)
+ {::new(p) T(val);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ void construct(pointer p, T&& val)
+ {::new(p) T(std::move(val));}
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ void destroy(pointer p) {p->~T();}
+
+ friend bool operator==(const non_default_test_allocator& x, const non_default_test_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const non_default_test_allocator& x, const non_default_test_allocator& y)
+ {return !(x == y);}
+};
+
+template <>
+class test_allocator<void>
+ : public test_alloc_base
+{
+ int data_;
+
+ template <class U> friend class test_allocator;
+public:
+
+ typedef unsigned size_type;
+ typedef int difference_type;
+ typedef void value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+
+ template <class U> struct rebind {typedef test_allocator<U> other;};
+
+ test_allocator() throw() : data_(-1) {}
+ explicit test_allocator(int i) throw() : data_(i) {}
+ test_allocator(const test_allocator& a) throw()
+ : data_(a.data_) {}
+ template <class U> test_allocator(const test_allocator<U>& a) throw()
+ : data_(a.data_) {}
+ ~test_allocator() throw() {data_ = 0;}
+
+ friend bool operator==(const test_allocator& x, const test_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const test_allocator& x, const test_allocator& y)
+ {return !(x == y);}
+};
+
+template <class T>
+class other_allocator
+{
+ int data_;
+
+ template <class U> friend class other_allocator;
+
+public:
+ typedef T value_type;
+
+ other_allocator() : data_(-1) {}
+ explicit other_allocator(int i) : data_(i) {}
+ template <class U> other_allocator(const other_allocator<U>& a)
+ : data_(a.data_) {}
+ T* allocate(std::size_t n)
+ {return (T*)::operator new(n * sizeof(T));}
+ void deallocate(T* p, std::size_t n)
+ {::operator delete((void*)p);}
+
+ other_allocator select_on_container_copy_construction() const
+ {return other_allocator(-2);}
+
+ friend bool operator==(const other_allocator& x, const other_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const other_allocator& x, const other_allocator& y)
+ {return !(x == y);}
+
+ typedef std::true_type propagate_on_container_copy_assignment;
+ typedef std::true_type propagate_on_container_move_assignment;
+ typedef std::true_type propagate_on_container_swap;
+
+#ifdef _LIBCPP_HAS_NO_ADVANCED_SFINAE
+ std::size_t max_size() const
+ {return UINT_MAX / sizeof(T);}
+#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+
+};
+
+#endif // TEST_ALLOCATOR_H
diff --git a/test/support/test_iterators.h b/test/support/test_iterators.h
new file mode 100644
index 0000000000000..e09fd834d215b
--- /dev/null
+++ b/test/support/test_iterators.h
@@ -0,0 +1,329 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ITERATORS_H
+#define ITERATORS_H
+
+#include <iterator>
+#include <cassert>
+
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+#define DELETE_FUNCTION = delete
+#else
+#define DELETE_FUNCTION
+#endif
+
+template <class It>
+class output_iterator
+{
+ It it_;
+
+ template <class U> friend class output_iterator;
+public:
+ typedef std::output_iterator_tag iterator_category;
+ typedef void value_type;
+ typedef typename std::iterator_traits<It>::difference_type difference_type;
+ typedef It pointer;
+ typedef typename std::iterator_traits<It>::reference reference;
+
+ It base() const {return it_;}
+
+ output_iterator () {}
+ explicit output_iterator(It it) : it_(it) {}
+ template <class U>
+ output_iterator(const output_iterator<U>& u) :it_(u.it_) {}
+
+ reference operator*() const {return *it_;}
+
+ output_iterator& operator++() {++it_; return *this;}
+ output_iterator operator++(int)
+ {output_iterator tmp(*this); ++(*this); return tmp;}
+
+ template <class T>
+ void operator,(T const &) DELETE_FUNCTION;
+};
+
+template <class It>
+class input_iterator
+{
+ It it_;
+
+ template <class U> friend class input_iterator;
+public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef typename std::iterator_traits<It>::value_type value_type;
+ typedef typename std::iterator_traits<It>::difference_type difference_type;
+ typedef It pointer;
+ typedef typename std::iterator_traits<It>::reference reference;
+
+ It base() const {return it_;}
+
+ input_iterator() : it_() {}
+ explicit input_iterator(It it) : it_(it) {}
+ template <class U>
+ input_iterator(const input_iterator<U>& u) :it_(u.it_) {}
+
+ reference operator*() const {return *it_;}
+ pointer operator->() const {return it_;}
+
+ input_iterator& operator++() {++it_; return *this;}
+ input_iterator operator++(int)
+ {input_iterator tmp(*this); ++(*this); return tmp;}
+
+ friend bool operator==(const input_iterator& x, const input_iterator& y)
+ {return x.it_ == y.it_;}
+ friend bool operator!=(const input_iterator& x, const input_iterator& y)
+ {return !(x == y);}
+
+ template <class T>
+ void operator,(T const &) DELETE_FUNCTION;
+};
+
+template <class T, class U>
+inline
+bool
+operator==(const input_iterator<T>& x, const input_iterator<U>& y)
+{
+ return x.base() == y.base();
+}
+
+template <class T, class U>
+inline
+bool
+operator!=(const input_iterator<T>& x, const input_iterator<U>& y)
+{
+ return !(x == y);
+}
+
+template <class It>
+class forward_iterator
+{
+ It it_;
+
+ template <class U> friend class forward_iterator;
+public:
+ typedef std::forward_iterator_tag iterator_category;
+ typedef typename std::iterator_traits<It>::value_type value_type;
+ typedef typename std::iterator_traits<It>::difference_type difference_type;
+ typedef It pointer;
+ typedef typename std::iterator_traits<It>::reference reference;
+
+ It base() const {return it_;}
+
+ forward_iterator() : it_() {}
+ explicit forward_iterator(It it) : it_(it) {}
+ template <class U>
+ forward_iterator(const forward_iterator<U>& u) :it_(u.it_) {}
+
+ reference operator*() const {return *it_;}
+ pointer operator->() const {return it_;}
+
+ forward_iterator& operator++() {++it_; return *this;}
+ forward_iterator operator++(int)
+ {forward_iterator tmp(*this); ++(*this); return tmp;}
+
+ friend bool operator==(const forward_iterator& x, const forward_iterator& y)
+ {return x.it_ == y.it_;}
+ friend bool operator!=(const forward_iterator& x, const forward_iterator& y)
+ {return !(x == y);}
+
+ template <class T>
+ void operator,(T const &) DELETE_FUNCTION;
+};
+
+template <class T, class U>
+inline
+bool
+operator==(const forward_iterator<T>& x, const forward_iterator<U>& y)
+{
+ return x.base() == y.base();
+}
+
+template <class T, class U>
+inline
+bool
+operator!=(const forward_iterator<T>& x, const forward_iterator<U>& y)
+{
+ return !(x == y);
+}
+
+template <class It>
+class bidirectional_iterator
+{
+ It it_;
+
+ template <class U> friend class bidirectional_iterator;
+public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef typename std::iterator_traits<It>::value_type value_type;
+ typedef typename std::iterator_traits<It>::difference_type difference_type;
+ typedef It pointer;
+ typedef typename std::iterator_traits<It>::reference reference;
+
+ It base() const {return it_;}
+
+ bidirectional_iterator() : it_() {}
+ explicit bidirectional_iterator(It it) : it_(it) {}
+ template <class U>
+ bidirectional_iterator(const bidirectional_iterator<U>& u) :it_(u.it_) {}
+
+ reference operator*() const {return *it_;}
+ pointer operator->() const {return it_;}
+
+ bidirectional_iterator& operator++() {++it_; return *this;}
+ bidirectional_iterator operator++(int)
+ {bidirectional_iterator tmp(*this); ++(*this); return tmp;}
+
+ bidirectional_iterator& operator--() {--it_; return *this;}
+ bidirectional_iterator operator--(int)
+ {bidirectional_iterator tmp(*this); --(*this); return tmp;}
+
+ template <class T>
+ void operator,(T const &) DELETE_FUNCTION;
+};
+
+template <class T, class U>
+inline
+bool
+operator==(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
+{
+ return x.base() == y.base();
+}
+
+template <class T, class U>
+inline
+bool
+operator!=(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
+{
+ return !(x == y);
+}
+
+template <class It>
+class random_access_iterator
+{
+ It it_;
+
+ template <class U> friend class random_access_iterator;
+public:
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef typename std::iterator_traits<It>::value_type value_type;
+ typedef typename std::iterator_traits<It>::difference_type difference_type;
+ typedef It pointer;
+ typedef typename std::iterator_traits<It>::reference reference;
+
+ It base() const {return it_;}
+
+ random_access_iterator() : it_() {}
+ explicit random_access_iterator(It it) : it_(it) {}
+ template <class U>
+ random_access_iterator(const random_access_iterator<U>& u) :it_(u.it_) {}
+
+ reference operator*() const {return *it_;}
+ pointer operator->() const {return it_;}
+
+ random_access_iterator& operator++() {++it_; return *this;}
+ random_access_iterator operator++(int)
+ {random_access_iterator tmp(*this); ++(*this); return tmp;}
+
+ random_access_iterator& operator--() {--it_; return *this;}
+ random_access_iterator operator--(int)
+ {random_access_iterator tmp(*this); --(*this); return tmp;}
+
+ random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;}
+ random_access_iterator operator+(difference_type n) const
+ {random_access_iterator tmp(*this); tmp += n; return tmp;}
+ friend random_access_iterator operator+(difference_type n, random_access_iterator x)
+ {x += n; return x;}
+ random_access_iterator& operator-=(difference_type n) {return *this += -n;}
+ random_access_iterator operator-(difference_type n) const
+ {random_access_iterator tmp(*this); tmp -= n; return tmp;}
+
+ reference operator[](difference_type n) const {return it_[n];}
+
+ template <class T>
+ void operator,(T const &) DELETE_FUNCTION;
+};
+
+template <class T, class U>
+inline
+bool
+operator==(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
+{
+ return x.base() == y.base();
+}
+
+template <class T, class U>
+inline
+bool
+operator!=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
+{
+ return !(x == y);
+}
+
+template <class T, class U>
+inline
+bool
+operator<(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
+{
+ return x.base() < y.base();
+}
+
+template <class T, class U>
+inline
+bool
+operator<=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
+{
+ return !(y < x);
+}
+
+template <class T, class U>
+inline
+bool
+operator>(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
+{
+ return y < x;
+}
+
+template <class T, class U>
+inline
+bool
+operator>=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
+{
+ return !(x < y);
+}
+
+template <class T, class U>
+inline
+typename std::iterator_traits<T>::difference_type
+operator-(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
+{
+ return x.base() - y.base();
+}
+
+template <class Iter>
+inline Iter base(output_iterator<Iter> i) { return i.base(); }
+
+template <class Iter>
+inline Iter base(input_iterator<Iter> i) { return i.base(); }
+
+template <class Iter>
+inline Iter base(forward_iterator<Iter> i) { return i.base(); }
+
+template <class Iter>
+inline Iter base(bidirectional_iterator<Iter> i) { return i.base(); }
+
+template <class Iter>
+inline Iter base(random_access_iterator<Iter> i) { return i.base(); }
+
+template <class Iter> // everything else
+inline Iter base(Iter i) { return i; }
+
+#undef DELETE_FUNCTION
+
+#endif // ITERATORS_H
diff --git a/test/support/test_macros.h b/test/support/test_macros.h
new file mode 100644
index 0000000000000..a08ca87be9350
--- /dev/null
+++ b/test/support/test_macros.h
@@ -0,0 +1,83 @@
+// -*- C++ -*-
+//===---------------------------- test_macros.h ---------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUPPORT_TEST_MACROS_HPP
+#define SUPPORT_TEST_MACROS_HPP
+
+#define TEST_CONCAT1(X, Y) X##Y
+#define TEST_CONCAT(X, Y) TEST_CONCAT1(X, Y)
+
+#ifdef __has_extension
+#define TEST_HAS_EXTENSION(X) __has_extension(X)
+#else
+#define TEST_HAS_EXTENSION(X) 0
+#endif
+
+/* Make a nice name for the standard version */
+#if __cplusplus <= 199711L
+# define TEST_STD_VER 3
+#elif __cplusplus <= 201103L
+# define TEST_STD_VER 11
+#elif __cplusplus <= 201402L
+# define TEST_STD_VER 14
+#else
+# define TEST_STD_VER 99 // greater than current standard
+#endif
+
+/* Features that were introduced in C++11 */
+#if TEST_STD_VER >= 11
+#define TEST_HAS_RVALUE_REFERENCES
+#define TEST_HAS_VARIADIC_TEMPLATES
+#define TEST_HAS_INITIALIZER_LISTS
+#define TEST_HAS_BASIC_CONSTEXPR
+#endif
+
+/* Features that were introduced in C++14 */
+#if TEST_STD_VER >= 14
+#define TEST_HAS_EXTENDED_CONSTEXPR
+#define TEST_HAS_VARIABLE_TEMPLATES
+#endif
+
+/* Features that were introduced after C++14 */
+#if TEST_STD_VER > 14
+#endif
+
+#if TEST_HAS_EXTENSION(cxx_decltype) || TEST_STD_VER >= 11
+#define TEST_DECLTYPE(T) decltype(T)
+#else
+#define TEST_DECLTYPE(T) __typeof__(T)
+#endif
+
+#if TEST_STD_VER >= 11
+#define TEST_NOEXCEPT noexcept
+#else
+#define TEST_NOEXCEPT
+#endif
+
+#if TEST_HAS_EXTENSION(cxx_static_assert) || TEST_STD_VER >= 11
+# define TEST_STATIC_ASSERT(Expr, Msg) static_assert(Expr, Msg)
+#else
+# define TEST_STATIC_ASSERT(Expr, Msg) \
+ typedef ::test_detail::static_assert_check<sizeof( \
+ ::test_detail::static_assert_incomplete_test<(Expr)>)> \
+ TEST_CONCAT(test_assert, __LINE__)
+#
+#endif
+
+namespace test_detail {
+
+template <bool> struct static_assert_incomplete_test;
+template <> struct static_assert_incomplete_test<true> {};
+template <unsigned> struct static_assert_check {};
+
+} // end namespace test_detail
+
+
+#endif // SUPPORT_TEST_MACROS_HPP
diff --git a/test/support/tracked_value.h b/test/support/tracked_value.h
new file mode 100644
index 0000000000000..b0869b23bdcbb
--- /dev/null
+++ b/test/support/tracked_value.h
@@ -0,0 +1,50 @@
+#ifndef SUPPORT_TRACKED_VALUE_H
+#define SUPPORT_TRACKED_VALUE_H
+
+#include <cassert>
+
+struct TrackedValue {
+ enum State { CONSTRUCTED, MOVED_FROM, DESTROYED };
+ State state;
+
+ TrackedValue() : state(State::CONSTRUCTED) {}
+
+ TrackedValue(TrackedValue const& t) : state(State::CONSTRUCTED) {
+ assert(t.state != State::MOVED_FROM && "copying a moved-from object");
+ assert(t.state != State::DESTROYED && "copying a destroyed object");
+ }
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ TrackedValue(TrackedValue&& t) : state(State::CONSTRUCTED) {
+ assert(t.state != State::MOVED_FROM && "double moving from an object");
+ assert(t.state != State::DESTROYED && "moving from a destroyed object");
+ t.state = State::MOVED_FROM;
+ }
+#endif
+
+ TrackedValue& operator=(TrackedValue const& t) {
+ assert(state != State::DESTROYED && "copy assigning into destroyed object");
+ assert(t.state != State::MOVED_FROM && "copying a moved-from object");
+ assert(t.state != State::DESTROYED && "copying a destroyed object");
+ state = t.state;
+ return *this;
+ }
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ TrackedValue& operator=(TrackedValue&& t) {
+ assert(state != State::DESTROYED && "move assigning into destroyed object");
+ assert(t.state != State::MOVED_FROM && "double moving from an object");
+ assert(t.state != State::DESTROYED && "moving from a destroyed object");
+ state = t.state;
+ t.state = State::MOVED_FROM;
+ return *this;
+ }
+#endif
+
+ ~TrackedValue() {
+ assert(state != State::DESTROYED && "double-destroying an object");
+ state = State::DESTROYED;
+ }
+};
+
+#endif // SUPPORT_TRACKED_VALUE_H
diff --git a/test/support/user_defined_integral.hpp b/test/support/user_defined_integral.hpp
new file mode 100644
index 0000000000000..3b0f7a19fcf40
--- /dev/null
+++ b/test/support/user_defined_integral.hpp
@@ -0,0 +1,44 @@
+#ifndef SUPPORT_USER_DEFINED_INTEGRAL_HPP
+#define SUPPORT_USER_DEFINED_INTEGRAL_HPP
+
+template <class T>
+struct UserDefinedIntegral
+{
+ UserDefinedIntegral() : value(0) {}
+ UserDefinedIntegral(T v) : value(v) {}
+ operator T() const { return value; }
+ T value;
+};
+
+// Poison the arithmetic and comparison operations
+template <class T, class U>
+void operator+(UserDefinedIntegral<T>, UserDefinedIntegral<U>);
+
+template <class T, class U>
+void operator-(UserDefinedIntegral<T>, UserDefinedIntegral<U>);
+
+template <class T, class U>
+void operator*(UserDefinedIntegral<T>, UserDefinedIntegral<U>);
+
+template <class T, class U>
+void operator/(UserDefinedIntegral<T>, UserDefinedIntegral<U>);
+
+template <class T, class U>
+void operator==(UserDefinedIntegral<T>, UserDefinedIntegral<U>);
+
+template <class T, class U>
+void operator!=(UserDefinedIntegral<T>, UserDefinedIntegral<U>);
+
+template <class T, class U>
+void operator<(UserDefinedIntegral<T>, UserDefinedIntegral<U>);
+
+template <class T, class U>
+void operator>(UserDefinedIntegral<T>, UserDefinedIntegral<U>);
+
+template <class T, class U>
+void operator<=(UserDefinedIntegral<T>, UserDefinedIntegral<U>);
+
+template <class T, class U>
+void operator>=(UserDefinedIntegral<T>, UserDefinedIntegral<U>);
+
+#endif // SUPPORT_USER_DEFINED_INTEGRAL_HPP