Skip to content

Commit 56cf4c7

Browse files
committed
Add vector_of_ptr
1 parent e601d5b commit 56cf4c7

File tree

4 files changed

+183
-0
lines changed

4 files changed

+183
-0
lines changed

Firestore/Example/Firestore.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@
179179
535F51F2FF2AB52A6E629091 /* FSTLevelDBMutationQueueTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E0872021552A00B64F25 /* FSTLevelDBMutationQueueTests.mm */; };
180180
53AB47E44D897C81A94031F6 /* write.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D921C2DDC800EFB9CC /* write.pb.cc */; };
181181
54080260D85A6F583E61DA1D /* FSTLocalSerializerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E08A2021552A00B64F25 /* FSTLocalSerializerTests.mm */; };
182+
540C379D22C1741000E70F15 /* vector_of_ptr_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 540C379C22C1741000E70F15 /* vector_of_ptr_test.cc */; };
183+
540C379E22C1741000E70F15 /* vector_of_ptr_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 540C379C22C1741000E70F15 /* vector_of_ptr_test.cc */; };
184+
540C379F22C1741000E70F15 /* vector_of_ptr_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 540C379C22C1741000E70F15 /* vector_of_ptr_test.cc */; };
182185
54131E9720ADE679001DF3FF /* string_format_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54131E9620ADE678001DF3FF /* string_format_test.cc */; };
183186
544129DA21C2DDC800EFB9CC /* common.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D221C2DDC800EFB9CC /* common.pb.cc */; };
184187
544129DB21C2DDC800EFB9CC /* firestore.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D421C2DDC800EFB9CC /* firestore.pb.cc */; };
@@ -779,6 +782,7 @@
779782
444B7AB3F5A2929070CB1363 /* hard_assert_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = hard_assert_test.cc; sourceTree = "<group>"; };
780783
4C73C0CC6F62A90D8573F383 /* string_apple_benchmark.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; path = string_apple_benchmark.mm; sourceTree = "<group>"; };
781784
5342CDDB137B4E93E2E85CCA /* byte_string_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = byte_string_test.cc; path = nanopb/byte_string_test.cc; sourceTree = "<group>"; };
785+
540C379C22C1741000E70F15 /* vector_of_ptr_test.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = vector_of_ptr_test.cc; sourceTree = "<group>"; };
782786
54131E9620ADE678001DF3FF /* string_format_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = string_format_test.cc; sourceTree = "<group>"; };
783787
544129D021C2DDC800EFB9CC /* query.pb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = query.pb.h; sourceTree = "<group>"; };
784788
544129D121C2DDC800EFB9CC /* common.pb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common.pb.h; sourceTree = "<group>"; };
@@ -1312,6 +1316,7 @@
13121316
79507DF8378D3C42F5B36268 /* string_win_test.cc */,
13131317
B68B1E002213A764008977EF /* to_string_apple_test.mm */,
13141318
B696858D2214B53900271095 /* to_string_test.cc */,
1319+
540C379C22C1741000E70F15 /* vector_of_ptr_test.cc */,
13151320
);
13161321
path = util;
13171322
sourceTree = "<group>";
@@ -3145,6 +3150,7 @@
31453150
8DA258092DD856D829D973B5 /* transform_operations_test.mm in Sources */,
31463151
5F19F66D8B01BA2B97579017 /* tree_sorted_map_test.cc in Sources */,
31473152
16F52ECC6FA8A0587CD779EB /* user_test.cc in Sources */,
3153+
540C379E22C1741000E70F15 /* vector_of_ptr_test.cc in Sources */,
31483154
E3C0E5F834A82EEE9F8C4519 /* watch_change_test.mm in Sources */,
31493155
53AB47E44D897C81A94031F6 /* write.pb.cc in Sources */,
31503156
59E6941008253D4B0F77C2BA /* writer_test.cc in Sources */,
@@ -3320,6 +3326,7 @@
33203326
5C7FAF228D0F52CFFE9E41B5 /* transform_operations_test.mm in Sources */,
33213327
627253FDEC6BB5549FE77F4E /* tree_sorted_map_test.cc in Sources */,
33223328
596C782EFB68131380F8EEF8 /* user_test.cc in Sources */,
3329+
540C379F22C1741000E70F15 /* vector_of_ptr_test.cc in Sources */,
33233330
178FE1E277C63B3E7120BE56 /* watch_change_test.mm in Sources */,
33243331
A5AB1815C45FFC762981E481 /* write.pb.cc in Sources */,
33253332
A21819C437C3C80450D7EEEE /* writer_test.cc in Sources */,
@@ -3574,6 +3581,7 @@
35743581
54A0352720A3AED0003E0143 /* transform_operations_test.mm in Sources */,
35753582
549CCA5120A36DBC00BCEB75 /* tree_sorted_map_test.cc in Sources */,
35763583
ABC1D7DE2023A05300BA84F0 /* user_test.cc in Sources */,
3584+
540C379D22C1741000E70F15 /* vector_of_ptr_test.cc in Sources */,
35773585
B68FC0E521F6848700A7055C /* watch_change_test.mm in Sources */,
35783586
544129DE21C2DDC800EFB9CC /* write.pb.cc in Sources */,
35793587
3BA4EEA6153B3833F86B8104 /* writer_test.cc in Sources */,
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright 2019 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_VECTOR_OF_PTR_H_
18+
#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_VECTOR_OF_PTR_H_
19+
20+
#include <initializer_list>
21+
#include <memory>
22+
#include <utility>
23+
#include <vector>
24+
25+
#include "absl/algorithm/container.h"
26+
27+
namespace firebase {
28+
namespace firestore {
29+
namespace util {
30+
31+
/**
32+
* A std::vector of some pointer type where equality and many other operations
33+
* are defined as operating on the value pointed to rather than on the pointers
34+
* themselves.
35+
*
36+
* Contrast with `std::vector<std::shared_ptr<T>>`, where `operator==` just
37+
* checks if the pointers in the collection are equal rather than checking if
38+
* the things the pointers point to are equal.
39+
*
40+
* This is useful in cases where values of type T need to be held by pointer
41+
* for some reason, usually this is to enable polymorphism or because copying
42+
* values of T is expensive.
43+
*/
44+
template <typename T, typename P = std::shared_ptr<T>>
45+
class vector_of_ptr {
46+
public:
47+
using value_type = T;
48+
using pointer_type = P;
49+
using vector_type = std::vector<P>;
50+
51+
vector_of_ptr() = default;
52+
vector_of_ptr(std::initializer_list<P> values) : values_(std::move(values)) {
53+
}
54+
55+
size_t size() const {
56+
return values_.size();
57+
}
58+
59+
void push_back(P value) {
60+
values_.push_back(std::move(value));
61+
}
62+
63+
typename vector_type::iterator begin() {
64+
return values_.begin();
65+
}
66+
typename vector_type::const_iterator begin() const {
67+
return values_.begin();
68+
}
69+
70+
typename vector_type::iterator end() {
71+
return values_.end();
72+
}
73+
typename vector_type::const_iterator end() const {
74+
return values_.end();
75+
}
76+
77+
friend bool operator==(const vector_of_ptr& lhs, const vector_of_ptr& rhs) {
78+
return absl::c_equal(
79+
lhs.values_, rhs.values_, [](const P& left, const P& right) {
80+
return left == nullptr ? right == nullptr
81+
: right != nullptr && *left == *right;
82+
});
83+
}
84+
85+
friend bool operator!=(const vector_of_ptr& lhs, const vector_of_ptr& rhs) {
86+
return !(lhs == rhs);
87+
}
88+
89+
private:
90+
vector_type values_;
91+
};
92+
93+
} // namespace util
94+
} // namespace firestore
95+
} // namespace firebase
96+
97+
#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_VECTOR_OF_PTR_H_

Firestore/core/test/firebase/firestore/util/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ cc_test(
163163
string_format_test.cc
164164
string_util_test.cc
165165
string_win_test.cc
166+
vector_of_ptr_test.cc
166167
DEPENDS
167168
absl_base
168169
absl_strings
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2019 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "Firestore/core/src/firebase/firestore/util/vector_of_ptr.h"
18+
19+
#include "gtest/gtest.h"
20+
21+
namespace firebase {
22+
namespace firestore {
23+
namespace util {
24+
25+
TEST(VectorOfPtrTest, DefaultConstructor) {
26+
vector_of_ptr<int> values;
27+
EXPECT_EQ(0, values.size());
28+
}
29+
30+
TEST(VectorOfPtrTest, PushBack) {
31+
vector_of_ptr<int> values;
32+
values.push_back(std::make_shared<int>(0));
33+
values.push_back(std::make_shared<int>(42));
34+
EXPECT_EQ(2, values.size());
35+
}
36+
37+
TEST(VectorOfPtrTest, BracedInitialization) {
38+
vector_of_ptr<int> brace_initialized_ints{std::make_shared<int>(0),
39+
std::make_shared<int>(1)};
40+
41+
EXPECT_EQ(2, brace_initialized_ints.size());
42+
43+
brace_initialized_ints = {};
44+
EXPECT_EQ(0, brace_initialized_ints.size());
45+
}
46+
47+
TEST(VectorOfPtrTest, EqualityIsValueEquality) {
48+
vector_of_ptr<int> lhs = {std::make_shared<int>(0), std::make_shared<int>(1)};
49+
vector_of_ptr<int> rhs = {std::make_shared<int>(0), std::make_shared<int>(1)};
50+
vector_of_ptr<int> other = {std::make_shared<int>(1),
51+
std::make_shared<int>(0)};
52+
vector_of_ptr<int> contains_nulls = {nullptr, nullptr};
53+
vector_of_ptr<int> empty;
54+
55+
EXPECT_EQ(lhs, lhs);
56+
EXPECT_EQ(lhs, rhs);
57+
EXPECT_NE(lhs, other);
58+
EXPECT_NE(lhs, contains_nulls);
59+
EXPECT_NE(lhs, empty);
60+
}
61+
62+
TEST(VectorOfPtrTest, IterationIsOnPointers) {
63+
std::shared_ptr<int> pointers[] = {std::make_shared<int>(-1),
64+
std::make_shared<int>(42)};
65+
vector_of_ptr<int> vector = {pointers[0], pointers[1]};
66+
67+
size_t pos = 0;
68+
for (const std::shared_ptr<int>& element : vector) {
69+
ASSERT_EQ(*pointers[pos], *element);
70+
++pos;
71+
}
72+
ASSERT_EQ(pos, sizeof(pointers) / sizeof(pointers[0]));
73+
}
74+
75+
} // namespace util
76+
} // namespace firestore
77+
} // namespace firebase

0 commit comments

Comments
 (0)