1 /*
2 * Copyright 2020 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "rtc_base/bounded_inline_vector.h"
12
13 #include <memory>
14 #include <string>
15 #include <utility>
16
17 #include "test/gmock.h"
18 #include "test/gtest.h"
19
20 namespace webrtc {
21 namespace {
22
23 using SmallTrivial = BoundedInlineVector<int, 2>;
24 using LargeTrivial = BoundedInlineVector<int, 200>;
25 using NonTrivial = BoundedInlineVector<std::string, 2>;
26 static_assert(std::is_trivially_copyable<SmallTrivial>::value, "");
27 static_assert(!std::is_trivially_copyable<LargeTrivial>::value, "");
28 static_assert(std::is_trivially_destructible<LargeTrivial>::value, "");
29 static_assert(!std::is_trivially_copyable<NonTrivial>::value, "");
30 static_assert(!std::is_trivially_destructible<NonTrivial>::value, "");
31
32 template <typename T>
33 class BoundedInlineVectorTestAllTypes : public ::testing::Test {};
34
35 using AllTypes =
36 ::testing::Types<int, // Scalar type.
37 std::pair<int, float>, // Trivial nonprimitive type.
38 std::unique_ptr<int>, // Move-only type.
39 std::string>; // Nontrivial copyable type.
40 TYPED_TEST_SUITE(BoundedInlineVectorTestAllTypes, AllTypes);
41
42 template <typename T>
43 class BoundedInlineVectorTestCopyableTypes : public ::testing::Test {};
44
45 using CopyableTypes = ::testing::Types<int, std::pair<int, float>, std::string>;
46 TYPED_TEST_SUITE(BoundedInlineVectorTestCopyableTypes, CopyableTypes);
47
TYPED_TEST(BoundedInlineVectorTestAllTypes,ConstructEmpty)48 TYPED_TEST(BoundedInlineVectorTestAllTypes, ConstructEmpty) {
49 BoundedInlineVector<TypeParam, 3> x;
50 EXPECT_EQ(x.size(), 0);
51 EXPECT_EQ(x.begin(), x.end());
52 static_assert(x.capacity() == 3, "");
53 }
54
TYPED_TEST(BoundedInlineVectorTestAllTypes,ConstructNonempty)55 TYPED_TEST(BoundedInlineVectorTestAllTypes, ConstructNonempty) {
56 BoundedInlineVector<TypeParam, 3> x = {TypeParam(), TypeParam()};
57 EXPECT_EQ(x.size(), 2);
58 static_assert(x.capacity() == 3, "");
59 }
60
TYPED_TEST(BoundedInlineVectorTestCopyableTypes,CopyConstruct)61 TYPED_TEST(BoundedInlineVectorTestCopyableTypes, CopyConstruct) {
62 BoundedInlineVector<TypeParam, 3> x = {TypeParam(), TypeParam()};
63 BoundedInlineVector<TypeParam, 2> y = x;
64 EXPECT_EQ(y.size(), 2);
65 static_assert(x.capacity() == 3, "");
66 static_assert(y.capacity() == 2, "");
67 }
68
TYPED_TEST(BoundedInlineVectorTestCopyableTypes,CopyAssign)69 TYPED_TEST(BoundedInlineVectorTestCopyableTypes, CopyAssign) {
70 BoundedInlineVector<TypeParam, 3> x = {TypeParam(), TypeParam()};
71 BoundedInlineVector<TypeParam, 2> y;
72 EXPECT_EQ(y.size(), 0);
73 y = x;
74 EXPECT_EQ(y.size(), 2);
75 }
76
TYPED_TEST(BoundedInlineVectorTestAllTypes,MoveConstruct)77 TYPED_TEST(BoundedInlineVectorTestAllTypes, MoveConstruct) {
78 BoundedInlineVector<TypeParam, 3> x = {TypeParam(), TypeParam()};
79 BoundedInlineVector<TypeParam, 2> y = std::move(x);
80 EXPECT_EQ(y.size(), 2);
81 static_assert(x.capacity() == 3, "");
82 static_assert(y.capacity() == 2, "");
83 }
84
TYPED_TEST(BoundedInlineVectorTestAllTypes,MoveAssign)85 TYPED_TEST(BoundedInlineVectorTestAllTypes, MoveAssign) {
86 BoundedInlineVector<TypeParam, 3> x = {TypeParam(), TypeParam()};
87 BoundedInlineVector<TypeParam, 2> y;
88 EXPECT_EQ(y.size(), 0);
89 y = std::move(x);
90 EXPECT_EQ(y.size(), 2);
91 }
92
TEST(BoundedInlineVectorTestOneType,Iteration)93 TEST(BoundedInlineVectorTestOneType, Iteration) {
94 BoundedInlineVector<std::string, 4> sv{"one", "two", "three", "four"};
95 std::string cat;
96 for (const auto& s : sv) {
97 cat += s;
98 }
99 EXPECT_EQ(cat, "onetwothreefour");
100 }
101
TEST(BoundedInlineVectorTestOneType,Indexing)102 TEST(BoundedInlineVectorTestOneType, Indexing) {
103 BoundedInlineVector<double, 1> x = {3.14};
104 EXPECT_EQ(x[0], 3.14);
105 }
106
107 template <typename T, int capacity, typename... Ts>
Returns(Ts...values)108 BoundedInlineVector<T, capacity> Returns(Ts... values) {
109 return {std::forward<Ts>(values)...};
110 }
111
TYPED_TEST(BoundedInlineVectorTestAllTypes,Return)112 TYPED_TEST(BoundedInlineVectorTestAllTypes, Return) {
113 EXPECT_EQ((Returns<TypeParam, 3>().size()), 0);
114 EXPECT_EQ((Returns<TypeParam, 3>(TypeParam(), TypeParam()).size()), 2);
115 }
116
TYPED_TEST(BoundedInlineVectorTestAllTypes,Resize)117 TYPED_TEST(BoundedInlineVectorTestAllTypes, Resize) {
118 BoundedInlineVector<TypeParam, 17> x;
119 EXPECT_EQ(x.size(), 0);
120 x.resize(17);
121 EXPECT_EQ(x.size(), 17);
122 // Test one arbitrary element, mostly to give MSan a chance to scream. But if
123 // the type has a trivial default constructor we can't, because the element
124 // won't be initialized.
125 if (!std::is_trivially_default_constructible<TypeParam>::value) {
126 EXPECT_EQ(x[4], TypeParam());
127 }
128 x.resize(2);
129 EXPECT_EQ(x.size(), 2);
130 }
131
132 } // namespace
133 } // namespace webrtc
134