diff --git a/TestSuite/diapasons4.pas b/TestSuite/diapasons4.pas deleted file mode 100644 index 74788c3ea..000000000 --- a/TestSuite/diapasons4.pas +++ /dev/null @@ -1,6 +0,0 @@ -begin - var r := 1..2; - assert(r <> nil); - r := nil; - assert(r = nil); -end. \ No newline at end of file diff --git a/bin/Lib/PABCSystem.pas b/bin/Lib/PABCSystem.pas index f26780be6..7a96fb3ca 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -619,238 +619,209 @@ type type /// Тип диапазона целых - IntRange = class(IEnumerable) - private - l,h: integer; - function GetCount: integer; - begin - Result := h-l+1; - if Result<0 then - Result := 0; - end; - public + IntRange = record(ICollection, IReadOnlyCollection, IEquatable) + private + l,h: integer; + public constructor(l,h: integer); begin Self.l := l; Self.h := h; end; + property Low: integer read l; property High: integer read h; - //property Count: integer read GetCount; - - static function operator in(x: integer; r: IntRange): boolean := (x >= r.l) and (x <= r.h); - static function operator in(x: real; r: IntRange): boolean := (x >= r.l) and (x <= r.h); - static function operator=(r1,r2: IntRange): boolean; + property Count: integer read System.Math.Max(0,h-l+1); + + property ICollection.IsReadOnly: boolean read boolean(true); + procedure ICollection.Add(item: integer) := raise new System.InvalidOperationException; + function ICollection.Remove(item: integer): boolean; begin - var o1: object := r1; - var o2: object := r2; - if (o1 = nil) and (o2 = nil) then - Result := true - else if (o1 <> nil) and (o2 = nil) then - Result := false - else if (o1 = nil) and (o2 <> nil) then - Result := false - else - Result := (r1.l = r2.l) and (r1.h = r2.h); + Result := false; + raise new System.InvalidOperationException; + end; + procedure ICollection.Clear := raise new System.InvalidOperationException; + + static function operator in(x: integer; r: IntRange): boolean := (x >= r.l) and (x <= r.h); + static function operator in(x: real; r: IntRange): boolean := (x >= r.l) and (x <= r.h); + public function Contains(x: integer) := x in self; + public function Contains(x: real) := x in self; + + static function operator=(r1,r2: IntRange) := + (r1.l = r2.l) and (r1.h = r2.h); + static function operator<>(r1,r2: IntRange) := not(r1=r2); + function Equals(other: IntRange) := self=other; + function Equals(o: object): boolean; override; + begin + Result := false; + if not(o is IntRange) then exit; + if self <> IntRange(o) then exit; + Result := true; end; /// Возвращает True если диапазон пуст function IsEmpty: boolean := l>h; - + function Step(n: integer): sequence of integer; function Reverse: sequence of integer; - - function GetEnumerator(): IEnumerator; + + function GetEnumerator: IEnumerator; function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := Self.GetEnumerator; - + function ToString: string; override := $'{l}..{h}'; - function Equals(o: Object): boolean; override; - begin - var r2 := IntRange(o); - Result := (l = r2.l) and (h = r2.h); - end; - function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode; - {function ToArray: array of integer; + + function GetHashCode: integer; override := + ValueTuple.Create(l,h).GetHashCode; + + function ToArray: array of integer; begin Result := new integer[Count]; - var x := l; for var i := 0 to Result.Length - 1 do - begin - Result[i] := x; - x += 1; - end; - end; - function ToList: List; - begin - Result := new List(Count); - var x := l; - loop Count do - begin - Result.Add(x); - x += 1; - end; - end;} - function ToLinkedList: LinkedList; - begin - Result := new LinkedList(System.Linq.Enumerable.Range(l,GetCount)); - end; - function ToHashSet: HashSet; - begin - Result := new HashSet(System.Linq.Enumerable.Range(l,GetCount)); - end; - function ToSortedSet: SortedSet; - begin - Result := new SortedSet(System.Linq.Enumerable.Range(l,GetCount)); + Result[i] := l+i; end; + // .ToList, .ToLinkedList, .ToHashSet, .ToSortedSet: + // Эти же методы последовательностей уже проверяют "is ICollection" и затем используют свойство .Count + // Только .ToArray перевыделяет память 1 лишний раз: + // https://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,783a052330e7d48d,references + + public procedure CopyTo(a: array of integer; arrayIndex: integer) := + for var i := 0 to System.Math.Min(self.Count, a.Length-arrayIndex) do + a[i+arrayIndex] := l+i; + end; - + /// Тип диапазона символов - CharRange = class(IEnumerable) - private - l,h: char; - function GetCount: integer; - begin - Result := integer(h) - integer(l)+1; - if Result<0 then - Result := 0; - end; - public + CharRange = record(ICollection, IReadOnlyCollection, IEquatable) + private + l,h: char; + public constructor(l,h: char); begin Self.l := l; Self.h := h; end; + property Low: char read l; property High: char read h; - //property Count: integer read GetCount; - - static function operator in(x: char; r: CharRange): boolean := (x >= r.l) and (x <= r.h); - static function operator=(r1,r2: CharRange): boolean := (r1.l = r2.l) and (r1.h = r2.h); + property Count: integer read System.Math.Max(0, integer(h)-integer(l)+1); + + property ICollection.IsReadOnly: boolean read boolean(true); + procedure ICollection.Add(item: char) := raise new System.InvalidOperationException; + function ICollection.Remove(item: char): boolean; + begin + Result := false; + raise new System.InvalidOperationException; + end; + procedure ICollection.Clear := raise new System.InvalidOperationException; + + static function operator in(x: char; r: CharRange): boolean := (x >= r.l) and (x <= r.h); + public function Contains(x: char) := x in self; + + static function operator=(r1,r2: CharRange) := + (r1.l = r2.l) and (r1.h = r2.h); + static function operator<>(r1,r2: CharRange) := not(r1=r2); + function Equals(other: CharRange) := self=other; + function Equals(o: object): boolean; override; + begin + Result := false; + if not(o is CharRange) then exit; + if self <> CharRange(o) then exit; + Result := true; + end; /// Возвращает True если диапазон пуст function IsEmpty: boolean := l>h; - + function Step(n: integer): sequence of char; function Reverse: sequence of char; - - function GetEnumerator(): IEnumerator; - function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := GetEnumerator; - - function ToString: string; override := $'{l}..{h}'; - function Equals(o: Object): boolean; override; - begin - var r2 := CharRange(o); - Result := (l = r2.l) and (h = r2.h); - end; - function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode; - {function ToArray: array of char; + function GetEnumerator: IEnumerator; + function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := GetEnumerator; + + function ToString: string; override := $'''{l}''..''{h}'''; + + function GetHashCode: integer; override := + ValueTuple.Create(l,h).GetHashCode; + + function ToArray: array of char; begin Result := new char[Count]; - var x := l; for var i := 0 to Result.Length - 1 do - begin - Result[i] := x; - x := char(integer(x) + 1); - end; - end; - function ToList: List; - begin - Result := new List; - var x := l; - loop Count do - begin - Result.Add(x); - x := char(integer(x) + 1); - end; - end;} - function ToLinkedList: LinkedList; - begin - Result := new LinkedList(System.Linq.Enumerable.Range(integer(l),GetCount).Select(i -> char(i))); - end; - function ToHashSet: HashSet; - begin - Result := new HashSet(System.Linq.Enumerable.Range(integer(l),GetCount).Select(i -> char(i))); - end; - function ToSortedSet: SortedSet; - begin - Result := new SortedSet(System.Linq.Enumerable.Range(integer(l),GetCount).Select(i -> char(i))); + Result[i] := char(integer(l)+i); end; + + public procedure CopyTo(a: array of char; arrayIndex: integer) := + for var i := 0 to System.Math.Min(self.Count, a.Length-arrayIndex) do + a[i+arrayIndex] := char(integer(l)+i); + end; /// Тип диапазона вещественных - RealRange = class - private - l,h: real; - public + RealRange = record(IEquatable) + private + l,h: real; + public constructor(l,h: real); begin Self.l := l; Self.h := h; end; + property Low: real read l; property High: real read h; - - static function operator in(x: real; r: RealRange): boolean := (x >= r.l) and (x <= r.h); - static function operator=(r1,r2: RealRange): boolean := (r1.l = r2.l) and (r1.h = r2.h); + property Size: real read h-l; + + static function operator in(x: real; r: RealRange): boolean := (x >= r.l) and (x <= r.h); + + static function operator=(r1,r2: RealRange) := + (r1.l = r2.l) and (r1.h = r2.h); + static function operator<>(r1,r2: RealRange) := not(r1=r2); + function Equals(other: RealRange) := self=other; + function Equals(o: object): boolean; override; + begin + Result := false; + if not(o is RealRange) then exit; + if self <> RealRange(o) then exit; + Result := true; + end; /// Возвращает True если диапазон пуст function IsEmpty: boolean := l>h; - + function ToString: string; override := $'{l}..{h}'; - function Equals(o: Object): boolean; override; - begin - var r2 := RealRange(o); - Result := (l = r2.l) and (h = r2.h); - end; + function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode; + end; - + ///Тип для представления индекса - SystemIndex = class - private - val: integer; - inverted: boolean; - public - property IndexValue: integer read val write val; - property IsInverted: boolean read inverted; - constructor(val: integer; inverted: boolean); - begin - Self.val := val; - Self.inverted := inverted; - end; - - static function operator implicit(i: integer): SystemIndex; - begin - Result := new SystemIndex(i, false); - end; - - function Reverse(list: List): integer; - begin - Result := list.Count - IndexValue; - end; - - function Reverse(arr: array of T): integer; - begin - Result := arr.Length - IndexValue; - end; - - function Reverse(str: string): integer; - begin - Result := str.Length - IndexValue + 1; - end; - - function Reverse0(str: string): integer; - begin - Result := str.Length - IndexValue; - end; - - function Reverse(arr: System.Array; dim: integer): integer; - begin - Result := arr.GetLength(dim) - IndexValue; - end; + SystemIndex = record + private + val: integer; + inverted: boolean; + public + property IndexValue: integer read val write val; + property IsInverted: boolean read inverted; + + constructor(val: integer; inverted: boolean); + begin + Self.val := val; + Self.inverted := inverted; + end; + + static function operator implicit(i: integer): SystemIndex := new SystemIndex(i, false); + + function Reverse(list: List): integer := list.Count - IndexValue; + + function Reverse(arr: array of T): integer := arr.Length - IndexValue; + + function Reverse0(str: string) := str.Length - IndexValue; + function Reverse(str: string) := str.Length - IndexValue + 1; + + function Reverse(arr: System.Array; dim: integer): integer := arr.GetLength(dim) - IndexValue; + end; - + //{{{doc: Начало секции интерфейса для документации }}} // ----------------------------------------------------- @@ -2454,10 +2425,6 @@ function LstInt(params a: array of integer): List; function LLst(params a: array of T): LinkedList; /// Возвращает двусвязный список, заполненный значениями из последовательности function LLst(a: sequence of T): LinkedList; -/// Возвращает двусвязный список, заполненный диапазоном значений -function LLst(a: IntRange): LinkedList; -/// Возвращает двусвязный список, заполненный диапазоном значений -function LLst(a: CharRange): LinkedList; /// Возвращает множество на базе хеш таблицы, заполненное указанными значениями function HSet(params a: array of T): HashSet; @@ -2476,10 +2443,6 @@ function HSetStr(params a: array of string): HashSet; function SSet(params a: array of T): SortedSet; /// Возвращает множество на базе бинарного дерева поиска, заполненное значениями из последовательности function SSet(a: sequence of T): SortedSet; -/// Возвращает множество на базе бинарного дерева поиска, заполненное диапазоном значений -function SSet(a: IntRange): SortedSet; -/// Возвращает множество на базе бинарного дерева поиска, заполненное диапазоном значений -function SSet(a: CharRange): SortedSet; /// Возвращает множество на базе бинарного дерева поиска, заполненное целыми значениями function SSetInt(params a: array of integer): SortedSet; /// Возвращает множество на базе бинарного дерева поиска, заполненное строковыми значениями @@ -4197,13 +4160,13 @@ begin Result := sb.ToString; end; -function IntRange.GetEnumerator(): IEnumerator := Range(l,h).GetEnumerator; +function IntRange.GetEnumerator: IEnumerator := Range(l,h).GetEnumerator; function IntRange.Step(n: integer): sequence of integer := Range(l,h,n); -function IntRange.Reverse: sequence of integer := Range(l,h).Reverse; +function IntRange.Reverse: sequence of integer := Range(h,l, -1); -function CharRange.GetEnumerator(): IEnumerator := Range(l,h).GetEnumerator; +function CharRange.GetEnumerator: IEnumerator := Range(l,h).GetEnumerator; function CharRange.Step(n: integer): sequence of char := Range(l,h,n); -function CharRange.Reverse: sequence of char := Range(l,h).Reverse; +function CharRange.Reverse: sequence of char := Range(h,l, -1); //------------------------------------------------------------------------------ // Операции для string и char @@ -5215,10 +5178,6 @@ function LLst(params a: array of T): LinkedList := new LinkedList(a); function LLst(a: sequence of T): LinkedList := new LinkedList(a); -function LLst(a: IntRange): LinkedList := a.ToLinkedList; - -function LLst(a: CharRange): LinkedList := a.ToLinkedList; - function HSet(params a: array of T): HashSet := new HashSet(a); @@ -5241,12 +5200,6 @@ function HSet(a: IntRange): HashSet := a.ToHashSet; function HSet(a: CharRange): HashSet := a.ToHashSet; - -function SSet(a: IntRange): SortedSet := a.ToSortedSet; - -function SSet(a: CharRange): SortedSet := a.ToSortedSet; - - function Dict(params pairs: array of KeyValuePair): Dictionary; begin Result := new Dictionary();