diff options
Diffstat (limited to 'test/support')
-rw-r--r-- | test/support/Counter.h | 52 | ||||
-rw-r--r-- | test/support/DefaultOnly.h | 35 | ||||
-rw-r--r-- | test/support/MoveOnly.h | 50 | ||||
-rw-r--r-- | test/support/allocators.h | 185 | ||||
-rw-r--r-- | test/support/asan_testing.h | 37 | ||||
-rw-r--r-- | test/support/cmpxchg_loop.h | 51 | ||||
-rw-r--r-- | test/support/constexpr_char_traits.hpp | 138 | ||||
-rw-r--r-- | test/support/count_new.hpp | 206 | ||||
-rw-r--r-- | test/support/counting_predicates.hpp | 46 | ||||
-rw-r--r-- | test/support/hexfloat.h | 38 | ||||
-rw-r--r-- | test/support/is_transparent.h | 73 | ||||
-rw-r--r-- | test/support/min_allocator.h | 291 | ||||
-rw-r--r-- | test/support/nasty_containers.hpp | 282 | ||||
-rw-r--r-- | test/support/nasty_macros.hpp | 32 | ||||
-rw-r--r-- | test/support/nothing_to_do.pass.cpp | 14 | ||||
-rw-r--r-- | test/support/platform_support.h | 98 | ||||
-rw-r--r-- | test/support/private_constructor.hpp | 31 | ||||
-rw-r--r-- | test/support/test_allocator.h | 226 | ||||
-rw-r--r-- | test/support/test_iterators.h | 329 | ||||
-rw-r--r-- | test/support/test_macros.h | 83 | ||||
-rw-r--r-- | test/support/tracked_value.h | 50 | ||||
-rw-r--r-- | test/support/user_defined_integral.hpp | 44 |
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 |