diff options
Diffstat (limited to 'libcxx/test/support/test_allocator.h')
-rw-r--r-- | libcxx/test/support/test_allocator.h | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/libcxx/test/support/test_allocator.h b/libcxx/test/support/test_allocator.h index 551477119c1..466c7fabc66 100644 --- a/libcxx/test/support/test_allocator.h +++ b/libcxx/test/support/test_allocator.h @@ -228,4 +228,82 @@ public: }; +#if TEST_STD_VER >= 11 + +struct Ctor_Tag {}; + +template <typename T> class TaggingAllocator; + +struct Tag_X { + // All constructors must be passed the Tag type. + + // DefaultInsertable into vector<X, TaggingAllocator<X>>, + Tag_X(Ctor_Tag) {} + // CopyInsertable into vector<X, TaggingAllocator<X>>, + Tag_X(Ctor_Tag, const Tag_X&) {} + // MoveInsertable into vector<X, TaggingAllocator<X>>, and + Tag_X(Ctor_Tag, Tag_X&&) {} + + // EmplaceConstructible into vector<X, TaggingAllocator<X>> from args. + template<typename... Args> + Tag_X(Ctor_Tag, Args&&...) { } + + // not DefaultConstructible, CopyConstructible or MoveConstructible. + Tag_X() = delete; + Tag_X(const Tag_X&) = delete; + Tag_X(Tag_X&&) = delete; + + // CopyAssignable. + Tag_X& operator=(const Tag_X&) { return *this; } + + // MoveAssignable. + Tag_X& operator=(Tag_X&&) { return *this; } + +private: + // Not Destructible. + ~Tag_X() { } + + // Erasable from vector<X, TaggingAllocator<X>>. + friend class TaggingAllocator<Tag_X>; +}; + + +template<typename T> +class TaggingAllocator { +public: + using value_type = T; + TaggingAllocator() = default; + + template<typename U> + TaggingAllocator(const TaggingAllocator<U>&) { } + + T* allocate(std::size_t n) { return std::allocator<T>{}.allocate(n); } + + void deallocate(T* p, std::size_t n) { std::allocator<T>{}.deallocate(p, n); } + + template<typename... Args> + void construct(Tag_X* p, Args&&... args) + { ::new((void*)p) Tag_X(Ctor_Tag{}, std::forward<Args>(args)...); } + + template<typename U, typename... Args> + void construct(U* p, Args&&... args) + { ::new((void*)p) U(std::forward<Args>(args)...); } + + template<typename U, typename... Args> + void destroy(U* p) + { p->~U(); } +}; + +template<typename T, typename U> +bool +operator==(const TaggingAllocator<T>&, const TaggingAllocator<U>&) +{ return true; } + +template<typename T, typename U> +bool +operator!=(const TaggingAllocator<T>&, const TaggingAllocator<U>&) +{ return false; } +#endif + + #endif // TEST_ALLOCATOR_H |