changeset 27431:170d05ce158f

Map.m: Allow numeric keys of one type to be used with a Map of a differing numeric keytype (bug #56594). * Map.m: Convert keys of mismatching types in indexing, assignment and concatenation. Add BIST tests.
author Guillaume Flandin
date Fri, 20 Sep 2019 11:45:27 +0100
parents ba3fc70ba996
children 1e79d913baaa
files scripts/+containers/Map.m
diffstat 1 files changed, 49 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/+containers/Map.m	Fri Sep 20 13:19:11 2019 -0700
+++ b/scripts/+containers/Map.m	Fri Sep 20 11:45:27 2019 +0100
@@ -448,9 +448,17 @@
       ## When concatenating maps, the data type of all values must be
       ## consistent with the ValueType of the leftmost map.
       keySet = cell (1, 0);
+      keyTypes = cell (1, 0);
       for i = 1:numel (varargin)
         keySet = [keySet, keys(varargin{i})];
+        keyTypes = [keyTypes, varargin{i}.KeyType];
       endfor
+      if (numel (unique (keyTypes)) != 1)
+        if (any (strcmp (keyTypes, "char")))
+          error ("containers.Map: cannot concatenate maps with numeric and string keys");
+        endif
+        keySet = cellfun (@(x) feval (keyTypes{1}, x), keySet, "UniformOutput", false);
+      endif
       valueSet = cell (1, 0);
       for i = 1:numel (varargin)
         valueSet = [valueSet, values(varargin{i})];
@@ -485,6 +493,8 @@
         else
           keys = cell2mat (keys);
         endif
+      elseif (! isa (keys, this.KeyType))
+        keys = feval (this.KeyType, keys);
       endif
       keys = num2hex (keys);  # Force to char matrix with single logical column
       if (cell_input)
@@ -725,6 +735,34 @@
 %!   assert (m.keys (), {key});
 %! endfor
 
+## Test using mixed numerical keys (subsref)
+%!test <*56594>
+%! key = [1, 2, 3];
+%! val = {"One", "Two", "Three"};
+%! types = {"double", "single", "int32", "uint32", "int64", "uint64", ...
+%!          "int8", "uint8", "int16", "uint16"};
+%! for type1 = types
+%!   type = type1{1};
+%!   k = feval (type, key);
+%!   m = containers.Map (k, val);
+%!   for type2 = [types, "logical"]
+%!     type = type2{1};
+%!     k = feval (type, key(1));
+%!     assert (m(k), "One");
+%!   endfor
+%! endfor
+
+## Test using mixed numerical keys (subsasgn)
+%!test <*56594>
+%! key = [1, 2, 3];
+%! val = {"One", "Two", "Three"};
+%! m = containers.Map(key, val);
+%! m (uint32 (1)) = "Four";
+%! assert (m.Count, uint64(3));
+%! assert (keys (m), {1, 2, 3});
+%! assert (m(1), "Four");
+%! assert (m(uint16 (1)), "Four");
+
 ## Test sort order of keys and values
 %!test
 %! key = {"d","a","b"};
@@ -750,6 +788,13 @@
 %! k = keys (m3);
 %! assert (numel (k), 2);
 %! assert (k, {"a", "b"});
+%! m1 = containers.Map (1, 1);
+%! m2 = containers.Map (single ([2, 3]), {2, 3});
+%! m3 = [m1, m2];
+%! assert (m3.KeyType, "double");
+%! assert (keys (m3), {1, 2, 3});
+%! m3 = [m2, m1];
+%! assert (m3.KeyType, "single");
 
 ## Test input validation
 %!error containers.Map (1,2,3)
@@ -805,3 +850,7 @@
 %! m1 = containers.Map ("KeyType", "cell", "ValueType", "any");
 %!error <unsupported ValueType>
 %! m1 = containers.Map ("KeyType", "char", "ValueType", "cell");
+%!error
+%! m1 = containers.Map (1, 1);
+%! m2 = containers.Map ("a", 2);
+%! m3 = [m1, m2];