From 5c875e394938c68248ff8e771de6cb8cc768702c Mon Sep 17 00:00:00 2001 From: Arthur O'Dwyer Date: Tue, 6 Nov 2018 08:10:09 -0500 Subject: [PATCH] Make inplace_function's move operations "noexcept". Fixes #128. --- SG14/inplace_function.h | 12 ++++++------ SG14_test/inplace_function_test.cpp | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/SG14/inplace_function.h b/SG14/inplace_function.h index 40677f74..de5664c8 100644 --- a/SG14/inplace_function.h +++ b/SG14/inplace_function.h @@ -104,7 +104,7 @@ template struct vtable { ::new (dst_ptr) C{ (*static_cast(src_ptr)) }; } }, relocate_ptr{ [](storage_ptr_t dst_ptr, storage_ptr_t src_ptr) - noexcept(std::is_nothrow_move_constructible::value) -> void + noexcept -> void { ::new (dst_ptr) C{ std::move(*static_cast(src_ptr)) }; static_cast(src_ptr)->~C(); @@ -220,7 +220,7 @@ class inplace_function ); } - inplace_function(inplace_function&& other) : + inplace_function(inplace_function&& other) noexcept : vtable_ptr_{std::exchange(other.vtable_ptr_, std::addressof(inplace_function_detail::empty_vtable))} { vtable_ptr_->relocate_ptr( @@ -251,7 +251,7 @@ class inplace_function return *this; } - inplace_function& operator= (inplace_function&& other) + inplace_function& operator= (inplace_function&& other) noexcept { if(this != std::addressof(other)) { @@ -305,7 +305,7 @@ class inplace_function } template - operator inplace_function() && + operator inplace_function() && noexcept { static_assert(inplace_function_detail::is_valid_inplace_dst< Cap, Align, Capacity, Alignment @@ -316,7 +316,7 @@ class inplace_function return {vtable_ptr, vtable_ptr->relocate_ptr, std::addressof(storage_)}; } - void swap(inplace_function& other) + void swap(inplace_function& other) noexcept { if (this == std::addressof(other)) return; @@ -339,7 +339,7 @@ class inplace_function std::swap(vtable_ptr_, other.vtable_ptr_); } - friend void swap(inplace_function& lhs, inplace_function& rhs) + friend void swap(inplace_function& lhs, inplace_function& rhs) noexcept { lhs.swap(rhs); } diff --git a/SG14_test/inplace_function_test.cpp b/SG14_test/inplace_function_test.cpp index 732d806c..a5859bfb 100644 --- a/SG14_test/inplace_function_test.cpp +++ b/SG14_test/inplace_function_test.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #define EXPECT_EQ(val1, val2) assert(val1 == val2) #define EXPECT_TRUE(val) assert(val) @@ -398,6 +399,18 @@ static void test_overloaded_operator_new() EXPECT_EQ(43, fun(1)); } +void test_move_construction_is_noexcept() +{ + using IPF = stdext::inplace_function; + std::vector vec; + vec.push_back(Functor()); + copied = 0; + moved = 0; + vec.reserve(vec.capacity() + 1); + EXPECT_EQ(0, copied); + EXPECT_EQ(1, moved); +} + void sg14_test::inplace_function_test() { // first set of tests (from Optiver) @@ -479,6 +492,7 @@ void sg14_test::inplace_function_test() test_exception_safety(); test_nullptr(); test_overloaded_operator_new(); + test_move_construction_is_noexcept(); } #ifdef TEST_MAIN