diff --git a/include/sg14/aa_inplace_vector.h b/include/sg14/aa_inplace_vector.h index 8312463..03940d8 100644 --- a/include/sg14/aa_inplace_vector.h +++ b/include/sg14/aa_inplace_vector.h @@ -293,6 +293,11 @@ struct ipv_alloc_holder { #endif explicit ipv_alloc_holder() = default; constexpr explicit ipv_alloc_holder(const Alloc& alloc) : alloc_(alloc) {} + ipv_alloc_holder(const ipv_alloc_holder&) noexcept = default; + ipv_alloc_holder(ipv_alloc_holder&&) noexcept = default; + ipv_alloc_holder& operator=(const ipv_alloc_holder&) noexcept = default; + ipv_alloc_holder& operator=(ipv_alloc_holder&&) noexcept = default; + ~ipv_alloc_holder() noexcept = default; constexpr const Alloc& get_allocator_() const { return alloc_; } }; @@ -397,13 +402,11 @@ struct SG14_INPLACE_VECTOR_TRIVIALLY_RELOCATABLE_IF((sg14::aaipv::be_trivially_r static constexpr bool CopyCtorIsNoexcept = ((std::is_nothrow_copy_constructible_v && sg14::aaipv::has_trivial_construct::value) || (N == 0)) && - sg14::aaipv::propagate_on_container_copy_construction::value && - std::is_nothrow_copy_constructible_v>; + sg14::aaipv::propagate_on_container_copy_construction::value; static constexpr bool MoveCtorIsNoexcept = ((std::is_nothrow_move_constructible_v && - sg14::aaipv::has_trivial_construct::value) || (N == 0)) && - std::is_nothrow_move_constructible_v>; + sg14::aaipv::has_trivial_construct::value) || (N == 0)); // Copy-assignment follows the Lakos Rule: if the precondition might be violated, then it's not noexcept. // diff --git a/test/aa_inplace_vector_test.cpp b/test/aa_inplace_vector_test.cpp index 12bf14d..099f673 100644 --- a/test/aa_inplace_vector_test.cpp +++ b/test/aa_inplace_vector_test.cpp @@ -33,6 +33,23 @@ struct CountingAlloc { } }; +template +struct NonNoexceptAlloc { + using value_type = T; + using propagate_on_container_copy_assignment = std::bool_constant; + using propagate_on_container_move_assignment = std::bool_constant; + using propagate_on_container_swap = std::bool_constant; + using is_always_equal = std::false_type; + explicit NonNoexceptAlloc(int); + NonNoexceptAlloc(const NonNoexceptAlloc&); // non-throwing but not noexcept + NonNoexceptAlloc(NonNoexceptAlloc&&); // non-throwing but not noexcept + NonNoexceptAlloc& operator=(const NonNoexceptAlloc&); // non-throwing but not noexcept + NonNoexceptAlloc& operator=(NonNoexceptAlloc&&); // non-throwing but not noexcept + ~NonNoexceptAlloc() noexcept(false); // non-throwing but not noexcept + friend bool operator==(NonNoexceptAlloc, NonNoexceptAlloc) { return true; } // non-throwing but not noexcept + int i_; +}; + TEST(aa_inplace_vector, AllocExtendedCopyCtor) { using A = CountingAlloc; @@ -63,4 +80,24 @@ TEST(aa_inplace_vector, AllocExtendedMoveCtor) EXPECT_EQ(mr2.size(), 3u); } +TEST(aa_inplace_vector, IgnoreNoexceptnessOfAllocator) +{ + { + using T = sg14::inplace_vector>; + static_assert(std::is_nothrow_copy_constructible_v); + static_assert(std::is_nothrow_move_constructible_v); + static_assert(std::is_nothrow_copy_assignable_v); + static_assert(std::is_nothrow_move_assignable_v); + static_assert(std::is_nothrow_destructible_v); + } + { + using T = sg14::inplace_vector>; + static_assert(std::is_nothrow_copy_constructible_v); + static_assert(std::is_nothrow_move_constructible_v); + static_assert(std::is_nothrow_copy_assignable_v); + static_assert(std::is_nothrow_move_assignable_v); + static_assert(std::is_nothrow_destructible_v); + } +} + #endif // __cplusplus >= 202002L