FTL: Refine container semantics

Allow constructing StaticVector and SmallVector by moving smaller
convertible vectors, which so far incurred a copy. Allow the same
copy/move conversion for SmallMap.

Consistently with StaticVector, do not require assignable elements for
the SmallVector to be assignable, which notably enables SmallMap to be
assignable despite its const keys.

Allow comparison of convertible containers.

Bug: 185536303
Test: ftl_test
Change-Id: I35923e794ef26178dc3072f514dea7ad5600bc15
diff --git a/libs/ftl/small_map_test.cpp b/libs/ftl/small_map_test.cpp
index ee650e5..1740a2b 100644
--- a/libs/ftl/small_map_test.cpp
+++ b/libs/ftl/small_map_test.cpp
@@ -96,6 +96,33 @@
   }
 }
 
+TEST(SmallMap, Assign) {
+  {
+    // Same types; smaller capacity.
+    SmallMap map1 = ftl::init::map<char, std::string>('k', "kilo")('M', "mega")('G', "giga");
+    const SmallMap map2 = ftl::init::map('T', "tera"s)('P', "peta"s);
+
+    map1 = map2;
+    EXPECT_EQ(map1, map2);
+  }
+  {
+    // Convertible types; same capacity.
+    SmallMap map1 = ftl::init::map<char, std::string>('M', "mega")('G', "giga");
+    const SmallMap map2 = ftl::init::map('T', "tera")('P', "peta");
+
+    map1 = map2;
+    EXPECT_EQ(map1, map2);
+  }
+  {
+    // Convertible types; zero capacity.
+    SmallMap<char, std::string, 0> map1 = ftl::init::map('M', "mega")('G', "giga");
+    const SmallMap<char, std::string, 0> map2 = ftl::init::map('T', "tera")('P', "peta");
+
+    map1 = map2;
+    EXPECT_EQ(map1, map2);
+  }
+}
+
 TEST(SmallMap, UniqueKeys) {
   {
     // Duplicate mappings are discarded.