MatrixBerryCore
MapExtended.m
Go to the documentation of this file.
1 classdef MapExtended<containers.Map
2  methods
3  function [isPos,reportStr]=isEqualProp(self,otherObj)
4  isPos=isequal(self.KeyType,otherObj.KeyType);
5  if ~isPos
6  reportStr='incompatible key types';
7  else
8  isPos=self.Count==0||otherObj.Count==0||...
9  isequal(self.ValueType,otherObj.ValueType);
10  if ~isPos
11  reportStr='incompatible value types';
12  else
13  reportStr='';
14  end
15  end
16  end
17  %
18  function checkIfEqualProp(self,otherObj)
19  import mxberry.core.throwerror;
20  [isPos,reportStr]=isEqualProp(self,otherObj);
21  if ~isPos
22  throwerror('wrongInput',reportStr);
23  end
24  end
25  function self=MapExtended(varargin)
26  self=self@containers.Map(varargin{:});
27  end
28  %
29  function obj=getUnionWith(self,otherObj)
31  import mxberry.core.throwerror;
32  if self.Count>0||otherObj.Count>0
33  self.checkIfEqualProp(otherObj);
34  keyList=[self.keys,otherObj.keys];
35  if ~mxberry.core.isunique(keyList)
36  throwerror('wrongInput:dupicateKeys',...
37  'key lists of both map objects cannot intersect');
38  end
39  %
40  obj=MapExtended(keyList,...
41  [self.values,otherObj.values]);
42  else
43  obj=self.getCopy();
44  end
45  end
46  %
47  function SRes=toStruct(self)
48  import mxberry.core.cont.MapExtended;
49  keyList=self.keys;
50  fieldNameList=cellfun(@MapExtended.key2FieldName,keyList,...
51  'UniformOutput',false);
52  %
53  valueList=self.values;
54  isMapVec=cellfun('isclass',valueList,mfilename('class'));
55  valueList(isMapVec)=cellfun(@(x)x.toStruct(),...
56  valueList(isMapVec),'UniformOutput',false);
57  keyValueMat=[fieldNameList;valueList];
58  %
59  SRes=struct(keyValueMat{:});
60  end
61  %
62  function obj=getCopy(self)
63  import mxberry.core.cont.MapExtended;
64  if self.Count>0
65  isUniform=~strcmp(self.ValueType,'any');
66  obj=MapExtended(self.keys,self.values,'UniformValues',...
67  isUniform);
68  else
69  obj=MapExtended('KeyType',self.KeyType,...
70  'ValueType',self.ValueType);
71  end
72  end
73  function [isPos,reportStr]=isEqual(self,otherObj)
74  import mxberry.core.struct.structcompare;
75  isPos=isequal(self,otherObj);
76  if isPos
77  reportStr='';
78  else
79  [isPos,reportStr]=self.isEqualProp(otherObj);
80  if isPos
81  [isPos,reportStr]=structcompare(self.toStruct(),...
82  otherObj.toStruct());
83  end
84  end
85  end
86  end
87  methods (Static)
88  function fieldName=key2FieldName(keyName)
89  import mxberry.core.cont.MapExtended;
90  N_MAX_NO_HASHED_CHARS=30;
91  %
92  nChars=length(keyName);
93  nNoHachedChars=min(N_MAX_NO_HASHED_CHARS,nChars);
94  fieldReadableNamePart=MapExtended.genVarName(...
95  keyName(1:nNoHachedChars));
96  nReadableChars=length(fieldReadableNamePart);
97  nNotHashed=min(nNoHachedChars,nReadableChars);
98  toHashStr=[fieldReadableNamePart(...
99  nNotHashed+1:end),...
100  keyName(nNoHachedChars+1:end)];
101  %
102  if ~isempty(toHashStr)
103  if length(toHashStr)>32||~isvarname(toHashStr)
104  hashedStr=mxberry.core.hash(toHashStr,'md2');
105  else
106  hashedStr=toHashStr;
107  end
108  fieldName=[fieldReadableNamePart(1:nNotHashed),...
109  '_',hashedStr];
110  else
111  fieldName=fieldReadableNamePart(1:nNotHashed);
112  end
113  end
114  end
115  %
116  methods (Static, Access=private)
117  function varname=genVarName(varname)
118  if ~isvarname(varname) % Short-circuit if varname already legal
119  % Insert x if the first column is non-letter.
120  varname = regexprep(varname,'^\s*+([^A-Za-z])','x$1', 'once');
121 
122  % Replace whitespace with camel casing.
123  [~, afterSpace] = regexp(varname,'\S\s+\S');
124  for j=afterSpace
125  varname(j) = upper(varname(j));
126  end
127  varname = regexprep(varname,'\s+','');
128  if (isempty(varname))
129  varname = 'x';
130  end
131  % Replace non-word character with its HEXADECIMAL equivalent
132  illegalChars = unique(varname(regexp(varname,'[^A-Za-z_0-9]')));
133  for illegalChar=illegalChars
134  if illegalChar <= intmax('uint8')
135  width = 2;
136  else
137  width = 4;
138  end
139  replace = ['0x' dec2hex(illegalChar,width)];
140  varname = strrep(varname, illegalChar, replace);
141  end
142  % Prepend keyword with 'x' and camel case.
143  if iskeyword(varname)
144  varname = ['x' upper(varname(1)) varname(2:end)];
145  end
146  end
147  end
148  end
149 end
function throwerror(in msgTag, in varargin)
THROWERROR works similarly to built-in ERROR function in case when there is no output arguments but s...
function hash(in inpArr, in methodName)
OBJECTHASH counts the hash of input object/array.
function unique(in inpVec)
UNIQUE for arrays of any type.
function structcompare(in SX, in SY, in absTol, in relTol)
STRUCTCOMPARE compares two structures using the specified tolerance.