github.com/remobjects/goldbaselibrary@v0.0.0-20230924164425-d458680a936b/Source/Gold/Gold.pas (about)

     1  namespace go.builtin;
     2  
     3  uses
     4    go.builtin
     5  {$IFDEF ECHOES}  , System.Linq, System.Collections, System.Collections.Generic{$ENDIF}
     6  
     7    ;
     8  
     9  type
    10    [AttributeUsage(AttributeTargets.Assembly, AllowMultiple := true)]
    11    PackageNameAttribute = public class(Attribute)
    12    public
    13      constructor(aNamespace, aName: System.String);
    14      begin
    15        &Namespace := aNamespace;
    16        Name := aName;
    17      end;
    18  
    19      property Name: System.String; readonly;
    20      property &Namespace: System.String; readonly;
    21    end;
    22  
    23  
    24    VTCheck<V> = class
    25    public
    26      class var IsVT := false; readonly;
    27  
    28      class constructor;
    29      begin
    30        var lType := typeOf(V);
    31        {$IFDEF ISLAND}
    32        if not lType.IsValueType and (lType.Methods.Any(a -> a.Name = '__Set')) then
    33          IsVT := true;
    34        {$ELSE}
    35        if not lType.IsValueType and (lType.GetMethods.Any(a -> a.Name = '__Set')) then
    36          IsVT := true;
    37        {$ENDIF}
    38      end;
    39    end;
    40  
    41    CloneHelper<T> = class
    42      {$IF ISLAND}
    43      class var CloneMethod: MethodInfo := typeOf(T).Methods.FirstOrDefault(a -> a.Name = '__Clone'); readonly;
    44      {$ELSE}
    45      class var CloneMethod: System.Reflection.MethodInfo := typeOf(T).GetMethods.FirstOrDefault(a -> a.Name = '__Clone'); readonly;
    46      {$ENDIF}
    47    end;
    48  
    49    IMap = public interface
    50      method GetReflectSequence: sequence of tuple of(go.reflect.Value, go.reflect.Value);
    51      method GetReflectValue(aKey: go.reflect.Value): go.reflect.Value;
    52      method GetReflectKeys: Slice<go.reflect.Value>;
    53      method SetReflectKeyValue(aKey: go.reflect.Value; aValue: go.reflect.Value);
    54      method GetLen: Integer;
    55    end;
    56  
    57    [ValueTypeSemantics]
    58    Map<K, V> = public class(IMap)
    59    private
    60    {$IFDEF ECHOES}
    61      fDict: System.Collections.Generic.Dictionary<K, V> := new System.Collections.Generic.Dictionary<K, V>;
    62    {$ELSEIF ISLAND}
    63      fDict: Dictionary<K, V> := new Dictionary<K, V>;
    64    {$ELSE}
    65    {$ERROR NOT SUPPORTED}
    66    {$ENDIF}
    67  
    68      method set_Item(aItem: K; aVal: V);
    69      begin
    70        fDict[aItem] := aVal;
    71      end;
    72  
    73    public
    74      method __Set(v: Object);
    75      begin
    76        if (v <> nil) and (v <> self) then begin
    77          fDict.Clear();
    78          for each el in Map<K, V>(v):fDict do
    79            fDict.Add(el.Key, el.Value);
    80        end;
    81      end;
    82  
    83      constructor(aArgs: array of tuple of (K, V));
    84      begin
    85        for each el in aArgs do
    86          fDict[el[0]] := el[1];
    87      end;
    88  
    89      constructor(aCap: Integer);
    90      begin
    91        //fDict.Capacity := aCap;
    92      end;
    93  
    94      constructor(aCap: go.builtin.int);
    95      begin
    96        //fDict.Capacity := aCap;
    97      end;
    98  
    99      constructor();
   100      begin
   101      end;
   102      {$IFDEF ECHOES}
   103      class operator implicit(aVal:  System.Collections.Generic.Dictionary<K, V>): Map<K, V>;
   104      begin
   105        result := new Map<K, V>;
   106        for each el in aVal do
   107          result.fDict.Add(el.Key, el.Value);
   108      end;
   109  
   110      class operator implicit(aVal: Map<K, V>):  System.Collections.Generic.Dictionary<K, V>;
   111      begin
   112        result := new System.Collections.Generic.Dictionary<K, V>;
   113  
   114        for each el in aVal.fDict do
   115          result.Add(el.Key, el.Value);
   116      end;
   117      {$ELSEIF ISLAND}
   118      class operator implicit(aVal:  Dictionary<K, V>): Map<K, V>;
   119      begin
   120        result := new Map<K, V>;
   121        for each el in aVal do
   122          result.fDict.Add(el.Key, el.Value);
   123      end;
   124  
   125      class operator implicit(aVal: Map<K, V>):  Dictionary<K, V>;
   126      begin
   127        result := new Dictionary<K, V>;
   128  
   129        for each el in aVal.fDict do
   130          result.Add(el.Key, el.Value);
   131      end;
   132      {$ELSE}
   133      {$ERROR NOT SUPPORTED}
   134      {$ENDIF}
   135  
   136      constructor(aKeys: array of K; aValues: array of V);
   137      begin
   138        if aKeys.Length <> aValues.Length then raise new Exception('Keys/Values do not match!');
   139        for i: Integer := 0 to aKeys.Length -1 do
   140          fDict[aKeys[i]] := aValues[i];
   141      end;
   142  
   143      class var fZero: Map<K, V> := new Map<K, V>();
   144      class property Zero: Map<K, V> := fZero; published;
   145  
   146      method __Clone: Map<K, V>;
   147      begin
   148        exit self;
   149      end;
   150  
   151      class operator IsNil(aVal: Map<K, V>): Boolean;
   152      begin
   153        result := (Object(aVal) = nil) or (Object(aVal) = Object(fZero));
   154      end;
   155  
   156      class operator Equal(Value1, Value2: Map<K, V>): Boolean;
   157      begin
   158        if ((Object(Value1) = nil) and (Object(Value2) = Object(fZero))) or ((Object(Value1) = Object(fZero)) and (Object(Value2) = nil)) then
   159          exit true;
   160  
   161        exit Object(Value1) = Object(Value2);
   162      end;
   163  
   164      class operator NotEqual(Value1, Value2: Map<K, V>): Boolean;
   165      begin
   166        result := not (Value1 = Value2);
   167      end;
   168  
   169      property Item[aItem: K]: V write set_Item; default;
   170      property Item[aItem: K]: tuple of (V, Boolean) read get_Item; default;
   171  
   172      method Get(aItem: K): V;
   173      begin
   174        exit Item[aItem][0];
   175      end;
   176  
   177      method Add(a: K; b: V);
   178      begin
   179        fDict[a] := b;
   180      end;
   181  
   182      method get_Item(aItem: K): tuple of (V, Boolean);
   183      begin
   184        var val: V;
   185        if fDict.TryGetValue(aItem,out val) then
   186          exit (val, true);
   187  
   188        {$IFDEF ISLAND}
   189        if VTCheck<V>.IsVT  then
   190          exit (typeOf(V).Instantiate as V, false);
   191        {$ELSE}
   192        if VTCheck<V>.IsVT then
   193          exit (Activator.CreateInstance<V>(), false);
   194        {$ENDIF}
   195        var lZero := go.reflect.Zero(new go.reflect.TypeImpl(typeOf(V)));
   196        if lZero.fValue <> nil then
   197          exit (lZero.fValue as V, false);
   198  
   199        exit (default(V), false);
   200      end;
   201  
   202      method Delete(aKey: K);
   203      begin
   204        fDict.Remove(aKey);
   205      end;
   206  
   207      method GetLen: Integer;
   208      begin
   209        result := Length;
   210      end;
   211  
   212      property Length: Integer read fDict.Count;
   213  
   214      method GetSequence: sequence of tuple of (K, V);
   215      begin
   216        {$IFDEF ISLAND}
   217        exit fDict.GetSequence.Select(a -> (a.Key, a.Value));
   218        {$ELSE}
   219        exit fDict.Select(a -> (a.Key, a.Value));
   220        {$ENDIF}
   221      end;
   222  
   223      method GetReflectSequence: sequence of tuple of(go.reflect.Value, go.reflect.Value);
   224      begin
   225        {$IFDEF ISLAND}
   226        exit fDict.GetSequence.Select(a -> (new go.reflect.Value(a.Key), new go.reflect.Value(a.Value)));
   227        {$ELSE}
   228        exit fDict.Select(a -> (new go.reflect.Value(a.Key), new go.reflect.Value(a.Value)));
   229        {$ENDIF}
   230      end;
   231  
   232      method GetReflectValue(aKey: go.reflect.Value): go.reflect.Value;
   233      begin
   234        result := new go.reflect.Value(Item[K(aKey.fValue)]);
   235      end;
   236  
   237      method GetReflectKeys: Slice<go.reflect.Value>;
   238      begin
   239        {$IFDEF ISLAND}
   240        exit fDict.GetSequence.Select(a -> (new go.reflect.Value(a.Key))).ToArray;
   241        {$ELSE}
   242        exit fDict.Select(a -> (new go.reflect.Value(a.Key))).ToArray;
   243        {$ENDIF}
   244      end;
   245  
   246      method SetReflectKeyValue(aKey: go.reflect.Value; aValue: go.reflect.Value);
   247      begin
   248        if aValue.IsValid then
   249          &Add(aKey.fValue as K, aValue.fValue as V)
   250        else
   251          Delete(aKey.fValue as K);
   252      end;
   253    end;
   254  
   255  {$IFDEF ISLAND}
   256    IndexOutOfRangeException = public class(Exception) end;
   257  {$ENDIF}
   258    ISlice = public interface
   259      method getAtIndex(i: Integer): Object;
   260      method setAtIndex(i: Integer; aValue: Object);
   261      method getCap: Integer;
   262      method setCap: Integer;
   263      method getLen: Integer;
   264      method setLen(aValue: Integer): Integer;
   265      method setFrom(aSrc: ISlice);
   266      method getReflectSlice(i: Integer; j: Integer): go.reflect.Value;
   267      method AppendObject(aObject: Object): go.reflect.Value;
   268      method CloneElems: Object;
   269    end;
   270  
   271  
   272    [ValueTypeSemantics]
   273    Slice<T> = public class(go.sort.Interface, ISlice)
   274    assembly
   275      fArray: array of T;
   276      fStart, fCount: Integer;
   277  
   278      method get_Item(i: Integer): T;
   279      begin
   280        if (i < 0) or (i ≥ fCount) then raise new IndexOutOfRangeException('Index out of range');
   281        {$IFDEF ISLAND}
   282        if VTCheck<T>.IsVT and (Object(fArray[i + fStart]) = nil) then
   283          fArray[i + fStart] := typeOf(T).Instantiate as T;
   284        {$ELSE}
   285        if VTCheck<T>.IsVT and (Object(fArray[i + fStart]) = nil) then
   286          fArray[i + fStart] := Activator.CreateInstance<T>();
   287        {$ENDIF}
   288        exit fArray[i + fStart];
   289      end;
   290  
   291      method set_Item(i: Integer; aVal: T);
   292      begin
   293        if (i < 0) or (i ≥ Capacity) then raise new IndexOutOfRangeException('Index out of range');
   294        fArray[i + fStart] := aVal;
   295      end;
   296      class var EmptyArray: array of T := [];
   297    public
   298  
   299      constructor(aArray: array of T; aStart, aCount: Integer);
   300      begin
   301        if (aStart < 0) or (aStart + aCount > aArray.Length) then raise new IndexOutOfRangeException('Index out of range');
   302        fArray := aArray;
   303        fStart := aStart;
   304        fCount := aCount;
   305      end;
   306  
   307      method Ref(i: int64): Memory<T>; unsafe;
   308      begin
   309        exit @fArray[i];
   310      end;
   311  
   312      constructor;
   313      begin
   314        constructor(EmptyArray, 0, 0);
   315      end;
   316  
   317      constructor(params aArray: array of T);
   318      begin
   319        constructor(aArray, 0, aArray.Length);
   320      end;
   321  
   322      constructor(aSize, aCap: go.builtin.int);
   323      begin
   324        if aCap < aSize then aCap := aSize;
   325        constructor(new T[aCap], 0, aSize);
   326      end;
   327  
   328      constructor(aSize, aCap: int64);
   329      begin
   330        if aCap < aSize then aCap := aSize;
   331        constructor(new T[aCap], 0, aSize);
   332      end;
   333  
   334      constructor(aSize: go.builtin.int; aCap: int64);
   335      begin
   336        if aCap < aSize then aCap := aSize;
   337        constructor(new T[aCap], 0, aSize);
   338      end;
   339      constructor(aSize: int64; aCap: go.builtin.int);
   340      begin
   341        if aCap < aSize then aCap := aSize;
   342        constructor(new T[aCap], 0, aSize);
   343      end;
   344  
   345      constructor(aSize: go.builtin.int);
   346      begin
   347        constructor(aSize, aSize);
   348      end;
   349  
   350      constructor(aSize: int64);
   351      begin
   352        constructor(aSize, aSize);
   353      end;
   354  
   355      class var fZero: Slice<T> := new Slice<T>;
   356      //class property Zero: Slice<T> := fZero; published;
   357      class property Zero: Slice<T> read new Slice<T>;
   358  
   359      class operator IsNil(aVal: Slice<T>): Boolean;
   360      begin
   361        result := (Object(aVal) = nil) or (Object(aVal) = Object(fZero)) or ((aVal.fArray = EmptyArray) and (aVal.Length = 0) and (aVal.Capacity = 0));
   362      end;
   363  
   364      method Assign(aOrg: array of T);
   365      begin
   366        if aOrg <> nil then
   367          for i: Integer := 0 to aOrg. Length -1 do begin
   368            self[i] := aOrg[i];
   369          end;
   370      end;
   371  
   372      method Assign(aOrg: Slice<T>);
   373      begin
   374        if aOrg <> nil then
   375        for i: Integer := 0 to aOrg. Length -1 do begin
   376          self[i] := aOrg[i];
   377        end;
   378      end;
   379  
   380      method getAtIndex(i: Integer): Object;
   381      begin
   382        result := get_Item(i);
   383      end;
   384  
   385      method AppendObject(aObject: Object): go.reflect.Value;
   386      begin
   387        exit new go.reflect.Value(append(self, T(aObject)));
   388      end;
   389  
   390      method setAtIndex(i: Integer; aValue: Object);
   391      begin
   392        set_Item(i, T(aValue));
   393      end;
   394  
   395      method getCap: Integer;
   396      begin
   397        result := Capacity;
   398      end;
   399  
   400      method setCap: Integer;
   401      begin
   402  
   403      end;
   404  
   405      method setLen(aValue: Integer): Integer;
   406      begin
   407        fCount := aValue;
   408      end;
   409  
   410      method getLen: Integer;
   411      begin
   412        result := Length;
   413      end;
   414  
   415      method setFrom(aSrc: go.builtin.ISlice);
   416      begin
   417        fArray := new T[aSrc.getCap];
   418        fStart := 0;
   419        //fStart := aSrc.fStart;
   420        fCount := aSrc.getLen;
   421      end;
   422  
   423      method ToArray: array of T;
   424      begin
   425        result := new T[Length];
   426        &Array.Copy(fArray, fStart, result, 0, fCount);
   427      end;
   428  
   429      method Len: go.builtin.int;
   430      begin
   431        result := fCount;
   432      end;
   433  
   434      method getReflectSlice(i: Integer; j: Integer): go.reflect.Value;
   435      begin
   436        result := new go.reflect.Value(new Slice<T>(fArray, i, j-i));
   437      end;
   438  
   439      method Less(a, b: go.builtin.int): go.builtin.bool;
   440      begin
   441  
   442      end;
   443  
   444      method Swap(a, b: go.builtin.int);
   445      begin
   446        var p := self[a];
   447        self[a] := self[b];
   448        self[b] := p;
   449      end;
   450  
   451      // helper; for contructor calls.
   452      method Add(a: Integer; b: T);
   453      begin
   454        Item[a] := b;
   455      end;
   456  
   457      property Capacity: Integer read fArray.Length - fStart;
   458      property Length: Integer read fCount;
   459      property Item[i: Integer]: T read get_Item write set_Item; default;
   460  
   461      class method Copy(aSource, aDest: Slice<T>);
   462      begin
   463        var lCopy := Math.Min(aSource.Length, aDest.Length);
   464        for i: Integer := 0 to lCopy -1 do
   465          aDest[i] := aSource[i];
   466      end;
   467  
   468      method CloneElems: Object;
   469      begin
   470        if CloneHelper<T>.CloneMethod <> nil then begin
   471          var lNewArray := new T[Capacity];
   472          for i: Integer := 0 to fArray.Length -1 do
   473            if fArray[i] <> nil then
   474              lNewArray[i] := T(CloneHelper<T>.CloneMethod.Invoke(fArray[i], []))
   475            else
   476              lNewArray[i] := nil;
   477  
   478          exit new Slice<T>(lNewArray, fStart, fCount);
   479        end
   480        else
   481          exit self;
   482      end;
   483  
   484      method Grow(aNewLen: Integer): Slice<T>;
   485      begin
   486        if aNewLen > Capacity then raise new ArgumentException('Length larger than capacity!');
   487  
   488        exit new Slice<T>(fArray, fStart, aNewLen);
   489      end;
   490  
   491      class operator implicit(aVal: array of T): Slice<T>;
   492      begin
   493        exit new Slice<T>(aVal);
   494      end;
   495  
   496      method GetSequence: sequence of tuple of (Integer, T); iterator;
   497      begin
   498        for i: Integer := 0 to Length -1 do
   499          yield (i, self[i]);
   500      end;
   501  
   502      class operator implicit(aVal: Slice<T>): array of T;
   503      begin
   504        if aVal = nil then
   505          exit new T[0];
   506  
   507        exit aVal.ToArray();
   508      end;
   509  
   510      class operator Equal(Value1, Value2: Slice<T>): Boolean; published;
   511      begin
   512        // Compare also if both are nil, sice fZero is not the same for all instances.
   513        if ((Object(Value1) = nil) and (Object(Value2) = Object(fZero))) or ((Object(Value1) = Object(fZero)) and (Object(Value2) = nil)) or
   514        (((Value1.fArray = EmptyArray) and (Value1.Length = 0) and (Value1.Capacity = 0)) and ((Value2.fArray = EmptyArray) and (Value2.Length = 0) and (Value2.Capacity = 0))) then
   515          exit true;
   516  
   517        exit Object(Value1) = Object(Value2);
   518      end;
   519  
   520      class operator NotEqual(Value1, Value2: Slice<T>): Boolean;
   521      begin
   522        result := not (Value1 = Value2);
   523      end;
   524  
   525      /*method Get(idxs: Slice<go.builtin.int32>; idx1: go.builtin.int32; idx2: go.builtin.int32): T;
   526      begin
   527        raise new NotImplementedException;
   528      end;
   529  
   530      method Get(idxs: Slice<go.builtin.int32>; idx1: go.builtin.int32): T;
   531      begin
   532        raise new NotImplementedException;
   533      end;*/
   534  
   535      method Get(idx1: go.builtin.int32; idx2: go.builtin.int32): T;
   536      begin
   537        raise new NotImplementedException;
   538      end;
   539  
   540  
   541    end;
   542  
   543    error = public soft interface
   544      method Error: string;
   545    end;
   546  
   547  
   548    IWaitMessage = public interface
   549      method Cancel;
   550      method Start(aNotifier: Func<Func<Boolean>, Boolean>): Boolean;
   551    end;
   552  
   553    IWaitSendMessage = public interface(IWaitMessage)
   554    end;
   555  
   556    IWaitReceiveMessage<T> = public interface(IWaitMessage)
   557      method TryHandOff(aVal: T): Boolean;
   558      property Data: tuple of (T, Boolean) read;
   559    end;
   560  
   561    IChannel = public interface
   562      property Length: Integer read;
   563    end;
   564  
   565    Channel<T> = public interface
   566      property Capacity: Integer read;
   567      method Close;
   568    end;
   569  
   570    ReceivingChannel<T> = public interface(Channel<T>)
   571      method Receive: tuple of (T, Boolean);
   572      method TryReceive: IWaitReceiveMessage<T>;
   573      method GetSequence: sequence of T;
   574    end;
   575  
   576    SendingChannel<T> = public interface(Channel<T>)
   577      method Send(aVal: T);
   578      method TrySend(aVal: T): IWaitSendMessage;
   579    end;
   580  
   581    GoException = public class(Exception)
   582    public
   583      property Value: Object; readonly;
   584      constructor(aVal: Object);
   585      begin
   586        inherited constructor(aVal.ToString);
   587        Value := aVal;
   588      end;
   589    end;
   590  
   591    method copy<T>(dst, src: Slice<T>): Integer;
   592    begin
   593      result := Math.Min(if src = nil then 0 else src.Length, if dst = nil then 0 else dst.Length);
   594      for i: Integer := 0 to result -1 do
   595        dst[i] := src[i];
   596    end;
   597  
   598    method copy(dst: Slice<byte>; src: string): Integer;
   599    begin
   600      {$IFDEF ISLAND}
   601      exit copy(dst, new Slice<byte>(Encoding.UTF8.GetBytes(src)));
   602      {$ELSE}
   603      exit copy(dst, new Slice<byte>(System.Text.Encoding.UTF8.GetBytes(src)));
   604      {$ENDIF}
   605    end;
   606  
   607    method append<T>(sl: Slice<T>; elems: T): Slice<T>;
   608    begin
   609      var slc := if sl = nil then 0 else sl.Length;
   610      var lNew := new T[slc + 1];
   611      for i: Integer := 0 to slc -1 do
   612        lNew[i] := sl[i];
   613  
   614      if (elems is IList) then begin
   615        {$IF ECHOES}
   616        var lType := typeOf(T);
   617        var lElementsType := lType.GetElementType();
   618        var CloneMethod: System.Reflection.MethodInfo := lElementsType.GetMethods.FirstOrDefault(a -> a.Name = '__Clone');
   619        var lTmp := Array.CreateInstance(lElementsType, IList(elems).Count);
   620        for i: Integer := 0 to IList(elems).Count - 1 do begin
   621          if CloneMethod <> nil then
   622            lTmp.SetValue(CloneMethod.Invoke(IList(elems)[i], []), i)
   623          else
   624            lTmp.SetValue(IList(elems)[i], i);
   625        end;
   626        {$ELSE}
   627        var lType := typeOf(sl);
   628        var lGeneric := lType.GenericArguments.First;
   629        var lElementsType := lGeneric.GenericArguments.First;
   630        var CloneMethod: MethodInfo := lElementsType.Methods.FirstOrDefault(a -> a.Name = '__Clone');
   631        var lTmp := InternalCalls.Cast<&Array>(Utilities.NewArray(lGeneric.RTTI, lElementsType.SizeOfType, IList(elems).Count));
   632        for i: Integer := 0 to IList(elems).Count - 1 do begin
   633          if CloneMethod <> nil then
   634            IList(lTmp)[i] := CloneMethod.Invoke(IList(elems)[i], [])
   635          else
   636            IList(lTmp)[i]:= IList(elems)[i];
   637          end;
   638        {$ENDIF}
   639        lNew[slc] := T(lTmp);
   640      end
   641      else
   642        //if (elems is go.builtin.ISlice) then begin
   643          //lNew[slc] := T(go.builtin.ISlice(elems).CloneElems);
   644        //end
   645        //else
   646            lNew[slc] := elems;
   647  
   648      exit lNew;
   649    end;
   650  
   651    method append<T>(sl: Slice<T>; a: T; params elems: array of T): Slice<T>;
   652    begin
   653      var c := if elems = nil then 0 else IList<T>(elems).Count;
   654      var slc := if sl = nil then 0 else sl.Length;
   655      if c + slc + 1 ≤ sl.Capacity then begin
   656        sl[slc] := a;
   657        for i: Integer := 0 to c -1 do
   658          sl[slc + i + 1] := IList<T>(elems)[i];
   659        sl.setLen(slc + c + 1);
   660        exit sl;
   661      end
   662      else begin
   663        var lNew := new T[slc + c + 1];
   664        for i: Integer := 0 to slc -1 do
   665          lNew[i] := sl[i];
   666        lNew[slc] := a;
   667        for i: Integer := 0 to c -1 do
   668          lNew[i + slc + 1] := IList<T>(elems)[i];
   669        exit lNew;
   670      end;
   671    end;
   672  
   673    method append<T>(sl, elems: Slice<T>): Slice<T>;
   674    begin
   675      var c := if elems = nil then 0 else elems.Length;
   676      var slc := if sl = nil then 0 else sl.Length;
   677      var slCap := if sl = nil then 0 else sl.Capacity;
   678      var lNew := new T[if (slc + c) <= slCap then slCap else slc + c];
   679      for i: Integer := 0 to slc -1 do
   680        lNew[i] := sl[i];
   681      for i: Integer := 0 to c -1 do
   682        lNew[i + slc] := elems[i];
   683      exit new Slice<T>(lNew, 0, slc + c);
   684    end;
   685  
   686    method append(sl: Slice<byte>; elems: string): Slice<byte>;
   687    begin
   688      exit append(sl, elems.Value);
   689    end;
   690  
   691    method close<T>(v: Channel<T>); public;
   692    begin
   693      v.Close;
   694    end;
   695  
   696    method cap<T>(v: Channel<T>): Integer; public;
   697    begin
   698      if v = nil then exit 0;
   699      exit v.Capacity;
   700    end;
   701  
   702    method cap<T>(v: Slice<T>): Integer; public;
   703    begin
   704      if Object(v) = nil then exit -1;
   705      exit v.Capacity;
   706    end;
   707  
   708    method len(v: string): Integer; public;
   709    begin
   710      //exit v.Value.Length;
   711      exit v.Length;
   712    end;
   713  
   714    method len<T>(v: array of T): Integer; public;
   715    begin
   716      exit length(v);
   717    end;
   718  
   719    method len<T>(v: Slice<T>): Integer; public;
   720    begin
   721      if v = nil then exit 0;
   722      exit v.Length;
   723    end;
   724  
   725    method len<K, V>(v: Map<K, V>): Integer; public;
   726    begin
   727      if v = nil then exit 0;
   728      exit v.Length;
   729    end;
   730  
   731    method Start(v: Action); public;
   732    begin
   733      {$IFDEF ISLAND}
   734      Task.Run(v);
   735      {$ELSE}
   736      System.Threading.Tasks.Task.Factory.StartNew(v);
   737      {$ENDIF}
   738    end;
   739  
   740    method AssignArray<T>(aDest, aSource: array of T); public;
   741    begin
   742      for i: Integer := 0 to Math.Min(length(aDest), length(aSource)) -1 do
   743        aDest[i] := aSource[i];
   744    end;
   745  
   746    method Send<T>(aChannel: SendingChannel<T>; aVal: T); public;
   747    begin
   748      if aChannel ≠ nil then
   749        aChannel.Send(aVal);
   750    end;
   751  
   752    method Receive<T>(aChannel: ReceivingChannel<T>): tuple of (T, Boolean); public;
   753    begin
   754      if aChannel = nil then
   755        exit (nil, false);
   756  
   757      exit aChannel.Receive();
   758    end;
   759  
   760    method delete<K,V>(aMap: Map<K, V>; aKey: K); public;
   761    begin
   762      aMap.Delete(aKey);
   763    end;
   764  
   765    method Slice<T>(aSlice: Slice<T>; aStart, aEnd: nullable Integer): Slice<T>; public;
   766    begin
   767      if aSlice = nil then
   768        exit nil;
   769      var lStart := valueOrDefault(aStart, 0);
   770      var lEnd := valueOrDefault(aEnd, aSlice.Length);
   771      //if Integer(lEnd) > aSlice.Length then lEnd := aSlice.Length;
   772      if (lStart = 0) and (lEnd = aSlice.Length) then exit aSlice;
   773      lStart := lStart + aSlice.fStart;
   774      lEnd := lEnd + aSlice.fStart;
   775      exit new Slice<T>(aSlice.fArray, lStart, lEnd - lStart);
   776    end;
   777  
   778    method Slice<T>(aSlice: Slice<T>; aStart, aEnd: nullable Integer; aCap: Integer): Slice<T>; public;
   779    begin
   780      var lStart := valueOrDefault(aStart, 0);
   781      var lEnd := valueOrDefault(aEnd, aSlice.Length);
   782      var lCap := aCap - aStart;
   783      if Integer(lEnd) > aSlice.Length then lEnd := aSlice.Length;
   784      if (lStart = 0) and (lEnd = aSlice.Length) then exit aSlice;
   785      lStart := lStart + aSlice.fStart;
   786      lEnd := lEnd + aSlice.fStart;
   787      if lCap > lEnd then begin
   788        var
   789          lSlice := new T[lCap];
   790          Array.Copy(aSlice.fArray, lStart, lSlice, 0, lEnd - lStart);
   791          exit new Slice<T>(lSlice, lStart, lEnd - lStart);
   792      end;
   793      exit new Slice<T>(aSlice.fArray, lStart, lEnd - lStart);
   794    end;
   795  
   796    method Slice<T>(aSlice: array of T; aStart, aEnd: nullable Integer; aCap: Integer): Slice<T>; public;
   797    begin
   798      var lStart := valueOrDefault(aStart, 0);
   799      var lEnd := valueOrDefault(aEnd, aSlice.Length);
   800      var lCap := aCap - aStart;
   801      if Integer(lEnd) > aSlice.Length then lEnd := aSlice.Length;
   802      if (lStart = 0) and (lEnd = aSlice.Length) then exit aSlice;
   803      if lCap > lEnd then begin
   804        var
   805        lSlice := new T[lCap];
   806        Array.Copy(aSlice, lStart, lSlice, 0, lEnd - lStart);
   807        exit new Slice<T>(lSlice, lStart, lEnd - lStart);
   808      end;
   809      exit new Slice<T>(aSlice, lStart, lEnd - lStart);
   810    end;
   811  
   812  
   813    method Slice(aSlice: string; aStart, aEnd: nullable Integer): string; public;
   814    begin
   815      var lStart := valueOrDefault(aStart, 0);
   816      var lEnd := valueOrDefault(aEnd, aSlice.Length);
   817      if Integer(lEnd) > aSlice.Length then lEnd := aSlice.Length;
   818      if (lStart = 0) and (lEnd = aSlice.Length) then exit aSlice;
   819      exit new string(new Slice<byte>(aSlice.Value, lStart, lEnd - lStart));
   820    end;
   821  
   822    method Slice<T>(aSlice: array of T; aStart, aEnd: nullable Integer): Slice<T>; public;
   823    begin
   824      exit Slice(new Slice<T>(aSlice), aStart, aEnd);
   825    end;
   826  
   827    method TypeAssert<T>(v: Object): tuple of (T, Boolean);
   828    begin
   829      if (v ≠ nil) and (v is Memory<T>) then begin
   830        exit (Memory<T>(v)^, true);
   831      end;
   832  
   833      if v is T then
   834        exit (T(v), true);
   835  
   836      if v is IMemory then begin
   837        if IMemory(v).GetValue is T then
   838          exit (IMemory(v).GetValue as T, true);
   839      end;
   840      {$IFDEF ISLAND}
   841      if VTCheck<T>.IsVT  then
   842        exit (typeOf(T).Instantiate as T, false);
   843      {$ELSE}
   844      if VTCheck<T>.IsVT then
   845        exit (Activator.CreateInstance<T>(), false);
   846      {$ENDIF}
   847      var lZero := go.reflect.Zero(new go.reflect.TypeImpl(typeOf(T)));
   848      if lZero.fValue <> nil then
   849        exit (lZero.fValue as T, false);
   850  
   851      exit (default(T), false); // for integers, T(V) cast would fail otherwise.
   852    end;
   853  
   854    method TypeAssertReference<T>(v: Object): tuple of (&Memory<T>, Boolean);
   855    begin
   856      result := TypeAssert<Memory<T>>(v);
   857      if result[1] then exit;
   858      if v is T then
   859        exit (new Memory<T>(T(v)), true);
   860    end;
   861  
   862    method panic(v: Object);
   863    begin
   864      raise new GoException(v);
   865    end;
   866  
   867    method recover: Object;
   868    begin
   869      exit nil;
   870    end;
   871  
   872    extension method ISequence<T>.GoldIterate: sequence of tuple of (Integer, T); iterator; public;
   873    begin
   874      for each el in self index n do
   875        yield (n, el);
   876    end;
   877  
   878  type
   879    IntExtension = extension class(Integer, go.fmt.Stringer)
   880    public
   881      method String: string;
   882      begin
   883        exit self.ToString;
   884      end;
   885    end;
   886  
   887    [AttributeUsage(AttributeTargets.Field)]
   888    TagAttribute = public class(Attribute)
   889    private
   890      fTag: string;
   891    public
   892      constructor(aTag: PlatformString);
   893      begin
   894        fTag := aTag;
   895      end;
   896  
   897      property Tag: string read fTag;
   898    end;
   899  
   900    go.crypto.internal.subtle.__Global = public partial class
   901    public
   902      class method InexactOverlap(x, y: go.builtin.Slice<byte>): Boolean;
   903      begin
   904        if (x.Length = 0) or (y.Length = 0) or (x.fArray <> y.fArray) or ((x.fArray = y.fArray) and (x.fStart = y.fStart)) then
   905          exit false;
   906  
   907        if (x.fArray = y.fArray) and ((x.fStart ≤ (y.fStart + y.Length)) and (y.fStart ≤ (x.fStart + x.Length))) then
   908          exit true
   909        else
   910          exit false;
   911      end;
   912    end;
   913  
   914    [assembly:GoldAspect.GoldFixer]
   915  
   916  
   917    extension method go.reflect.Kind.String(): go.builtin.string; public;
   918    begin
   919      case Integer(self) of
   920        0: exit 'Invalid';
   921        1: exit 'Bool';
   922        2: exit 'Int';
   923        3: exit 'Int8';
   924        4: exit 'Int16';
   925        5: exit 'Int32';
   926        6: exit 'Int64';
   927        7: exit 'Uint';
   928        8: exit 'Uint8';
   929        9: exit 'Uint16';
   930        10: exit 'Uint32';
   931        11: exit 'Uint64';
   932        12: exit 'Uintptr';
   933        13: exit 'Float32';
   934        14: exit 'Float64';
   935        15: exit 'Complex64';
   936        16: exit 'Complex128';
   937        17: exit '&Array';
   938        18: exit 'Chan';
   939        19: exit 'Func';
   940        20: exit '&Interface';
   941        21: exit 'Map';
   942        22: exit 'Ptr';
   943        23: exit 'Slice';
   944        24: exit 'String';
   945        25: exit 'Struct';
   946        26: exit 'UnsafePointer';
   947      end;
   948      exit 'Unknown';
   949    end;
   950  
   951  
   952  
   953  end.