#include "Tutorial.h" void Map() { /// .`VectorMap`, `ArrayMap` /// `VectorMap` is nothing else than a simple composition of `Index` of keys and `Vector` /// of values. You can use `Add` methods to put elements into the `VectorMap`: struct Person : Moveable { String name; String surname; String ToString() const { return String() << name << ' ' << surname; } Person(String name, String surname) : name(name), surname(surname) {} Person() {} }; VectorMap m; m.Add("1", Person("John", "Smith")); m.Add("2", Person("Carl", "Engles")); Person& p = m.Add("3"); p.name = "Paul"; p.surname = "Carpenter"; DUMP(m); /// `VectorMap` provides read-only access to its `Index` of keys and read-write access to its /// `Vector` of values: DUMP(m.GetKeys()); DUMP(m.GetValues()); /// m.GetValues()[2].name = "Peter"; DUMP(m); /// You can use indices to iterate `VectorMap` contents: for(int i = 0; i < m.GetCount(); i++) LOG(m.GetKey(i) << ": " << m[i]); /// Standard `begin` / `end` pair for `VectorMap` is the range of just values (internal Vector) /// - it corresponds with `operator[]` returning values: for(const auto& p : m) DUMP(p); /// To iterate through keys, you can use `begin`/`end` of internal `Index`: for(const auto& k : m.GetKeys()) DUMP(p); /// Alternatively, it is possible to create 'projection range' of VectorMap that provides /// convenient key/value iteration, using `operator~` (note that is also removes 'unliked' /// items, see later): for(const auto& e : ~m) { DUMP(e.key); DUMP(e.value); } /// Note that the 'projection range' obtained by `operator~` is temporary value, which /// means that if mutating operation is required for values, r-value reference has to be /// used instead of plain reference: for(const auto& e : ~m) if(e.key == "2") e.value.surname = "May"; DUMP(m); /// You can use Find method to retrieve position of element with required key: DUMP(m.Find("2")); /// or Get method to retrieve corresponding value: DUMP(m.Get("2")); /// Passing key not present in `VectorMap` as `Get` parameter is undefined behavior (ASSERT /// fails in debug mode), but there exists two parameter version of `Get` that returns second /// parameter if the key is not found in VectorMap: DUMP(m.Get("33", Person("unknown", "person"))); /// As with `Index`, you can use `Unlink` to make elements invisible for Find operations: m.Unlink(1); DUMP(m.Find("2")); /// `SetKey` changes the key of the element: m.SetKey(1, "33"); DUMP(m.Get("33", Person("unknown", "person"))); /// If there are more elements with the same key in `VectorMap`, you can iterate them using /// `FindNext` method: m.Add("33", Person("Peter", "Pan")); int q = m.Find("33"); while(q >= 0) { DUMP(m[q]); q = m.FindNext(q); } /// Unlinked positions can be 'reused' using Put method: m.UnlinkKey("33"); m.Put("22", Person("Ali", "Baba")); m.Put("44", Person("Ivan", "Wilks")); DUMP(m); /// `PickValues` / `PickIndex` / `PickKeys` / pick internal `Vector` / `Index` / `Vector` /// of `Index`: Vector ps = m.PickValues(); Vector ks = m.PickKeys(); DUMP(ps); DUMP(ks); DUMP(m); /// `VectorMap` pick constructor to create map by picking: ks[0] = "Changed key"; m = VectorMap(pick(ks), pick(ps)); DUMP(m); /// `ArrayMap` is composition of Index and Array, for cases where Array is better fit for /// value type (e.g. they are polymorphic): ArrayMap am; am.Create("key", "new", "person"); DUMP(am); /// }