From 93810790ae6f5336902a07675a0537a726e66739 Mon Sep 17 00:00:00 2001 From: Gene Harvey Date: Sat, 30 Nov 2024 17:42:26 -0600 Subject: [PATCH] Add verification of proper usage of `select_on_container_copy_construction` to unit tests --- source/test/test_allocators.hpp | 99 ++++++++++++++++++- source/test/unit/member/assign/test-copy.cpp | 4 + source/test/unit/member/assign/test-move.cpp | 4 + .../unit/member/constructor/test-copy.cpp | 2 + .../unit/member/constructor/test-move.cpp | 2 + 5 files changed, 110 insertions(+), 1 deletion(-) diff --git a/source/test/test_allocators.hpp b/source/test/test_allocators.hpp index b9a6dfb..6ae3fe3 100644 --- a/source/test/test_allocators.hpp +++ b/source/test/test_allocators.hpp @@ -399,7 +399,8 @@ namespace gch template constexpr GCH_IMPLICIT_CONVERSION verifying_allocator (const verifying_allocator& other) noexcept - : base (other) + : base (other), + created_by_container_copy_construction (other.created_by_container_copy_construction) { } GCH_NODISCARD @@ -452,8 +453,44 @@ namespace gch remove_object (p); alloc_traits::destroy (*this, p); } + + verifying_allocator + select_on_container_copy_construction () const + { + verifying_allocator ret (*this); + ret.created_by_container_copy_construction = true; + return ret; + } + + bool created_by_container_copy_construction = false; }; + template + constexpr void + verify_created_by_container_copy_construction (const A& a) + { } + + template + constexpr void + verify_created_by_container_copy_construction (const verifying_allocator& a) + { + assert (a.created_by_container_copy_construction + && "select_on_container_copy_construction unexpectedly invoked"); + } + + template + constexpr void + verify_not_created_by_container_copy_construction (const A& a) + { } + + template + constexpr void + verify_not_created_by_container_copy_construction (const verifying_allocator& a) + { + assert (! a.created_by_container_copy_construction + && "select_on_container_copy_construction unexpectedly not invoked"); + } + template constexpr bool @@ -489,6 +526,12 @@ namespace gch using propagate_on_container_move_assignment = std::false_type; using propagate_on_container_copy_assignment = std::false_type; using propagate_on_container_swap = std::false_type; + + non_propagating_verifying_allocator + select_on_container_copy_construction () const + { + return non_propagating_verifying_allocator {}; + } }; template @@ -604,6 +647,60 @@ namespace gch return ! (lhs == rhs); } + template + class allocator_testing_traits + { + template + struct has_created_by_container_copy_construction_field + : std::false_type + { }; + + template + struct has_created_by_container_copy_construction_field + : std::true_type + { }; + + public: + template ::value + >::type * = nullptr> + constexpr void + verify_created_by_container_copy_construction (const A& a) + { + assert (a.created_by_container_copy_construction + && "select_on_container_copy_construction unexpectedly not invoked"); + } + + template ::value + >::type * = nullptr> + constexpr void + verify_created_by_container_copy_construction (const A&) + { } + + template ::value + >::type * = nullptr> + constexpr void + verify_not_created_by_container_copy_construction (const A& a) + { + assert (! a.created_by_container_copy_construction + && "select_on_container_copy_construction unexpectedly not invoked"); + } + + template ::value + >::type * = nullptr> + constexpr void + verify_not_created_by_container_copy_construction (const A&) + { } + }; + } } diff --git a/source/test/unit/member/assign/test-copy.cpp b/source/test/unit/member/assign/test-copy.cpp index 98eb044..a3643be 100644 --- a/source/test/unit/member/assign/test-copy.cpp +++ b/source/test/unit/member/assign/test-copy.cpp @@ -211,6 +211,7 @@ struct tester n.assign (m); CHECK (n == m_cmp); + gch::test_types::verify_not_created_by_container_copy_construction (n.get_allocator ()); } { // vector_type (ni) -> vector_type (mi) @@ -222,6 +223,7 @@ struct tester m.assign (n); CHECK (m == n_cmp); + gch::test_types::verify_not_created_by_container_copy_construction (m.get_allocator ()); } { // vector_type (ni) -> vector_type (mi) @@ -233,6 +235,7 @@ struct tester n.assign (m); CHECK (n == n_cmp); + gch::test_types::verify_not_created_by_container_copy_construction (n.get_allocator ()); } { // vector_type (mi) -> vector_type (ni) @@ -244,6 +247,7 @@ struct tester m.assign (n); CHECK (m == m_cmp); + gch::test_types::verify_not_created_by_container_copy_construction (m.get_allocator ()); } } diff --git a/source/test/unit/member/assign/test-move.cpp b/source/test/unit/member/assign/test-move.cpp index b5bca52..8b41ee8 100644 --- a/source/test/unit/member/assign/test-move.cpp +++ b/source/test/unit/member/assign/test-move.cpp @@ -318,6 +318,7 @@ struct tester n.assign (std::move (m)); CHECK (n == m_cmp); + gch::test_types::verify_not_created_by_container_copy_construction (n.get_allocator ()); } { // vector_type (ni) -> vector_type (mi) @@ -329,6 +330,7 @@ struct tester m.assign (std::move (n)); CHECK (m == n_cmp); + gch::test_types::verify_not_created_by_container_copy_construction (m.get_allocator ()); } { // vector_type (ni) -> vector_type (mi) @@ -340,6 +342,7 @@ struct tester n.assign (std::move (m)); CHECK (n == n_cmp); + gch::test_types::verify_not_created_by_container_copy_construction (n.get_allocator ()); } { // vector_type (mi) -> vector_type (ni) @@ -351,6 +354,7 @@ struct tester m.assign (std::move (n)); CHECK (m == m_cmp); + gch::test_types::verify_not_created_by_container_copy_construction (m.get_allocator ()); } } diff --git a/source/test/unit/member/constructor/test-copy.cpp b/source/test/unit/member/constructor/test-copy.cpp index 9955189..bfd971a 100644 --- a/source/test/unit/member/constructor/test-copy.cpp +++ b/source/test/unit/member/constructor/test-copy.cpp @@ -118,6 +118,7 @@ struct tester vector_type v (m); CHECK (v == m_cmp); + gch::test_types::verify_created_by_container_copy_construction (v.get_allocator ()); } { vector_type m (mi.begin (), mi.end (), m_alloc); @@ -125,6 +126,7 @@ struct tester vector_type v (m, m_alloc); CHECK (v == m_cmp); + gch::test_types::verify_not_created_by_container_copy_construction (v.get_allocator ()); } } diff --git a/source/test/unit/member/constructor/test-move.cpp b/source/test/unit/member/constructor/test-move.cpp index 621a520..7c2bb4f 100644 --- a/source/test/unit/member/constructor/test-move.cpp +++ b/source/test/unit/member/constructor/test-move.cpp @@ -119,6 +119,7 @@ struct tester vector_type v (std::move (m)); CHECK (v == m_cmp); + gch::test_types::verify_not_created_by_container_copy_construction (v.get_allocator ()); } { vector_type m (mi.begin (), mi.end (), m_alloc); @@ -126,6 +127,7 @@ struct tester vector_type v (std::move (m), m_init_alloc); CHECK (v == m_cmp); + gch::test_types::verify_not_created_by_container_copy_construction (v.get_allocator ()); } }