diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 7c74165..8337f8f 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -55,6 +55,8 @@ jobs: args: "-DCMAKE_CXX_FLAGS=-fsanitize=thread" - description: "ASan" args: "-DCMAKE_CXX_FLAGS='-fsanitize=address -fsanitize=undefined'" + - description: "NoExcep" + args: "-DBEMAN_INPLACE_VECTOR_NO_EXCEPTIONS=on" include: - platform: ubuntu-24.04 compiler: diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c6a78f..e5330c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,18 @@ option( ${PROJECT_IS_TOP_LEVEL} ) +option( + BEMAN_INPLACE_VECTOR_NO_EXCEPTIONS + "Disable exceptions by replacing throw calls with abort. Default: OFF. Values: { ON, OFF }." + OFF +) + +configure_file( + "${PROJECT_SOURCE_DIR}/include/beman/inplace_vector/config.hpp.in" + "${PROJECT_BINARY_DIR}/include/beman/inplace_vector/config.hpp" + @ONLY +) + include(FetchContent) include(GNUInstallDirs) @@ -38,6 +50,7 @@ target_include_directories( beman.inplace_vector INTERFACE $ + $ $ ) diff --git a/include/beman/inplace_vector/config.hpp.in b/include/beman/inplace_vector/config.hpp.in new file mode 100644 index 0000000..b551164 --- /dev/null +++ b/include/beman/inplace_vector/config.hpp.in @@ -0,0 +1,6 @@ +#ifndef BEMAN_INPLACE_VECTOR_CONFIG_HPP +#define BEMAN_INPLACE_VECTOR_CONFIG_HPP + +#cmakedefine01 BEMAN_INPLACE_VECTOR_NO_EXCEPTIONS() + +#endif diff --git a/include/beman/inplace_vector/inplace_vector.hpp b/include/beman/inplace_vector/inplace_vector.hpp index aa6a7fa..da3c45d 100644 --- a/include/beman/inplace_vector/inplace_vector.hpp +++ b/include/beman/inplace_vector/inplace_vector.hpp @@ -3,6 +3,10 @@ #ifndef BEMAN_INPLACE_VECTOR_INPLACE_VECTOR_HPP #define BEMAN_INPLACE_VECTOR_INPLACE_VECTOR_HPP +#if !defined(__has_include) || __has_include() +#include +#endif + #include // for rotate... #include #include @@ -10,19 +14,27 @@ #include // for size_t #include // for fixed-width integer types #include // for assertion diagnostics -#include // for abort #include // for less and equal_to #include // for reverse_iterator and iterator traits #include // for numeric_limits #include // for destroy #include // for operator new #include -#include // for length_error #include // for aligned_storage and all meta-functions // Artifact from previous implementation, can be used as hints for optimizer #define IV_EXPECT(EXPR) +#ifndef BEMAN_IV_THROW_OR_ABORT +#if BEMAN_INPLACE_VECTOR_NO_EXCEPTIONS() +#include // for abort +#define BEMAN_IV_THROW_OR_ABORT(x) abort() +#else +#include // for length_error +#define BEMAN_IV_THROW_OR_ABORT(x) throw x +#endif +#endif + // beman::from_range_t namespace beman { struct from_range_t {}; @@ -260,8 +272,9 @@ struct inplace_vector static constexpr size_type max_size() noexcept { return N; } static constexpr size_type capacity() noexcept { return N; } constexpr void reserve(size_type n) { - if (n > N) [[unlikely]] - throw std::bad_alloc(); + if (n > N) [[unlikely]] { + BEMAN_IV_THROW_OR_ABORT(std::bad_alloc()); + } } constexpr void shrink_to_fit() {} @@ -351,8 +364,9 @@ struct inplace_vector constexpr T &emplace_back(Args &&...args) requires(std::constructible_from) { - if (!try_emplace_back(std::forward(args)...)) [[unlikely]] - throw std::bad_alloc(); + if (!try_emplace_back(std::forward(args)...)) [[unlikely]] { + BEMAN_IV_THROW_OR_ABORT(std::bad_alloc()); + } return back(); } constexpr T &push_back(const T &x) @@ -395,12 +409,14 @@ struct inplace_vector requires(std::constructible_from>) { if constexpr (std::ranges::sized_range) { - if (size() + std::ranges::size(rg) > capacity()) [[unlikely]] - throw std::bad_alloc(); + if (size() + std::ranges::size(rg) > capacity()) [[unlikely]] { + BEMAN_IV_THROW_OR_ABORT(std::bad_alloc()); + } } for (auto &&e : rg) { - if (size() == capacity()) [[unlikely]] - throw std::bad_alloc(); + if (size() == capacity()) [[unlikely]] { + BEMAN_IV_THROW_OR_ABORT(std::bad_alloc()); + } emplace_back(std::forward(e)); } } @@ -438,8 +454,9 @@ struct inplace_vector assert_iterator_in_range(position); if constexpr (std::random_access_iterator) { if (size() + static_cast(std::distance(first, last)) > - capacity()) [[unlikely]] - throw std::bad_alloc{}; + capacity()) [[unlikely]] { + BEMAN_IV_THROW_OR_ABORT(std::bad_alloc()); + } } auto b = end(); for (; first != last; ++first) @@ -555,9 +572,9 @@ struct inplace_vector { if (sz == size()) return; - else if (sz > N) [[unlikely]] - throw std::bad_alloc{}; - else if (sz > size()) + else if (sz > N) [[unlikely]] { + BEMAN_IV_THROW_OR_ABORT(std::bad_alloc()); + } else if (sz > size()) insert(end(), sz - size(), c); else { unsafe_destroy(begin() + sz, end()); @@ -569,25 +586,27 @@ struct inplace_vector { if (sz == size()) return; - else if (sz > N) [[unlikely]] - throw std::bad_alloc{}; - else if (sz > size()) + else if (sz > N) [[unlikely]] { + BEMAN_IV_THROW_OR_ABORT(std::bad_alloc()); + } else if (sz > size()) { while (size() != sz) emplace_back(T{}); - else { + } else { unsafe_destroy(begin() + sz, end()); unsafe_set_size(sz); } } constexpr reference at(size_type pos) { - if (pos >= size()) [[unlikely]] - throw std::out_of_range("inplace_vector::at"); + if (pos >= size()) [[unlikely]] { + BEMAN_IV_THROW_OR_ABORT(std::out_of_range("inplace_vector::at")); + } return details::inplace_vector::index(*this, pos); } constexpr const_reference at(size_type pos) const { - if (pos >= size()) [[unlikely]] - throw std::out_of_range("inplace_vector::at"); + if (pos >= size()) [[unlikely]] { + BEMAN_IV_THROW_OR_ABORT(std::out_of_range("inplace_vector::at")); + } return details::inplace_vector::index(*this, pos); } @@ -606,7 +625,7 @@ struct inplace_vector std::copyable) { for (auto &&e : x) - emplace_back(e); + unchecked_emplace_back(e); } constexpr inplace_vector(inplace_vector &&x) @@ -618,7 +637,7 @@ struct inplace_vector std::movable) { for (auto &&e : x) - emplace_back(std::move(e)); + unchecked_emplace_back(std::move(e)); } constexpr inplace_vector &operator=(const inplace_vector &x) @@ -636,7 +655,7 @@ struct inplace_vector { clear(); for (auto &&e : x) - emplace_back(e); + unchecked_emplace_back(e); return *this; } @@ -655,7 +674,7 @@ struct inplace_vector { clear(); for (auto &&e : x) - emplace_back(std::move(e)); + unchecked_emplace_back(std::move(e)); return *this; } diff --git a/tests/beman/inplace_vector/CMakeLists.txt b/tests/beman/inplace_vector/CMakeLists.txt index 1d80ab2..2f93633 100644 --- a/tests/beman/inplace_vector/CMakeLists.txt +++ b/tests/beman/inplace_vector/CMakeLists.txt @@ -43,6 +43,21 @@ add_gtest(size_n_data) add_gtest(erasure) add_gtest(modifiers) +# only add noexception tests if NO_EXCEPTIONS option is set and compiler supports -fno-exceptions +if( + BEMAN_INPLACE_VECTOR_NO_EXCEPTIONS + AND ( + CMAKE_CXX_COMPILER_ID STREQUAL "Clang" + OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU" + ) +) + add_gtest(noexceptions) + target_compile_options( + beman.inplace_vector.tests.noexceptions + PRIVATE -fno-exceptions + ) +endif() + # constexpr test add_executable(beman.inplace_vector.tests.constexpr constexpr.test.cpp) target_link_libraries( diff --git a/tests/beman/inplace_vector/constructors.test.cpp b/tests/beman/inplace_vector/constructors.test.cpp index 6e018f8..556f678 100644 --- a/tests/beman/inplace_vector/constructors.test.cpp +++ b/tests/beman/inplace_vector/constructors.test.cpp @@ -21,7 +21,7 @@ TYPED_TEST(Constructors, SizedDefault) { EXPECT_EQ(IV(0), IV{}); - EXPECT_THROW(IV(IV::capacity() + 1), std::bad_alloc); + SAFE_EXPECT_THROW(IV(IV::capacity() + 1), std::bad_alloc); constexpr auto mid_size = std::midpoint(0ul, IV::capacity()); IV mid(mid_size); @@ -57,7 +57,7 @@ TYPED_TEST(Constructors, SizedValue) { IV device(0, value); EXPECT_EQ(device, IV{}); - EXPECT_THROW(IV(IV::capacity() + 1, value), std::bad_alloc); + SAFE_EXPECT_THROW(IV(IV::capacity() + 1, value), std::bad_alloc); } if constexpr (IV::capacity() < 1u) diff --git a/tests/beman/inplace_vector/container_requirements.test.cpp b/tests/beman/inplace_vector/container_requirements.test.cpp index ec91a00..aaa9c1b 100644 --- a/tests/beman/inplace_vector/container_requirements.test.cpp +++ b/tests/beman/inplace_vector/container_requirements.test.cpp @@ -626,7 +626,7 @@ TYPED_TEST(SequenceContainerRequirements, ConstructorInitializerList) { using T = TestFixture::T; if (IV::capacity() == 0) { - EXPECT_THROW(IV({T{20}}), std::bad_alloc); + SAFE_EXPECT_THROW(IV({T{20}}), std::bad_alloc); return; } @@ -657,7 +657,7 @@ TYPED_TEST(SequenceContainerRequirements, AssignInitializerList) { if (IV::capacity() == 0) { IV device; - EXPECT_THROW(device = {T{52}}, std::bad_alloc); + SAFE_EXPECT_THROW(device = {T{52}}, std::bad_alloc); return; } @@ -787,7 +787,7 @@ TYPED_TEST(SequenceContainerRequirements, AssignIterRange) { EXPECT_EQ(device, correct); std::array ref{}; - EXPECT_THROW(device.assign(ref.begin(), ref.end()), std::bad_alloc); + SAFE_EXPECT_THROW(device.assign(ref.begin(), ref.end()), std::bad_alloc); } { @@ -802,7 +802,7 @@ TYPED_TEST(SequenceContainerRequirements, AssignIterRange) { // [containers.sequences.inplace.vector.overview] // 5. Any member function of inplace_vector that would cause the size // to exceed N throws an exception of type bad_alloc. - EXPECT_THROW( + SAFE_EXPECT_THROW( device.assign(InputIterator{0}, InputIterator{IV::max_size() + 1}), std::bad_alloc); } @@ -833,7 +833,7 @@ TYPED_TEST(SequenceContainerRequirements, AssignRange) { std::array ref; std::copy(correct.begin(), correct.end(), ref.begin()); ref.back() = T{5}; - EXPECT_THROW(device.assign_range(ref), std::bad_alloc); + SAFE_EXPECT_THROW(device.assign_range(ref), std::bad_alloc); } // a.assign(il) @@ -846,7 +846,7 @@ TYPED_TEST(SequenceContainerRequirements, AssignFuncInitializerList) { auto device = this->unique(); if (device.capacity() == 0) { - EXPECT_THROW(device.assign({T{50}}), std::bad_alloc); + SAFE_EXPECT_THROW(device.assign({T{50}}), std::bad_alloc); return; } @@ -916,7 +916,8 @@ TYPED_TEST(SequenceContainerRequirements, AssignMulti) { } device.clear(); - EXPECT_THROW(device.assign(device.capacity() + 1, T{12}), std::bad_alloc); + SAFE_EXPECT_THROW(device.assign(device.capacity() + 1, T{12}), + std::bad_alloc); } // a.front() @@ -1017,7 +1018,7 @@ TYPED_TEST(SequenceContainerRequirements, ElementAccessAt) { EXPECT_EQ(device.at(i), *(device.begin() + i)); } - EXPECT_THROW(device.at(IV::capacity()), std::out_of_range); + SAFE_EXPECT_THROW(device.at(IV::capacity()), std::out_of_range); } }; // namespace diff --git a/tests/beman/inplace_vector/gtest_setup.hpp b/tests/beman/inplace_vector/gtest_setup.hpp index 4c8a868..1517492 100644 --- a/tests/beman/inplace_vector/gtest_setup.hpp +++ b/tests/beman/inplace_vector/gtest_setup.hpp @@ -392,3 +392,11 @@ template class IVBasicTest : public ::testing::Test { template std::size_t IVBasicTest::InputIterator::num_deref; + +#if BEMAN_INPLACE_VECTOR_NO_EXCEPTIONS() +#define SAFE_EXPECT_THROW(x, y) \ + do { \ + } while (0) +#else +#define SAFE_EXPECT_THROW(x, y) EXPECT_THROW(x, y) +#endif diff --git a/tests/beman/inplace_vector/inplace_vector.test.cpp b/tests/beman/inplace_vector/inplace_vector.test.cpp index fee9c6b..cfb1d9c 100644 --- a/tests/beman/inplace_vector/inplace_vector.test.cpp +++ b/tests/beman/inplace_vector/inplace_vector.test.cpp @@ -65,6 +65,12 @@ template constexpr void test() { assert(const_data == std::addressof(const_front)); } +#if BEMAN_INPLACE_VECTOR_NO_EXCEPTIONS() +int main() { + test(); + return 0; +} +#else void test_exceptions() { using vec = inplace_vector; { @@ -86,8 +92,10 @@ void test_exceptions() { } } } + int main() { test(); test_exceptions(); return 0; } +#endif diff --git a/tests/beman/inplace_vector/modifiers.test.cpp b/tests/beman/inplace_vector/modifiers.test.cpp index bee74d1..068d2c5 100644 --- a/tests/beman/inplace_vector/modifiers.test.cpp +++ b/tests/beman/inplace_vector/modifiers.test.cpp @@ -42,10 +42,10 @@ TYPED_TEST(Modifiers, InsertSingleConstRef) { } T val{272}; - EXPECT_THROW(device.insert(device.begin(), val), std::bad_alloc); + SAFE_EXPECT_THROW(device.insert(device.begin(), val), std::bad_alloc); EXPECT_EQ(device, reference); - EXPECT_THROW(device.insert(device.begin(), val), std::bad_alloc); + SAFE_EXPECT_THROW(device.insert(device.begin(), val), std::bad_alloc); EXPECT_EQ(device, reference); } @@ -82,10 +82,10 @@ TYPED_TEST(Modifiers, InsertSingleRV) { } } - EXPECT_THROW(device.insert(device.begin(), T{272}), std::bad_alloc); + SAFE_EXPECT_THROW(device.insert(device.begin(), T{272}), std::bad_alloc); EXPECT_EQ(device, reference); - EXPECT_THROW(device.insert(device.begin(), T{272}), std::bad_alloc); + SAFE_EXPECT_THROW(device.insert(device.begin(), T{272}), std::bad_alloc); EXPECT_EQ(device, reference); } @@ -121,10 +121,10 @@ TYPED_TEST(Modifiers, InsertEmplace) { } } - EXPECT_THROW(device.emplace(device.begin(), 272), std::bad_alloc); + SAFE_EXPECT_THROW(device.emplace(device.begin(), 272), std::bad_alloc); EXPECT_EQ(device, reference); - EXPECT_THROW(device.emplace(device.begin(), 272), std::bad_alloc); + SAFE_EXPECT_THROW(device.emplace(device.begin(), 272), std::bad_alloc); EXPECT_EQ(device, reference); } @@ -161,7 +161,7 @@ TYPED_TEST(Modifiers, InsertMulti) { } EXPECT_NO_THROW(device.insert(device.begin(), 0, {2538})); - EXPECT_THROW(device.insert(device.begin(), 1, {2538}), std::bad_alloc); + SAFE_EXPECT_THROW(device.insert(device.begin(), 1, {2538}), std::bad_alloc); } TYPED_TEST(Modifiers, InsertInitList) { @@ -201,7 +201,7 @@ TYPED_TEST(Modifiers, InsertInitList) { auto full = this->unique(); EXPECT_NO_THROW(full.insert(full.begin(), {})); - EXPECT_THROW(full.insert(full.begin(), {T{25}}), std::bad_alloc); + SAFE_EXPECT_THROW(full.insert(full.begin(), {T{25}}), std::bad_alloc); } TYPED_TEST(Modifiers, InsertRange) { @@ -257,8 +257,9 @@ TYPED_TEST(Modifiers, InsertRange) { EXPECT_NO_THROW(device.insert_range(device.begin(), std::array{})); EXPECT_EQ(device, reference); - EXPECT_THROW(device.insert_range(device.begin(), std::array{T{25}}), - std::bad_alloc); + SAFE_EXPECT_THROW( + device.insert_range(device.begin(), std::array{T{25}}), + std::bad_alloc); } TYPED_TEST(Modifiers, InsertItrRange) { @@ -315,7 +316,7 @@ TYPED_TEST(Modifiers, InsertItrRange) { EXPECT_EQ(device, reference); std::array single_array{T{25}}; - EXPECT_THROW( + SAFE_EXPECT_THROW( device.insert(device.begin(), single_array.begin(), single_array.end()), std::bad_alloc); } @@ -375,7 +376,7 @@ TYPED_TEST(Modifiers, PushBackConstRef) { } T val{0}; - EXPECT_THROW(device.push_back(val), std::bad_alloc); + SAFE_EXPECT_THROW(device.push_back(val), std::bad_alloc); } TYPED_TEST(Modifiers, PushBackRV) { @@ -401,7 +402,7 @@ TYPED_TEST(Modifiers, PushBackRV) { } T val{0}; - EXPECT_THROW(device.push_back(val), std::bad_alloc); + SAFE_EXPECT_THROW(device.push_back(val), std::bad_alloc); } // TODO: Check if there's extra copies @@ -427,7 +428,7 @@ TYPED_TEST(Modifiers, EmplaceBack) { EXPECT_EQ(device, IV(reference.begin(), reference.begin() + i + 1)); } - EXPECT_THROW(device.emplace_back(0), std::bad_alloc); + SAFE_EXPECT_THROW(device.emplace_back(0), std::bad_alloc); } TYPED_TEST(Modifiers, TryEmplaceBack) { @@ -701,7 +702,7 @@ TYPED_TEST(Modifiers, ReserveNonEmpty) { device.reserve(device.capacity()); EXPECT_EQ(device, reference); - EXPECT_THROW(device.reserve(device.capacity() + 1), std::bad_alloc); + SAFE_EXPECT_THROW(device.reserve(device.capacity() + 1), std::bad_alloc); } TYPED_TEST(Modifiers, ReserveEmpty) { @@ -723,7 +724,7 @@ TYPED_TEST(Modifiers, ReserveEmpty) { device.reserve(device.capacity()); EXPECT_EQ(device, IV()); - EXPECT_THROW(device.reserve(device.capacity() + 1), std::bad_alloc); + SAFE_EXPECT_THROW(device.reserve(device.capacity() + 1), std::bad_alloc); } TYPED_TEST(Modifiers, ShrinkToFitNonEmpty) { diff --git a/tests/beman/inplace_vector/noexceptions.test.cpp b/tests/beman/inplace_vector/noexceptions.test.cpp new file mode 100644 index 0000000..709d64e --- /dev/null +++ b/tests/beman/inplace_vector/noexceptions.test.cpp @@ -0,0 +1,161 @@ +#include + +#include +#define BEMAN_IV_THROW_OR_ABORT(x) abort() + +#include "gtest_setup.hpp" + +namespace { + +// clang-format off +using exceptionTestTypes = ::testing::Types< + TestParam, TestParam, + TestParam, TestParam>; +// clang-format on + +template class NoExceptions : public IVBasicTest {}; +TYPED_TEST_SUITE(NoExceptions, exceptionTestTypes); + +TYPED_TEST(NoExceptions, NonThrowing) { + + using IV = TestFixture::IV; + using T = TestFixture::T; + + const auto reference = this->unique(); + + IV device; + + device.assign(reference.begin(), reference.end()); + EXPECT_EQ(device, reference); + + EXPECT_EQ(device.try_emplace_back(T{}), nullptr); + EXPECT_EQ(device.try_push_back(T{}), nullptr); + auto range = std::array{}; + EXPECT_EQ(device.try_append_range(range), range.begin()); + + IV sanitycheck = this->unique(); + EXPECT_EQ(sanitycheck.size(), IV::capacity()); +} + +TYPED_TEST(NoExceptions, emplace_back) { + + using IV = TestFixture::IV; + using T = TestFixture::T; + GTEST_FLAG_SET(death_test_style, "fast"); + + EXPECT_DEATH( + { + IV device = this->unique(); + device.emplace_back(T{}); + }, + ".*"); +} + +TYPED_TEST(NoExceptions, resize) { + + using IV = TestFixture::IV; + using T = TestFixture::T; + GTEST_FLAG_SET(death_test_style, "fast"); + + EXPECT_DEATH( + { + IV device = this->unique(); + device.resize(IV::capacity() + 1); + }, + ".*"); + + EXPECT_DEATH( + { + IV device = this->unique(); + device.resize(IV::capacity() + 1, T{}); + }, + ".*"); +} + +TYPED_TEST(NoExceptions, reserve) { + + using IV = TestFixture::IV; + using T = TestFixture::T; + GTEST_FLAG_SET(death_test_style, "fast"); + + EXPECT_DEATH( + { + IV device = this->unique(); + device.reserve(IV::capacity() + 1); + }, + ".*"); +} + +TYPED_TEST(NoExceptions, append_range) { + + using IV = TestFixture::IV; + using T = TestFixture::T; + GTEST_FLAG_SET(death_test_style, "fast"); + + EXPECT_DEATH( + { + IV device{}; + device.append_range(std::array{}); + }, + ".*"); + + EXPECT_DEATH( + { + IV device = this->unique(); + device.append_range(std::array{}); + }, + ".*"); + + // TODO consider adding test for append_range of unsized range +} + +TYPED_TEST(NoExceptions, insert) { + + using IV = TestFixture::IV; + using T = TestFixture::T; + GTEST_FLAG_SET(death_test_style, "fast"); + + if constexpr (IV::capacity() > 0) { + EXPECT_DEATH( + { + IV device = this->unique(); + // test macro fails to compile if we use std::array without + // parenthesis () + auto range = (std::array{}); + device.insert(device.end(), range.begin(), range.end()); + }, + ".*"); + } + + EXPECT_DEATH( + { + IV device{}; + // test macro fails to compile if we use std::array without + // parenthesis () + auto range = (std::array{}); + device.insert(device.end(), range.begin(), range.end()); + }, + ".*"); +} + +TYPED_TEST(NoExceptions, at) { + + using IV = TestFixture::IV; + using T = TestFixture::T; + GTEST_FLAG_SET(death_test_style, "fast"); + + EXPECT_DEATH( + { + IV device = this->unique(); + auto e = device.at(IV::capacity()); + }, + ".*"); + + EXPECT_DEATH( + { + IV device; + const auto e = device.at(IV::capacity()); + }, + ".*"); +} +} // namespace diff --git a/tests/beman/inplace_vector/ref_impl.test.cpp b/tests/beman/inplace_vector/ref_impl.test.cpp index 835508a..83c0564 100644 --- a/tests/beman/inplace_vector/ref_impl.test.cpp +++ b/tests/beman/inplace_vector/ref_impl.test.cpp @@ -42,6 +42,11 @@ static constexpr void __assert_failure(char const *__file, int __line, : ::__assert_failure(static_cast(__FILE__), __LINE__, \ "assertion failed: " #__VA_ARGS__)) +#if BEMAN_INPLACE_VECTOR_NO_EXCEPTIONS() +#define CHECK_THROWS(EXPR, EXCEPT) \ + do { \ + } while (0) +#else #define CHECK_THROWS(EXPR, EXCEPT) \ if (auto e = \ [&] { \ @@ -58,6 +63,7 @@ static constexpr void __assert_failure(char const *__file, int __line, __assert_failure(static_cast(__FILE__), __LINE__, \ "expression failed to throw " #EXCEPT ": " #EXPR); \ } +#endif template struct beman::details::inplace_vector::storage::zero_sized; template struct beman::details::inplace_vector::storage::trivial; diff --git a/tests/beman/inplace_vector/size_n_data.test.cpp b/tests/beman/inplace_vector/size_n_data.test.cpp index b46414d..1d45fc8 100644 --- a/tests/beman/inplace_vector/size_n_data.test.cpp +++ b/tests/beman/inplace_vector/size_n_data.test.cpp @@ -56,7 +56,7 @@ TYPED_TEST(SizeNCapacity, ResizeUp) { IV device; - EXPECT_THROW(device.resize(device.capacity() + 1), std::bad_alloc); + SAFE_EXPECT_THROW(device.resize(device.capacity() + 1), std::bad_alloc); EXPECT_EQ(device, IV{}); if (device.capacity() == 0) @@ -86,7 +86,7 @@ TYPED_TEST(SizeNCapacity, ResizeUp) { } IV before_resize(device); - EXPECT_THROW(device.resize(device.capacity() + 1), std::bad_alloc); + SAFE_EXPECT_THROW(device.resize(device.capacity() + 1), std::bad_alloc); EXPECT_EQ(device, before_resize); }