-
Notifications
You must be signed in to change notification settings - Fork 11
noexceptions #88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
noexceptions #88
Changes from 7 commits
d6b00ff
55e0e78
7cef9c6
43ed978
7810199
dd1f1ee
0b91e2d
25eb57b
4b951fc
d5041e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| #ifndef BEMAN_INPLACE_VECTOR_CONFIG_HPP | ||
| #define BEMAN_INPLACE_VECTOR_CONFIG_HPP | ||
|
|
||
| #cmakedefine01 BEMAN_INPLACE_VECTOR_NO_EXCEPTIONS() | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,6 +43,17 @@ add_gtest(size_n_data) | |
| add_gtest(erasure) | ||
| add_gtest(modifiers) | ||
|
|
||
| if( | ||
| 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 | ||
| ) | ||
|
Comment on lines
+55
to
+58
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this still needed?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it ensures that there are no throws in the compiled code. Without it, EXPECT_DEATH could still pass if an unhandled exception was thrown. Although, I'm now not sure if we need the compiler check. It allows running the tests on compilers that don't support or have a different syntax for disabling exceptions (e.g. MSVC). But right now, CI only includes Clang and GCC, and maybe it would be better to error out instead of silently skipping tests on other compilers. On the other hand, it doesn't matter much, as the implementation should be compiler agnostic as long as there is abort() CMAKE_CXX_COMPILER_ID STREQUAL "Clang"
OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU" |
||
| endif() | ||
|
|
||
| # constexpr test | ||
| add_executable(beman.inplace_vector.tests.constexpr constexpr.test.cpp) | ||
| target_link_libraries( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,158 @@ | ||
| #include <array> | ||
|
|
||
| #include "gtest_setup.hpp" | ||
|
|
||
| namespace { | ||
|
|
||
| // clang-format off | ||
| using exceptionTestTypes = ::testing::Types< | ||
| TestParam<Trivial, 0>, TestParam<Trivial, 42>, | ||
| TestParam<NonTrivial, 0>, TestParam<NonTrivial, 42>>; | ||
| // clang-format on | ||
|
|
||
| template <typename Param> class NoExceptions : public IVBasicTest<Param> {}; | ||
| 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<T, 1>{}; | ||
| 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<T, IV::capacity() + 1>{}); | ||
| }, | ||
| ".*"); | ||
|
|
||
| EXPECT_DEATH( | ||
| { | ||
| IV device = this->unique(); | ||
| device.append_range(std::array<T, 1>{}); | ||
| }, | ||
| ".*"); | ||
|
|
||
| // 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<T, N> without | ||
| // parenthesis () | ||
| auto range = (std::array<T, IV::capacity()>{}); | ||
| device.insert(device.end(), range.begin(), range.end()); | ||
| }, | ||
| ".*"); | ||
| } | ||
|
|
||
| EXPECT_DEATH( | ||
| { | ||
| IV device{}; | ||
| // test macro fails to compile if we use std::array<T, N> without | ||
| // parenthesis () | ||
| auto range = (std::array<T, IV::capacity() + 1>{}); | ||
| 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 |
Uh oh!
There was an error while loading. Please reload this page.