Use record's for ranges and SystemIndex
This commit is contained in:
parent
36c606fe4c
commit
4ed748de2e
|
|
@ -1,6 +0,0 @@
|
|||
begin
|
||||
var r := 1..2;
|
||||
assert(r <> nil);
|
||||
r := nil;
|
||||
assert(r = nil);
|
||||
end.
|
||||
|
|
@ -619,238 +619,209 @@ type
|
|||
|
||||
type
|
||||
/// Тип диапазона целых
|
||||
IntRange = class(IEnumerable<integer>)
|
||||
private
|
||||
l,h: integer;
|
||||
function GetCount: integer;
|
||||
begin
|
||||
Result := h-l+1;
|
||||
if Result<0 then
|
||||
Result := 0;
|
||||
end;
|
||||
public
|
||||
IntRange = record(ICollection<integer>, IReadOnlyCollection<integer>, IEquatable<IntRange>)
|
||||
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<integer>.IsReadOnly: boolean read boolean(true);
|
||||
procedure ICollection<integer>.Add(item: integer) := raise new System.InvalidOperationException;
|
||||
function ICollection<integer>.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<integer>.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<integer>;
|
||||
|
||||
function GetEnumerator: IEnumerator<integer>;
|
||||
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<integer>;
|
||||
begin
|
||||
Result := new List<integer>(Count);
|
||||
var x := l;
|
||||
loop Count do
|
||||
begin
|
||||
Result.Add(x);
|
||||
x += 1;
|
||||
end;
|
||||
end;}
|
||||
function ToLinkedList: LinkedList<integer>;
|
||||
begin
|
||||
Result := new LinkedList<integer>(System.Linq.Enumerable.Range(l,GetCount));
|
||||
end;
|
||||
function ToHashSet: HashSet<integer>;
|
||||
begin
|
||||
Result := new HashSet<integer>(System.Linq.Enumerable.Range(l,GetCount));
|
||||
end;
|
||||
function ToSortedSet: SortedSet<integer>;
|
||||
begin
|
||||
Result := new SortedSet<integer>(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<char>)
|
||||
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<char>, IReadOnlyCollection<char>, IEquatable<CharRange>)
|
||||
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<char>.IsReadOnly: boolean read boolean(true);
|
||||
procedure ICollection<char>.Add(item: char) := raise new System.InvalidOperationException;
|
||||
function ICollection<char>.Remove(item: char): boolean;
|
||||
begin
|
||||
Result := false;
|
||||
raise new System.InvalidOperationException;
|
||||
end;
|
||||
procedure ICollection<char>.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<char>;
|
||||
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<char>;
|
||||
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<char>;
|
||||
begin
|
||||
Result := new List<char>;
|
||||
var x := l;
|
||||
loop Count do
|
||||
begin
|
||||
Result.Add(x);
|
||||
x := char(integer(x) + 1);
|
||||
end;
|
||||
end;}
|
||||
function ToLinkedList: LinkedList<char>;
|
||||
begin
|
||||
Result := new LinkedList<char>(System.Linq.Enumerable.Range(integer(l),GetCount).Select(i -> char(i)));
|
||||
end;
|
||||
function ToHashSet: HashSet<char>;
|
||||
begin
|
||||
Result := new HashSet<char>(System.Linq.Enumerable.Range(integer(l),GetCount).Select(i -> char(i)));
|
||||
end;
|
||||
function ToSortedSet: SortedSet<char>;
|
||||
begin
|
||||
Result := new SortedSet<char>(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<RealRange>)
|
||||
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<T>(list: List<T>): integer;
|
||||
begin
|
||||
Result := list.Count - IndexValue;
|
||||
end;
|
||||
|
||||
function Reverse<T>(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<T>(list: List<T>): integer := list.Count - IndexValue;
|
||||
|
||||
function Reverse<T>(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<integer>;
|
|||
function LLst<T>(params a: array of T): LinkedList<T>;
|
||||
/// Возвращает двусвязный список, заполненный значениями из последовательности
|
||||
function LLst<T>(a: sequence of T): LinkedList<T>;
|
||||
/// Возвращает двусвязный список, заполненный диапазоном значений
|
||||
function LLst(a: IntRange): LinkedList<integer>;
|
||||
/// Возвращает двусвязный список, заполненный диапазоном значений
|
||||
function LLst(a: CharRange): LinkedList<char>;
|
||||
|
||||
/// Возвращает множество на базе хеш таблицы, заполненное указанными значениями
|
||||
function HSet<T>(params a: array of T): HashSet<T>;
|
||||
|
|
@ -2476,10 +2443,6 @@ function HSetStr(params a: array of string): HashSet<string>;
|
|||
function SSet<T>(params a: array of T): SortedSet<T>;
|
||||
/// Возвращает множество на базе бинарного дерева поиска, заполненное значениями из последовательности
|
||||
function SSet<T>(a: sequence of T): SortedSet<T>;
|
||||
/// Возвращает множество на базе бинарного дерева поиска, заполненное диапазоном значений
|
||||
function SSet(a: IntRange): SortedSet<integer>;
|
||||
/// Возвращает множество на базе бинарного дерева поиска, заполненное диапазоном значений
|
||||
function SSet(a: CharRange): SortedSet<char>;
|
||||
/// Возвращает множество на базе бинарного дерева поиска, заполненное целыми значениями
|
||||
function SSetInt(params a: array of integer): SortedSet<integer>;
|
||||
/// Возвращает множество на базе бинарного дерева поиска, заполненное строковыми значениями
|
||||
|
|
@ -4197,13 +4160,13 @@ begin
|
|||
Result := sb.ToString;
|
||||
end;
|
||||
|
||||
function IntRange.GetEnumerator(): IEnumerator<integer> := Range(l,h).GetEnumerator;
|
||||
function IntRange.GetEnumerator: IEnumerator<integer> := 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<char> := Range(l,h).GetEnumerator;
|
||||
function CharRange.GetEnumerator: IEnumerator<char> := 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<T>(params a: array of T): LinkedList<T> := new LinkedList<T>(a);
|
|||
|
||||
function LLst<T>(a: sequence of T): LinkedList<T> := new LinkedList<T>(a);
|
||||
|
||||
function LLst(a: IntRange): LinkedList<integer> := a.ToLinkedList;
|
||||
|
||||
function LLst(a: CharRange): LinkedList<char> := a.ToLinkedList;
|
||||
|
||||
|
||||
function HSet<T>(params a: array of T): HashSet<T> := new HashSet<T>(a);
|
||||
|
||||
|
|
@ -5241,12 +5200,6 @@ function HSet(a: IntRange): HashSet<integer> := a.ToHashSet;
|
|||
function HSet(a: CharRange): HashSet<char> := a.ToHashSet;
|
||||
|
||||
|
||||
|
||||
function SSet(a: IntRange): SortedSet<integer> := a.ToSortedSet;
|
||||
|
||||
function SSet(a: CharRange): SortedSet<char> := a.ToSortedSet;
|
||||
|
||||
|
||||
function Dict<TKey, TVal>(params pairs: array of KeyValuePair<TKey, TVal>): Dictionary<TKey, TVal>;
|
||||
begin
|
||||
Result := new Dictionary<TKey, TVal>();
|
||||
|
|
|
|||
Loading…
Reference in a new issue