@@ -43,6 +43,13 @@ local tinsert = table.insert
4343local tremove = table.remove
4444local tmove = table.move
4545local tsort = table.sort
46+ local pack = table.pack
47+ local unpack = table.unpack
48+ local error = error
49+ local coroutine = coroutine
50+ local ccreate = coroutine.create
51+ local cresume = coroutine.resume
52+ local cyield = coroutine.yield
4653
4754local null = {}
4855local arrayEnumerator
@@ -165,6 +172,13 @@ local function set(t, index, v)
165172 t .version = t .version + 1
166173end
167174
175+ local function add (t , v )
176+ local n = # t
177+ t [n + 1 ] = v == nil and null or v
178+ t .version = t .version + 1
179+ return n
180+ end
181+
168182local function addRange (t , collection )
169183 if collection == nil then throw (ArgumentNullException (" collection" )) end
170184 local count = # t + 1
@@ -194,9 +208,17 @@ local function buildArray(T, len, t)
194208 if t == nil then
195209 t = {}
196210 if len > 0 then
197- local default = T .__genericT__ :default ()
198- if default == nil then default = null end
199- fill (t , 1 , len , default )
211+ local genericT = T .__genericT__
212+ local default = genericT :default ()
213+ if default == nil then
214+ fill (t , 1 , len , null )
215+ elseif type (default ) ~= " table" then
216+ fill (t , 1 , len , default )
217+ else
218+ for i = 1 , len do
219+ t [i ] = genericT :default ()
220+ end
221+ end
200222 end
201223 else
202224 if len > 0 then
@@ -282,17 +304,15 @@ local function copy(sourceArray, sourceIndex, destinationArray, destinationIndex
282304end
283305
284306local function removeRange (t , index , count )
285- if count < 0 or index > # t - count then
307+ local n = # t
308+ if count < 0 or index > n - count then
286309 throw (ArgumentOutOfRangeException (" index or count" ))
287310 end
288311 if count > 0 then
289- local size = # t - count
290- if index < size then
291- copy (t , index + count , t , index , size - index )
292- end
293- for i = size + 1 , size + count do
294- t [i ] = nil
312+ if index + count < n then
313+ tmove (t , index + count + 1 , n , index + 1 )
295314 end
315+ fill (t , n - count + 1 , n , nil )
296316 t .version = t .version + 1
297317 end
298318end
@@ -439,9 +459,12 @@ Array = {
439459 if type (collection ) == " number" then return end
440460 addRange (t , collection )
441461 end ,
442- add = function (t , v )
443- t [# t + 1 ] = v == nil and null or v
444- t .version = t .version + 1
462+ add = add ,
463+ addObj = function (this , item )
464+ if not System .is (item , this .__genericT__ ) then
465+ throw (ArgumentException ())
466+ end
467+ return add (this , item )
445468 end ,
446469 addRange = addRange ,
447470 AsReadOnly = function (t )
@@ -719,7 +742,7 @@ Array = {
719742 if count < 0 or startIndex - count + 1 < 0 then
720743 throw (ArgumentOutOfRangeException (" count" ))
721744 end
722- local endIndex = startIndex - count
745+ local endIndex = startIndex - count + 1
723746 for i = startIndex + 1 , endIndex + 1 , - 1 do
724747 local item = t [i ]
725748 if item == null then
@@ -764,7 +787,7 @@ Array = {
764787 end
765788 local comparer = EqualityComparer (t .__genericT__ ).getDefault ()
766789 local equals = comparer .EqualsOf
767- local endIndex = startIndex - count
790+ local endIndex = startIndex - count + 1
768791 for i = startIndex + 1 , endIndex + 1 , - 1 do
769792 local item = t [i ]
770793 if item == null then item = nil end
@@ -862,8 +885,19 @@ Array = {
862885 return t
863886 end ,
864887 CopyTo = function (this , array , index )
865- if array == nil then throw (ArgumentNullException (" array" )) end
866- copy (this , 0 , array , index or 0 , # this )
888+ local n = # this
889+ checkIndexAndCount (array , index , n )
890+ local T = this .__genericT__
891+ if T .class == " S" then
892+ local default = T :default ()
893+ if type (default ) == " table" then
894+ for i = 1 , n do
895+ array [i + index ] = this [i ]:__clone__ ()
896+ end
897+ return
898+ end
899+ end
900+ tmove (this , 1 , n , index + 1 , array )
867901 end ,
868902 GetEnumerator = arrayEnumerator ,
869903 GetLength = function (this , dimension )
@@ -883,6 +917,11 @@ Array = {
883917 end ,
884918 SetValue = function (this , value , index1 , index2 )
885919 set (this , checkArrayIndex (index1 , index2 ), System .castWithNullable (this .__genericT__ , value ))
920+ end ,
921+ Clone = function (this )
922+ local array = {}
923+ tmove (this , 1 , # this , 1 , array )
924+ return arrayFromTable (array , this .__genericT__ )
886925 end
887926}
888927
@@ -958,13 +997,18 @@ local MultiArray = {
958997 GetUpperBound = function (this , dimension )
959998 local rank = this .__rank__
960999 if dimension < 0 or dimension >= # rank then throw (IndexOutOfRangeException ()) end
961- return # rank - 1
1000+ return rank [ dimension + 1 ] - 1
9621001 end ,
9631002 GetValue = function (this , ...)
9641003 return get (this , checkMultiArrayIndex (this , ... ))
9651004 end ,
9661005 SetValue = function (this , value , ...)
9671006 set (this , checkMultiArrayIndex (this , ... ), System .castWithNullable (this .__genericT__ , value ))
1007+ end ,
1008+ Clone = function (this )
1009+ local array = { __rank__ = this .__rank__ }
1010+ tmove (this , 1 , # this , 1 , array )
1011+ return arrayFromTable (array , this .__genericT__ )
9681012 end
9691013}
9701014
@@ -980,11 +1024,84 @@ end
9801024
9811025System .defArray (" System.Array" , function (T )
9821026 return {
983- __inherits__ = { System .IList_1 (T ), System .IReadOnlyList_1 (T ), System .IList },
1027+ __inherits__ = { System .ICloneable , System . IList_1 (T ), System .IReadOnlyList_1 (T ), System .IList },
9841028 __genericT__ = T
9851029 }
9861030end , Array , MultiArray )
9871031
1032+ local yieldCoroutinePool = {}
1033+ local function yieldCoroutineCreate (f )
1034+ local co = tremove (yieldCoroutinePool )
1035+ if co == nil then
1036+ co = ccreate (function (...)
1037+ f (... )
1038+ while true do
1039+ f = nil
1040+ yieldCoroutinePool [# yieldCoroutinePool + 1 ] = co
1041+ f = cyield (yieldCoroutinePool )
1042+ f (cyield ())
1043+ end
1044+ end )
1045+ else
1046+ cresume (co , f )
1047+ end
1048+ return co
1049+ end
1050+
1051+ local YieldEnumerable
1052+ YieldEnumerable = define (" System.YieldEnumerable" , function (T )
1053+ return {
1054+ __inherits__ = { System .IEnumerable_1 (T ), System .IEnumerator_1 (T ), System .IDisposable },
1055+ __genericT__ = T
1056+ }
1057+ end , {
1058+ getCurrent = System .getCurrent ,
1059+ Dispose = System .emptyFn ,
1060+ GetEnumerator = function (this )
1061+ return setmetatable ({ f = this .f , args = this .args }, YieldEnumerable (this .__genericT__ ))
1062+ end ,
1063+ MoveNext = function (this )
1064+ local co = this .co
1065+ if co == false then
1066+ return false
1067+ end
1068+
1069+ local ok , v
1070+ if co == nil then
1071+ co = yieldCoroutineCreate (this .f )
1072+ this .co = co
1073+ local args = this .args
1074+ ok , v = cresume (co , unpack (args , 1 , args .n ))
1075+ this .args = nil
1076+ else
1077+ ok , v = cresume (co )
1078+ end
1079+
1080+ if ok then
1081+ if v == yieldCoroutinePool then
1082+ this .co = false
1083+ this .current = nil
1084+ return false
1085+ else
1086+ this .current = v
1087+ return true
1088+ end
1089+ else
1090+ error (v )
1091+ end
1092+ end
1093+ })
1094+
1095+ function System .yieldIEnumerator (f , T , ...)
1096+ return setmetatable ({ f = f , args = pack (... ) }, YieldEnumerable (T ))
1097+ end
1098+
1099+ function System .yieldIEnumerable (f , T , ...)
1100+ return setmetatable ({ f = f , args = pack (... ) }, YieldEnumerable (T ))
1101+ end
1102+
1103+ System .yieldReturn = cyield
1104+
9881105local ReadOnlyCollection = {
9891106 __ctor__ = function (this , list )
9901107 if not list then throw (ArgumentNullException (" list" )) end
0 commit comments