about summary refs log tree commit diff
path: root/absl/container/inlined_vector_exception_safety_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/container/inlined_vector_exception_safety_test.cc')
-rw-r--r--absl/container/inlined_vector_exception_safety_test.cc93
1 files changed, 93 insertions, 0 deletions
diff --git a/absl/container/inlined_vector_exception_safety_test.cc b/absl/container/inlined_vector_exception_safety_test.cc
index 0a9649250302..e7c47127df9f 100644
--- a/absl/container/inlined_vector_exception_safety_test.cc
+++ b/absl/container/inlined_vector_exception_safety_test.cc
@@ -12,7 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include <array>
+#include <initializer_list>
+#include <iterator>
 #include <memory>
+#include <utility>
 
 #include "gtest/gtest.h"
 #include "absl/base/internal/exception_safety_testing.h"
@@ -81,6 +85,24 @@ using OneSizeTestParams =
                      TestParams<ThrowAllocMovableThrowerVec, kLargeSize>,
                      TestParams<ThrowAllocMovableThrowerVec, kSmallSize>>;
 
+using TwoSizeTestParams = ::testing::Types<
+    TestParams<ThrowerVec, kLargeSize, kLargeSize>,
+    TestParams<ThrowerVec, kLargeSize, kSmallSize>,
+    TestParams<ThrowerVec, kSmallSize, kLargeSize>,
+    TestParams<ThrowerVec, kSmallSize, kSmallSize>,
+    TestParams<MovableThrowerVec, kLargeSize, kLargeSize>,
+    TestParams<MovableThrowerVec, kLargeSize, kSmallSize>,
+    TestParams<MovableThrowerVec, kSmallSize, kLargeSize>,
+    TestParams<MovableThrowerVec, kSmallSize, kSmallSize>,
+    TestParams<ThrowAllocThrowerVec, kLargeSize, kLargeSize>,
+    TestParams<ThrowAllocThrowerVec, kLargeSize, kSmallSize>,
+    TestParams<ThrowAllocThrowerVec, kSmallSize, kLargeSize>,
+    TestParams<ThrowAllocThrowerVec, kSmallSize, kSmallSize>,
+    TestParams<ThrowAllocMovableThrowerVec, kLargeSize, kLargeSize>,
+    TestParams<ThrowAllocMovableThrowerVec, kLargeSize, kSmallSize>,
+    TestParams<ThrowAllocMovableThrowerVec, kSmallSize, kLargeSize>,
+    TestParams<ThrowAllocMovableThrowerVec, kSmallSize, kSmallSize>>;
+
 template <typename>
 struct NoSizeTest : ::testing::Test {};
 TYPED_TEST_SUITE(NoSizeTest, NoSizeTestParams);
@@ -89,6 +111,25 @@ template <typename>
 struct OneSizeTest : ::testing::Test {};
 TYPED_TEST_SUITE(OneSizeTest, OneSizeTestParams);
 
+template <typename>
+struct TwoSizeTest : ::testing::Test {};
+TYPED_TEST_SUITE(TwoSizeTest, TwoSizeTestParams);
+
+template <typename VecT>
+bool InlinedVectorInvariants(VecT* vec) {
+  if (*vec != *vec) return false;
+  if (vec->size() > vec->capacity()) return false;
+  if (vec->size() > vec->max_size()) return false;
+  if (vec->capacity() > vec->max_size()) return false;
+  if (vec->data() != std::addressof(vec->at(0))) return false;
+  if (vec->data() != vec->begin()) return false;
+  if (*vec->data() != *vec->begin()) return false;
+  if (vec->begin() > vec->end()) return false;
+  if ((vec->end() - vec->begin()) != vec->size()) return false;
+  if (std::distance(vec->begin(), vec->end()) != vec->size()) return false;
+  return true;
+}
+
 // Function that always returns false is correct, but refactoring is required
 // for clarity. It's needed to express that, as a contract, certain operations
 // should not throw at all. Execution of this function means an exception was
@@ -179,6 +220,45 @@ TYPED_TEST(OneSizeTest, MoveConstructor) {
   }
 }
 
+TYPED_TEST(TwoSizeTest, Assign) {
+  using VecT = typename TypeParam::VecT;
+  using value_type = typename VecT::value_type;
+  constexpr static auto from_size = TypeParam::GetSizeAt(0);
+  constexpr static auto to_size = TypeParam::GetSizeAt(1);
+
+  auto tester = testing::MakeExceptionSafetyTester()
+                    .WithInitialValue(VecT{from_size})
+                    .WithContracts(InlinedVectorInvariants<VecT>);
+
+  EXPECT_TRUE(tester.Test([](VecT* vec) {
+    *vec = ABSL_INTERNAL_MAKE_INIT_LIST(value_type, to_size);
+  }));
+
+  EXPECT_TRUE(tester.Test([](VecT* vec) {
+    VecT other_vec{to_size};
+    *vec = other_vec;
+  }));
+
+  EXPECT_TRUE(tester.Test([](VecT* vec) {
+    VecT other_vec{to_size};
+    *vec = std::move(other_vec);
+  }));
+
+  EXPECT_TRUE(tester.Test([](VecT* vec) {
+    value_type val{};
+    vec->assign(to_size, val);
+  }));
+
+  EXPECT_TRUE(tester.Test([](VecT* vec) {
+    vec->assign(ABSL_INTERNAL_MAKE_INIT_LIST(value_type, to_size));
+  }));
+
+  EXPECT_TRUE(tester.Test([](VecT* vec) {
+    std::array<value_type, to_size> arr{};
+    vec->assign(arr.begin(), arr.end());
+  }));
+}
+
 TYPED_TEST(OneSizeTest, PopBack) {
   using VecT = typename TypeParam::VecT;
   constexpr static auto size = TypeParam::GetSizeAt(0);
@@ -205,4 +285,17 @@ TYPED_TEST(OneSizeTest, Clear) {
   }));
 }
 
+TYPED_TEST(OneSizeTest, ShrinkToFit) {
+  using VecT = typename TypeParam::VecT;
+  constexpr static auto size = TypeParam::GetSizeAt(0);
+
+  auto tester = testing::MakeExceptionSafetyTester()
+                    .WithInitialValue(VecT{size})
+                    .WithContracts(InlinedVectorInvariants<VecT>);
+
+  EXPECT_TRUE(tester.Test([](VecT* vec) {
+    vec->shrink_to_fit();  //
+  }));
+}
+
 }  // namespace