| //===----------------------------------------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef ALLOCATORS_H |
| #define ALLOCATORS_H |
| |
| #include <type_traits> |
| #include <utility> |
| |
| #include "test_macros.h" |
| |
| #if TEST_STD_VER >= 11 |
| |
| 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;} |
| A1& operator=(const A1& a) TEST_NOEXCEPT { id_ = a.id(); copy_called = true; return *this;} |
| A1& operator=(A1&& a) TEST_NOEXCEPT { id_ = a.id(); move_called = true; return *this;} |
| |
| 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;} |
| A2& operator=(const A2& a) TEST_NOEXCEPT { id_ = a.id(); copy_called = true; return *this;} |
| A2& operator=(A2&& a) TEST_NOEXCEPT { id_ = a.id(); move_called = true; return *this;} |
| |
| T* allocate(std::size_t, const void* hint) |
| { |
| allocate_called = true; |
| return (T*) const_cast<void *>(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;} |
| A3& operator=(const A3& a) TEST_NOEXCEPT { id_ = a.id(); copy_called = true; return *this;} |
| A3& operator=(A3&& a) TEST_NOEXCEPT { id_ = a.id(); move_called = true; return *this;} |
| |
| 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 // TEST_STD_VER >= 11 |
| |
| #endif // ALLOCATORS_H |