diff options
Diffstat (limited to 'libcxx/test')
3 files changed, 99 insertions, 0 deletions
diff --git a/libcxx/test/std/containers/sequences/deque/deque.modifiers/emplace_back.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.modifiers/emplace_back.pass.cpp index 4859a371895..784b3a38553 100644 --- a/libcxx/test/std/containers/sequences/deque/deque.modifiers/emplace_back.pass.cpp +++ b/libcxx/test/std/containers/sequences/deque/deque.modifiers/emplace_back.pass.cpp @@ -16,6 +16,7 @@ #include "../../../Emplaceable.h" #include "min_allocator.h" +#include "test_allocator.h" #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -82,6 +83,17 @@ int main() for (int j = 0; j < N; ++j) testN<std::deque<Emplaceable, min_allocator<Emplaceable>> >(rng[i], rng[j]); } + { + std::deque<Tag_X, TaggingAllocator<Tag_X>> c; + c.emplace_back(); + assert(c.size() == 1); + c.emplace_back(1, 2, 3); + assert(c.size() == 2); + c.emplace_front(); + assert(c.size() == 3); + c.emplace_front(1, 2, 3); + assert(c.size() == 4); + } #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp index a58f8f02cdc..61ccade76b0 100644 --- a/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp @@ -15,6 +15,7 @@ #include <cassert> #include "../../../stack_allocator.h" #include "min_allocator.h" +#include "test_allocator.h" #include "asan_testing.h" #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -102,6 +103,14 @@ int main() assert(c.back().getd() == 4.5); assert(is_contiguous_container_asan_correct(c)); } + { + std::vector<Tag_X, TaggingAllocator<Tag_X>> c; + c.emplace_back(); + assert(c.size() == 1); + c.emplace_back(1, 2, 3); + assert(c.size() == 2); + assert(is_contiguous_container_asan_correct(c)); + } #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } 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 |