1*635a8641SAndroid Build Coastguard Worker# base/containers library 2*635a8641SAndroid Build Coastguard Worker 3*635a8641SAndroid Build Coastguard Worker## What goes here 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard WorkerThis directory contains some STL-like containers. 6*635a8641SAndroid Build Coastguard Worker 7*635a8641SAndroid Build Coastguard WorkerThings should be moved here that are generally applicable across the code base. 8*635a8641SAndroid Build Coastguard WorkerDon't add things here just because you need them in one place and think others 9*635a8641SAndroid Build Coastguard Workermay someday want something similar. You can put specialized containers in 10*635a8641SAndroid Build Coastguard Workeryour component's directory and we can promote them here later if we feel there 11*635a8641SAndroid Build Coastguard Workeris broad applicability. 12*635a8641SAndroid Build Coastguard Worker 13*635a8641SAndroid Build Coastguard Worker### Design and naming 14*635a8641SAndroid Build Coastguard Worker 15*635a8641SAndroid Build Coastguard WorkerContainers should adhere as closely to STL as possible. Functions and behaviors 16*635a8641SAndroid Build Coastguard Workernot present in STL should only be added when they are related to the specific 17*635a8641SAndroid Build Coastguard Workerdata structure implemented by the container. 18*635a8641SAndroid Build Coastguard Worker 19*635a8641SAndroid Build Coastguard WorkerFor STL-like containers our policy is that they should use STL-like naming even 20*635a8641SAndroid Build Coastguard Workerwhen it may conflict with the style guide. So functions and class names should 21*635a8641SAndroid Build Coastguard Workerbe lower case with underscores. Non-STL-like classes and functions should use 22*635a8641SAndroid Build Coastguard WorkerGoogle naming. Be sure to use the base namespace. 23*635a8641SAndroid Build Coastguard Worker 24*635a8641SAndroid Build Coastguard Worker## Map and set selection 25*635a8641SAndroid Build Coastguard Worker 26*635a8641SAndroid Build Coastguard Worker### Usage advice 27*635a8641SAndroid Build Coastguard Worker 28*635a8641SAndroid Build Coastguard Worker * Generally avoid **std::unordered\_set** and **std::unordered\_map**. In the 29*635a8641SAndroid Build Coastguard Worker common case, query performance is unlikely to be sufficiently higher than 30*635a8641SAndroid Build Coastguard Worker std::map to make a difference, insert performance is slightly worse, and 31*635a8641SAndroid Build Coastguard Worker the memory overhead is high. This makes sense mostly for large tables where 32*635a8641SAndroid Build Coastguard Worker you expect a lot of lookups. 33*635a8641SAndroid Build Coastguard Worker 34*635a8641SAndroid Build Coastguard Worker * Most maps and sets in Chrome are small and contain objects that can be 35*635a8641SAndroid Build Coastguard Worker moved efficiently. In this case, consider **base::flat\_map** and 36*635a8641SAndroid Build Coastguard Worker **base::flat\_set**. You need to be aware of the maximum expected size of 37*635a8641SAndroid Build Coastguard Worker the container since individual inserts and deletes are O(n), giving O(n^2) 38*635a8641SAndroid Build Coastguard Worker construction time for the entire map. But because it avoids mallocs in most 39*635a8641SAndroid Build Coastguard Worker cases, inserts are better or comparable to other containers even for 40*635a8641SAndroid Build Coastguard Worker several dozen items, and efficiently-moved types are unlikely to have 41*635a8641SAndroid Build Coastguard Worker performance problems for most cases until you have hundreds of items. If 42*635a8641SAndroid Build Coastguard Worker your container can be constructed in one shot, the constructor from vector 43*635a8641SAndroid Build Coastguard Worker gives O(n log n) construction times and it should be strictly better than 44*635a8641SAndroid Build Coastguard Worker a std::map. 45*635a8641SAndroid Build Coastguard Worker 46*635a8641SAndroid Build Coastguard Worker * **base::small\_map** has better runtime memory usage without the poor 47*635a8641SAndroid Build Coastguard Worker mutation performance of large containers that base::flat\_map has. But this 48*635a8641SAndroid Build Coastguard Worker advantage is partially offset by additional code size. Prefer in cases 49*635a8641SAndroid Build Coastguard Worker where you make many objects so that the code/heap tradeoff is good. 50*635a8641SAndroid Build Coastguard Worker 51*635a8641SAndroid Build Coastguard Worker * Use **std::map** and **std::set** if you can't decide. Even if they're not 52*635a8641SAndroid Build Coastguard Worker great, they're unlikely to be bad or surprising. 53*635a8641SAndroid Build Coastguard Worker 54*635a8641SAndroid Build Coastguard Worker### Map and set details 55*635a8641SAndroid Build Coastguard Worker 56*635a8641SAndroid Build Coastguard WorkerSizes are on 64-bit platforms. Stable iterators aren't invalidated when the 57*635a8641SAndroid Build Coastguard Workercontainer is mutated. 58*635a8641SAndroid Build Coastguard Worker 59*635a8641SAndroid Build Coastguard Worker| Container | Empty size | Per-item overhead | Stable iterators? | 60*635a8641SAndroid Build Coastguard Worker|:---------------------------------------- |:--------------------- |:----------------- |:----------------- | 61*635a8641SAndroid Build Coastguard Worker| std::map, std::set | 16 bytes | 32 bytes | Yes | 62*635a8641SAndroid Build Coastguard Worker| std::unordered\_map, std::unordered\_set | 128 bytes | 16-24 bytes | No | 63*635a8641SAndroid Build Coastguard Worker| base::flat\_map and base::flat\_set | 24 bytes | 0 (see notes) | No | 64*635a8641SAndroid Build Coastguard Worker| base::small\_map | 24 bytes (see notes) | 32 bytes | No | 65*635a8641SAndroid Build Coastguard Worker 66*635a8641SAndroid Build Coastguard Worker**Takeaways:** std::unordered\_map and std::unordered\_map have high 67*635a8641SAndroid Build Coastguard Workeroverhead for small container sizes, prefer these only for larger workloads. 68*635a8641SAndroid Build Coastguard Worker 69*635a8641SAndroid Build Coastguard WorkerCode size comparisons for a block of code (see appendix) on Windows using 70*635a8641SAndroid Build Coastguard Workerstrings as keys. 71*635a8641SAndroid Build Coastguard Worker 72*635a8641SAndroid Build Coastguard Worker| Container | Code size | 73*635a8641SAndroid Build Coastguard Worker|:------------------- |:---------- | 74*635a8641SAndroid Build Coastguard Worker| std::unordered\_map | 1646 bytes | 75*635a8641SAndroid Build Coastguard Worker| std::map | 1759 bytes | 76*635a8641SAndroid Build Coastguard Worker| base::flat\_map | 1872 bytes | 77*635a8641SAndroid Build Coastguard Worker| base::small\_map | 2410 bytes | 78*635a8641SAndroid Build Coastguard Worker 79*635a8641SAndroid Build Coastguard Worker**Takeaways:** base::small\_map generates more code because of the inlining of 80*635a8641SAndroid Build Coastguard Workerboth brute-force and red-black tree searching. This makes it less attractive 81*635a8641SAndroid Build Coastguard Workerfor random one-off uses. But if your code is called frequently, the runtime 82*635a8641SAndroid Build Coastguard Workermemory benefits will be more important. The code sizes of the other maps are 83*635a8641SAndroid Build Coastguard Workerclose enough it's not worth worrying about. 84*635a8641SAndroid Build Coastguard Worker 85*635a8641SAndroid Build Coastguard Worker### std::map and std::set 86*635a8641SAndroid Build Coastguard Worker 87*635a8641SAndroid Build Coastguard WorkerA red-black tree. Each inserted item requires the memory allocation of a node 88*635a8641SAndroid Build Coastguard Workeron the heap. Each node contains a left pointer, a right pointer, a parent 89*635a8641SAndroid Build Coastguard Workerpointer, and a "color" for the red-black tree (32-bytes per item on 64-bits). 90*635a8641SAndroid Build Coastguard Worker 91*635a8641SAndroid Build Coastguard Worker### std::unordered\_map and std::unordered\_set 92*635a8641SAndroid Build Coastguard Worker 93*635a8641SAndroid Build Coastguard WorkerA hash table. Implemented on Windows as a std::vector + std::list and in libc++ 94*635a8641SAndroid Build Coastguard Workeras the equivalent of a std::vector + a std::forward\_list. Both implementations 95*635a8641SAndroid Build Coastguard Workerallocate an 8-entry hash table (containing iterators into the list) on 96*635a8641SAndroid Build Coastguard Workerinitialization, and grow to 64 entries once 8 items are inserted. Above 64 97*635a8641SAndroid Build Coastguard Workeritems, the size doubles every time the load factor exceeds 1. 98*635a8641SAndroid Build Coastguard Worker 99*635a8641SAndroid Build Coastguard WorkerThe empty size is sizeof(std::unordered\_map) = 64 + 100*635a8641SAndroid Build Coastguard Workerthe initial hash table size which is 8 pointers. The per-item overhead in the 101*635a8641SAndroid Build Coastguard Workertable above counts the list node (2 pointers on Windows, 1 pointer in libc++), 102*635a8641SAndroid Build Coastguard Workerplus amortizes the hash table assuming a 0.5 load factor on average. 103*635a8641SAndroid Build Coastguard Worker 104*635a8641SAndroid Build Coastguard WorkerIn a microbenchmark on Windows, inserts of 1M integers into a 105*635a8641SAndroid Build Coastguard Workerstd::unordered\_set took 1.07x the time of std::set, and queries took 0.67x the 106*635a8641SAndroid Build Coastguard Workertime of std::set. For a typical 4-entry set (the statistical mode of map sizes 107*635a8641SAndroid Build Coastguard Workerin the browser), query performance is identical to std::set and base::flat\_set. 108*635a8641SAndroid Build Coastguard WorkerOn ARM, unordered\_set performance can be worse because integer division to 109*635a8641SAndroid Build Coastguard Workercompute the bucket is slow, and a few "less than" operations can be faster than 110*635a8641SAndroid Build Coastguard Workercomputing a hash depending on the key type. The takeaway is that you should not 111*635a8641SAndroid Build Coastguard Workerdefault to using unordered maps because "they're faster." 112*635a8641SAndroid Build Coastguard Worker 113*635a8641SAndroid Build Coastguard Worker### base::flat\_map and base::flat\_set 114*635a8641SAndroid Build Coastguard Worker 115*635a8641SAndroid Build Coastguard WorkerA sorted std::vector. Seached via binary search, inserts in the middle require 116*635a8641SAndroid Build Coastguard Workermoving elements to make room. Good cache locality. For large objects and large 117*635a8641SAndroid Build Coastguard Workerset sizes, std::vector's doubling-when-full strategy can waste memory. 118*635a8641SAndroid Build Coastguard Worker 119*635a8641SAndroid Build Coastguard WorkerSupports efficient construction from a vector of items which avoids the O(n^2) 120*635a8641SAndroid Build Coastguard Workerinsertion time of each element separately. 121*635a8641SAndroid Build Coastguard Worker 122*635a8641SAndroid Build Coastguard WorkerThe per-item overhead will depend on the underlying std::vector's reallocation 123*635a8641SAndroid Build Coastguard Workerstrategy and the memory access pattern. Assuming items are being linearly added, 124*635a8641SAndroid Build Coastguard Workerone would expect it to be 3/4 full, so per-item overhead will be 0.25 * 125*635a8641SAndroid Build Coastguard Workersizeof(T). 126*635a8641SAndroid Build Coastguard Worker 127*635a8641SAndroid Build Coastguard Worker 128*635a8641SAndroid Build Coastguard Workerflat\_set/flat\_map support a notion of transparent comparisons. Therefore you 129*635a8641SAndroid Build Coastguard Workercan, for example, lookup base::StringPiece in a set of std::strings without 130*635a8641SAndroid Build Coastguard Workerconstructing a temporary std::string. This functionality is based on C++14 131*635a8641SAndroid Build Coastguard Workerextensions to std::set/std::map interface. 132*635a8641SAndroid Build Coastguard Worker 133*635a8641SAndroid Build Coastguard WorkerYou can find more information about transparent comparisons here: 134*635a8641SAndroid Build Coastguard Workerhttp://en.cppreference.com/w/cpp/utility/functional/less_void 135*635a8641SAndroid Build Coastguard Worker 136*635a8641SAndroid Build Coastguard WorkerExample, smart pointer set: 137*635a8641SAndroid Build Coastguard Worker 138*635a8641SAndroid Build Coastguard Worker```cpp 139*635a8641SAndroid Build Coastguard Worker// Declare a type alias using base::UniquePtrComparator. 140*635a8641SAndroid Build Coastguard Workertemplate <typename T> 141*635a8641SAndroid Build Coastguard Workerusing UniquePtrSet = base::flat_set<std::unique_ptr<T>, 142*635a8641SAndroid Build Coastguard Worker base::UniquePtrComparator>; 143*635a8641SAndroid Build Coastguard Worker 144*635a8641SAndroid Build Coastguard Worker// ... 145*635a8641SAndroid Build Coastguard Worker// Collect data. 146*635a8641SAndroid Build Coastguard Workerstd::vector<std::unique_ptr<int>> ptr_vec; 147*635a8641SAndroid Build Coastguard Workerptr_vec.reserve(5); 148*635a8641SAndroid Build Coastguard Workerstd::generate_n(std::back_inserter(ptr_vec), 5, []{ 149*635a8641SAndroid Build Coastguard Worker return std::make_unique<int>(0); 150*635a8641SAndroid Build Coastguard Worker}); 151*635a8641SAndroid Build Coastguard Worker 152*635a8641SAndroid Build Coastguard Worker// Construct a set. 153*635a8641SAndroid Build Coastguard WorkerUniquePtrSet<int> ptr_set(std::move(ptr_vec), base::KEEP_FIRST_OF_DUPES); 154*635a8641SAndroid Build Coastguard Worker 155*635a8641SAndroid Build Coastguard Worker// Use raw pointers to lookup keys. 156*635a8641SAndroid Build Coastguard Workerint* ptr = ptr_set.begin()->get(); 157*635a8641SAndroid Build Coastguard WorkerEXPECT_TRUE(ptr_set.find(ptr) == ptr_set.begin()); 158*635a8641SAndroid Build Coastguard Worker``` 159*635a8641SAndroid Build Coastguard Worker 160*635a8641SAndroid Build Coastguard WorkerExample flat_map<std\::string, int>: 161*635a8641SAndroid Build Coastguard Worker 162*635a8641SAndroid Build Coastguard Worker```cpp 163*635a8641SAndroid Build Coastguard Workerbase::flat_map<std::string, int> str_to_int({{"a", 1}, {"c", 2},{"b", 2}}, 164*635a8641SAndroid Build Coastguard Worker base::KEEP_FIRST_OF_DUPES); 165*635a8641SAndroid Build Coastguard Worker 166*635a8641SAndroid Build Coastguard Worker// Does not construct temporary strings. 167*635a8641SAndroid Build Coastguard Workerstr_to_int.find("c")->second = 3; 168*635a8641SAndroid Build Coastguard Workerstr_to_int.erase("c"); 169*635a8641SAndroid Build Coastguard WorkerEXPECT_EQ(str_to_int.end(), str_to_int.find("c")->second); 170*635a8641SAndroid Build Coastguard Worker 171*635a8641SAndroid Build Coastguard Worker// NOTE: This does construct a temporary string. This happens since if the 172*635a8641SAndroid Build Coastguard Worker// item is not in the container, then it needs to be constructed, which is 173*635a8641SAndroid Build Coastguard Worker// something that transparent comparators don't have to guarantee. 174*635a8641SAndroid Build Coastguard Workerstr_to_int["c"] = 3; 175*635a8641SAndroid Build Coastguard Worker``` 176*635a8641SAndroid Build Coastguard Worker 177*635a8641SAndroid Build Coastguard Worker### base::small\_map 178*635a8641SAndroid Build Coastguard Worker 179*635a8641SAndroid Build Coastguard WorkerA small inline buffer that is brute-force searched that overflows into a full 180*635a8641SAndroid Build Coastguard Workerstd::map or std::unordered\_map. This gives the memory benefit of 181*635a8641SAndroid Build Coastguard Workerbase::flat\_map for small data sizes without the degenerate insertion 182*635a8641SAndroid Build Coastguard Workerperformance for large container sizes. 183*635a8641SAndroid Build Coastguard Worker 184*635a8641SAndroid Build Coastguard WorkerSince instantiations require both code for a std::map and a brute-force search 185*635a8641SAndroid Build Coastguard Workerof the inline container, plus a fancy iterator to cover both cases, code size 186*635a8641SAndroid Build Coastguard Workeris larger. 187*635a8641SAndroid Build Coastguard Worker 188*635a8641SAndroid Build Coastguard WorkerThe initial size in the above table is assuming a very small inline table. The 189*635a8641SAndroid Build Coastguard Workeractual size will be sizeof(int) + min(sizeof(std::map), sizeof(T) * 190*635a8641SAndroid Build Coastguard Workerinline\_size). 191*635a8641SAndroid Build Coastguard Worker 192*635a8641SAndroid Build Coastguard Worker# Deque 193*635a8641SAndroid Build Coastguard Worker 194*635a8641SAndroid Build Coastguard Worker### Usage advice 195*635a8641SAndroid Build Coastguard Worker 196*635a8641SAndroid Build Coastguard WorkerChromium code should always use `base::circular_deque` or `base::queue` in 197*635a8641SAndroid Build Coastguard Workerpreference to `std::deque` or `std::queue` due to memory usage and platform 198*635a8641SAndroid Build Coastguard Workervariation. 199*635a8641SAndroid Build Coastguard Worker 200*635a8641SAndroid Build Coastguard WorkerThe `base::circular_deque` implementation (and the `base::queue` which uses it) 201*635a8641SAndroid Build Coastguard Workerprovide performance consistent across platforms that better matches most 202*635a8641SAndroid Build Coastguard Workerprogrammer's expectations on performance (it doesn't waste as much space as 203*635a8641SAndroid Build Coastguard Workerlibc++ and doesn't do as many heap allocations as MSVC). It also generates less 204*635a8641SAndroid Build Coastguard Workercode tham `std::queue`: using it across the code base saves several hundred 205*635a8641SAndroid Build Coastguard Workerkilobytes. 206*635a8641SAndroid Build Coastguard Worker 207*635a8641SAndroid Build Coastguard WorkerSince `base::deque` does not have stable iterators and it will move the objects 208*635a8641SAndroid Build Coastguard Workerit contains, it may not be appropriate for all uses. If you need these, 209*635a8641SAndroid Build Coastguard Workerconsider using a `std::list` which will provide constant time insert and erase. 210*635a8641SAndroid Build Coastguard Worker 211*635a8641SAndroid Build Coastguard Worker### std::deque and std::queue 212*635a8641SAndroid Build Coastguard Worker 213*635a8641SAndroid Build Coastguard WorkerThe implementation of `std::deque` varies considerably which makes it hard to 214*635a8641SAndroid Build Coastguard Workerreason about. All implementations use a sequence of data blocks referenced by 215*635a8641SAndroid Build Coastguard Workeran array of pointers. The standard guarantees random access, amortized 216*635a8641SAndroid Build Coastguard Workerconstant operations at the ends, and linear mutations in the middle. 217*635a8641SAndroid Build Coastguard Worker 218*635a8641SAndroid Build Coastguard WorkerIn Microsoft's implementation, each block is the smaller of 16 bytes or the 219*635a8641SAndroid Build Coastguard Workersize of the contained element. This means in practice that every expansion of 220*635a8641SAndroid Build Coastguard Workerthe deque of non-trivial classes requires a heap allocation. libc++ (on Android 221*635a8641SAndroid Build Coastguard Workerand Mac) uses 4K blocks which elimiates the problem of many heap allocations, 222*635a8641SAndroid Build Coastguard Workerbut generally wastes a large amount of space (an Android analysis revealed more 223*635a8641SAndroid Build Coastguard Workerthan 2.5MB wasted space from deque alone, resulting in some optimizations). 224*635a8641SAndroid Build Coastguard Workerlibstdc++ uses an intermediate-size 512 byte buffer. 225*635a8641SAndroid Build Coastguard Worker 226*635a8641SAndroid Build Coastguard WorkerMicrosoft's implementation never shrinks the deque capacity, so the capacity 227*635a8641SAndroid Build Coastguard Workerwill always be the maximum number of elements ever contained. libstdc++ 228*635a8641SAndroid Build Coastguard Workerdeallocates blocks as they are freed. libc++ keeps up to two empty blocks. 229*635a8641SAndroid Build Coastguard Worker 230*635a8641SAndroid Build Coastguard Worker### base::circular_deque and base::queue 231*635a8641SAndroid Build Coastguard Worker 232*635a8641SAndroid Build Coastguard WorkerA deque implemented as a circular buffer in an array. The underlying array will 233*635a8641SAndroid Build Coastguard Workergrow like a `std::vector` while the beginning and end of the deque will move 234*635a8641SAndroid Build Coastguard Workeraround. The items will wrap around the underlying buffer so the storage will 235*635a8641SAndroid Build Coastguard Workernot be contiguous, but fast random access iterators are still possible. 236*635a8641SAndroid Build Coastguard Worker 237*635a8641SAndroid Build Coastguard WorkerWhen the underlying buffer is filled, it will be reallocated and the constents 238*635a8641SAndroid Build Coastguard Workermoved (like a `std::vector`). The underlying buffer will be shrunk if there is 239*635a8641SAndroid Build Coastguard Workertoo much wasted space (_unlike_ a `std::vector`). As a result, iterators are 240*635a8641SAndroid Build Coastguard Workernot stable across mutations. 241*635a8641SAndroid Build Coastguard Worker 242*635a8641SAndroid Build Coastguard Worker# Stack 243*635a8641SAndroid Build Coastguard Worker 244*635a8641SAndroid Build Coastguard Worker`std::stack` is like `std::queue` in that it is a wrapper around an underlying 245*635a8641SAndroid Build Coastguard Workercontainer. The default container is `std::deque` so everything from the deque 246*635a8641SAndroid Build Coastguard Workersection applies. 247*635a8641SAndroid Build Coastguard Worker 248*635a8641SAndroid Build Coastguard WorkerChromium provides `base/containers/stack.h` which defines `base::stack` that 249*635a8641SAndroid Build Coastguard Workershould be used in preference to std::stack. This changes the underlying 250*635a8641SAndroid Build Coastguard Workercontainer to `base::circular_deque`. The result will be very similar to 251*635a8641SAndroid Build Coastguard Workermanually specifying a `std::vector` for the underlying implementation except 252*635a8641SAndroid Build Coastguard Workerthat the storage will shrink when it gets too empty (vector will never 253*635a8641SAndroid Build Coastguard Workerreallocate to a smaller size). 254*635a8641SAndroid Build Coastguard Worker 255*635a8641SAndroid Build Coastguard WorkerWatch out: with some stack usage patterns it's easy to depend on unstable 256*635a8641SAndroid Build Coastguard Workerbehavior: 257*635a8641SAndroid Build Coastguard Worker 258*635a8641SAndroid Build Coastguard Worker```cpp 259*635a8641SAndroid Build Coastguard Workerbase::stack<Foo> stack; 260*635a8641SAndroid Build Coastguard Workerfor (...) { 261*635a8641SAndroid Build Coastguard Worker Foo& current = stack.top(); 262*635a8641SAndroid Build Coastguard Worker DoStuff(); // May call stack.push(), say if writing a parser. 263*635a8641SAndroid Build Coastguard Worker current.done = true; // Current may reference deleted item! 264*635a8641SAndroid Build Coastguard Worker} 265*635a8641SAndroid Build Coastguard Worker``` 266*635a8641SAndroid Build Coastguard Worker 267*635a8641SAndroid Build Coastguard Worker## Appendix 268*635a8641SAndroid Build Coastguard Worker 269*635a8641SAndroid Build Coastguard Worker### Code for map code size comparison 270*635a8641SAndroid Build Coastguard Worker 271*635a8641SAndroid Build Coastguard WorkerThis just calls insert and query a number of times, with printfs that prevent 272*635a8641SAndroid Build Coastguard Workerthings from being dead-code eliminated. 273*635a8641SAndroid Build Coastguard Worker 274*635a8641SAndroid Build Coastguard Worker```cpp 275*635a8641SAndroid Build Coastguard WorkerTEST(Foo, Bar) { 276*635a8641SAndroid Build Coastguard Worker base::small_map<std::map<std::string, Flubber>> foo; 277*635a8641SAndroid Build Coastguard Worker foo.insert(std::make_pair("foo", Flubber(8, "bar"))); 278*635a8641SAndroid Build Coastguard Worker foo.insert(std::make_pair("bar", Flubber(8, "bar"))); 279*635a8641SAndroid Build Coastguard Worker foo.insert(std::make_pair("foo1", Flubber(8, "bar"))); 280*635a8641SAndroid Build Coastguard Worker foo.insert(std::make_pair("bar1", Flubber(8, "bar"))); 281*635a8641SAndroid Build Coastguard Worker foo.insert(std::make_pair("foo", Flubber(8, "bar"))); 282*635a8641SAndroid Build Coastguard Worker foo.insert(std::make_pair("bar", Flubber(8, "bar"))); 283*635a8641SAndroid Build Coastguard Worker auto found = foo.find("asdf"); 284*635a8641SAndroid Build Coastguard Worker printf("Found is %d\n", (int)(found == foo.end())); 285*635a8641SAndroid Build Coastguard Worker found = foo.find("foo"); 286*635a8641SAndroid Build Coastguard Worker printf("Found is %d\n", (int)(found == foo.end())); 287*635a8641SAndroid Build Coastguard Worker found = foo.find("bar"); 288*635a8641SAndroid Build Coastguard Worker printf("Found is %d\n", (int)(found == foo.end())); 289*635a8641SAndroid Build Coastguard Worker found = foo.find("asdfhf"); 290*635a8641SAndroid Build Coastguard Worker printf("Found is %d\n", (int)(found == foo.end())); 291*635a8641SAndroid Build Coastguard Worker found = foo.find("bar1"); 292*635a8641SAndroid Build Coastguard Worker printf("Found is %d\n", (int)(found == foo.end())); 293*635a8641SAndroid Build Coastguard Worker} 294*635a8641SAndroid Build Coastguard Worker``` 295*635a8641SAndroid Build Coastguard Worker 296