Index: base/containers/README.md |
diff --git a/base/containers/README.md b/base/containers/README.md |
index e64e8f3a637162d1b43b7d4df0f90e705289ecc9..fa8d3d82a52d503ff100a5bacb33438d633c2772 100644 |
--- a/base/containers/README.md |
+++ b/base/containers/README.md |
@@ -124,6 +124,77 @@ strategy and the memory access pattern. Assuming items are being linearly added, |
one would expect it to be 3/4 full, so per-item overhead will be 0.25 * |
sizeof(T). |
+ |
+flat\_set/flat\_map support a notion of transparent comparisons. Therefore you |
+can, for example, lookup base::StringPiece in a set of std::strings without |
+constructing a temporary std::string. This functionality is based on C++14 |
+extensions to std::set/std::map interface. |
+ |
+You can find more information about transparent comparisons here: |
+http://en.cppreference.com/w/cpp/utility/functional/less_void |
+ |
+Example, smart pointer set: |
+ |
+```cpp |
+// Define a custom comparator. |
+struct UniquePtrComparator { |
+ // Mark your comparison as transparent. |
+ using is_transparent = int; |
+ |
+ template <typename T> |
+ bool operator()(const std::unique_ptr<T>& lhs, |
+ const std::unique_ptr<T>& rhs) const { |
+ return lhs < rhs; |
+ } |
+ |
+ template <typename T> |
+ bool operator()(const T* lhs, const std::unique_ptr<T>& rhs) const { |
+ return lhs < rhs.get(); |
+ } |
+ |
+ template <typename T> |
+ bool operator()(const std::unique_ptr<T>& lhs, const T* rhs) const { |
+ return lhs.get() < rhs; |
+ } |
+}; |
+ |
+// Declare a typedef. |
+template <typename T> |
+using UniquePtrSet = base::flat_set<std::unique_ptr<T>, UniquePtrComparator>; |
+ |
+// ... |
+// Collect data. |
+std::vector<std::unique_ptr<int>> ptr_vec; |
+ptr_vec.reserve(5); |
+std::generate_n(std::back_inserter(ptr_vec), 5, []{ |
+ return base::MakeUnique<int>(0); |
+}); |
+ |
+// Construct a set. |
+UniquePtrSet<int> ptr_set(std::move(ptr_vec), base::KEEP_FIRST_OF_DUPES); |
+ |
+// Use raw pointers to lookup keys. |
+int* ptr = ptr_set.begin()->get(); |
+EXPECT_TRUE(ptr_set.find(ptr) == ptr_set.begin()); |
+``` |
+ |
+Example flat_map<std\::string, int>: |
+ |
+```cpp |
+base::flat_map<std::string, int> str_to_int({{"a", 1}, {"c", 2},{"b", 2}}, |
+ base::KEEP_FIRST_OF_DUPES); |
+ |
+// Does not construct temporary strings. |
+str_to_int.find("c")->second = 3; |
+str_to_int.erase("c"); |
+EXPECT_EQ(str_to_int.end(), str_to_int.find("c")->second); |
+ |
+// NOTE: This does construct a temporary string. This happens since if the |
+// item is not in the container, then it needs to be constructed, which is |
+// something that transparent comparators don't have to guarantee. |
+str_to_int["c"] = 3; |
+``` |
+ |
### base::small\_map |
A small inline buffer that is brute-force searched that overflows into a full |