diff --git a/CodeCompletion/DomSyntaxTreeVisitor.cs b/CodeCompletion/DomSyntaxTreeVisitor.cs index fc161e8cf..0cfc060f9 100644 --- a/CodeCompletion/DomSyntaxTreeVisitor.cs +++ b/CodeCompletion/DomSyntaxTreeVisitor.cs @@ -38,8 +38,9 @@ namespace CodeCompletion private bool search_all = false;//flag, iskat vse peregruzki ili tolko odnu. sdelal dlja effektivnosti. true zadaetsja tolko v visit(method_call) internal bool parse_only_interface = false; private template_type_reference converted_template_type = null; + private List pending_is_pattern_vars = new List(); - public SemanticOptions semantic_options = new SemanticOptions(); + public SemanticOptions semantic_options = new SemanticOptions(); public DomSyntaxTreeVisitor(DomConverter converter) { @@ -165,7 +166,7 @@ namespace CodeCompletion cur_scope.AddName("$block_scope",stmt_scope); stmt_scope.loc = get_location(_statement_list); cur_scope = stmt_scope; - } + } //try { foreach (statement stmt in _statement_list.subnodes) @@ -688,59 +689,131 @@ namespace CodeCompletion SymScope tmp = cur_scope; //if (_for_node.type_name != null) { - SymScope stmt_scope = new BlockScope(cur_scope); - cur_scope.AddName("$block_scope",stmt_scope); - stmt_scope.loc = get_location(_for_node); - returned_scope = null; - if (_for_node.type_name != null) - _for_node.type_name.visit(this); - if (returned_scope != null) - { - cur_scope = stmt_scope; - ElementScope es = new ElementScope(new SymInfo(_for_node.loop_variable.name, SymbolKind.Variable,_for_node.loop_variable.name),returned_scope,cur_scope); - stmt_scope.AddName(_for_node.loop_variable.name,es); - es.loc = get_location(_for_node.loop_variable); - returned_scope = null; - } - else - { - _for_node.initial_value.visit(this); - if (returned_scope != null) - { - cur_scope = stmt_scope; - if (_for_node.create_loop_variable) - { - ElementScope es = new ElementScope(new SymInfo(_for_node.loop_variable.name, SymbolKind.Variable,_for_node.loop_variable.name),returned_scope,cur_scope); - stmt_scope.AddName(_for_node.loop_variable.name,es); - es.loc = get_location(_for_node.loop_variable); - } - returned_scope = null; - } - } + SymScope stmt_scope = new BlockScope(cur_scope); + cur_scope.AddName("$block_scope", stmt_scope); + stmt_scope.loc = get_location(_for_node); + returned_scope = null; + if (_for_node.type_name != null) + _for_node.type_name.visit(this); + if (returned_scope != null) + { + cur_scope = stmt_scope; + ElementScope es = new ElementScope(new SymInfo(_for_node.loop_variable.name, SymbolKind.Variable, _for_node.loop_variable.name), returned_scope, cur_scope); + stmt_scope.AddName(_for_node.loop_variable.name, es); + es.loc = get_location(_for_node.loop_variable); + returned_scope = null; + } + else + { + _for_node.initial_value.visit(this); + if (returned_scope != null) + { + cur_scope = stmt_scope; + if (_for_node.create_loop_variable) + { + ElementScope es = new ElementScope(new SymInfo(_for_node.loop_variable.name, SymbolKind.Variable, _for_node.loop_variable.name), returned_scope, cur_scope); + stmt_scope.AddName(_for_node.loop_variable.name, es); + es.loc = get_location(_for_node.loop_variable); + } + returned_scope = null; + } + } } if (_for_node.statements != null) - _for_node.statements.visit(this); + _for_node.statements.visit(this); cur_scope = tmp; } public override void visit(PascalABCCompiler.SyntaxTree.repeat_node _repeat_node) { - if (_repeat_node.statements != null) - _repeat_node.statements.visit(this); + if (_repeat_node.statements != null) + _repeat_node.statements.visit(this); } public override void visit(PascalABCCompiler.SyntaxTree.while_node _while_node) { if (_while_node.statements != null) - _while_node.statements.visit(this); + _while_node.statements.visit(this); + } + + public override void visit(is_pattern_expr _is_pattern_expr) + { + _is_pattern_expr.right.visit(this); + } + + public override void visit(deconstructor_pattern _deconstructor_pattern) + { + _deconstructor_pattern.type.visit(this); + foreach (pattern_deconstructor_parameter pdp in _deconstructor_pattern.parameters) + { + if (pdp is var_deconstructor_parameter) + { + var_deconstructor_parameter vdp = pdp as var_deconstructor_parameter; + pending_is_pattern_vars.Add(new var_def_statement(vdp.identifier, _deconstructor_pattern.type, _deconstructor_pattern.source_context)); + } + } + } + + public override void visit(match_with _match_with) + { + if (_match_with.case_list != null) + { + foreach (pattern_case pc in _match_with.case_list.elements) + pc.visit(this); + } + + } + + public override void visit(pattern_case _pattern_case) + { + _pattern_case.pattern.visit(this); + statement stmt = merge_with_is_variables(_pattern_case.case_action); + stmt.visit(this); + } + + public void visit_is_patterns(expression expr) + { + if (expr is bin_expr) + { + bin_expr bexpr = expr as bin_expr; + visit_is_patterns(bexpr.left); + visit_is_patterns(bexpr.right); + } + else if (expr is is_pattern_expr) + expr.visit(this); + } + + public statement merge_with_is_variables(statement stmt) + { + if (pending_is_pattern_vars.Count > 0) + { + if (stmt is statement_list) + { + foreach (var_def_statement vds in pending_is_pattern_vars) + (stmt as statement_list).Insert(0, new var_statement(vds, vds.source_context)); + } + else + { + statement_list slist = new statement_list(); + slist.source_context = stmt.source_context; + foreach (var_def_statement vds in pending_is_pattern_vars) + slist.Insert(0, new var_statement(vds, vds.source_context)); + slist.Add(stmt); + stmt = slist; + } + pending_is_pattern_vars.Clear(); + } + return stmt; } public override void visit(PascalABCCompiler.SyntaxTree.if_node _if_node) { - if (_if_node.then_body != null) - _if_node.then_body.visit(this); + visit_is_patterns(_if_node.condition); + statement then_stmt = merge_with_is_variables(_if_node.then_body); + if (then_stmt != null) + then_stmt.visit(this); if (_if_node.else_body != null) - _if_node.else_body.visit(this); + _if_node.else_body.visit(this); } public override void visit(ref_type _ref_type) diff --git a/TestSuite/intellisense_tests/PABCSystem.pas b/TestSuite/intellisense_tests/PABCSystem.pas index c51deb9bf..3de7e3c01 100644 --- a/TestSuite/intellisense_tests/PABCSystem.pas +++ b/TestSuite/intellisense_tests/PABCSystem.pas @@ -5,17 +5,17 @@ /// !! System unit unit PABCSystem; - {$define PascalABC} +{$define PascalABC} {$gendoc true} // Default Application type {$apptype console} -{$reference 'System.dll'} -{$reference 'mscorlib.dll'} -{$reference 'System.Core.dll'} -{$reference 'System.Numerics.dll'} +{$reference '%GAC%\System.dll'} +{$reference '%GAC%\mscorlib.dll'} +{$reference '%GAC%\System.Core.dll'} +{$reference '%GAC%\System.Numerics.dll'} interface @@ -65,7 +65,7 @@ const Pi = 3.141592653589793; /// Константа E /// !! E constant - E = 2.718281828459045; + E = 2.718281828459045; /// Константа перехода на новую строку /// !! The newline string defined for this environment. NewLine = System.Environment.NewLine; @@ -89,13 +89,13 @@ type /// Базовый тип исключений Exception = System.Exception; - /// type double = real + /// double = real double = System.Double; - /// type longint = integer + /// longint = integer longint = System.Int32; - /// type cardinal = longword + /// cardinal = longword cardinal = System.UInt32; /// Представляет 128-битное вещественное число @@ -104,6 +104,9 @@ type /// Представляет произвольно большое целое число BigInteger = System.Numerics.BigInteger; + + /// Представляет дату и время + DateTime = System.DateTime; /// Представляет комплексное число Complex = System.Numerics.Complex; @@ -117,25 +120,26 @@ type /// Представляет базовый класс для реализации интерфейса IComparer Comparer = System.Collections.Generic.Comparer; + /// Представляет базовый класс для реализации интерфейса IComparer IComparable = System.IComparable; - + /// Представляет множество значений, реализованное на базе хеш-таблицы HashSet = System.Collections.Generic.HashSet; /// Представляет множество значений, реализованное на базе бинарного дерева поиска SortedSet = System.Collections.Generic.SortedSet; - + /// Представляет ассоциативный массив (набор пар Ключ-Значение), реализованный на базе хеш-таблицы - Dictionary = System.Collections.Generic.Dictionary; + Dictionary = System.Collections.Generic.Dictionary; /// Представляет ассоциативный массив, реализованный на базе бинарного дерева поиска - SortedDictionary = System.Collections.Generic.SortedDictionary; + SortedDictionary = System.Collections.Generic.SortedDictionary; /// Представляет ассоциативный массив (набор пар ключ-значение), реализованный на базе динамического массива пар - SortedList = System.Collections.Generic.SortedList; + SortedList = System.Collections.Generic.SortedList; /// Представляет пару Ключ-Значение для ассоциативного массива - KeyValuePair = System.Collections.Generic.KeyValuePair; + KeyValuePair = System.Collections.Generic.KeyValuePair; /// Представляет двусвязный список LinkedList = System.Collections.Generic.LinkedList; @@ -148,31 +152,31 @@ type /// Представляет стек - набор элементов, реализованных по принципу "последний вошел-первый вышел" Stack = System.Collections.Generic.Stack; - + /// Представляет интерфейс для коллекции ICollection = System.Collections.Generic.ICollection; - + /// Представляет интерфейс для сравнения двух элементов IComparer = System.Collections.Generic.IComparer; - + /// Представляет интерфейс для набора пар Ключ-Значение - IDictionary = System.Collections.Generic.IDictionary; + IDictionary = System.Collections.Generic.IDictionary; /// Представляет интерфейс, предоставляющий перечислитель для перебора элементов коллекции IEnumerable = System.Collections.Generic.IEnumerable; - + /// Представляет интерфейс для перебора элементов коллекции IEnumerator = System.Collections.Generic.IEnumerator; /// Представляет интерфейс для поддержки сравнения на равенство IEqualityComparer = System.Collections.Generic.IEqualityComparer; - + /// Представляет интерфейс для коллекции с доступом по индексу IList = System.Collections.Generic.IList; - + /// Представляет интерфейс для множества ISet = System.Collections.Generic.ISet; - + /// Представляет изменяемую строку символов StringBuilder = System.Text.StringBuilder; @@ -184,52 +188,52 @@ type /// Представляет действие с одним параметром Action = System.Action; - + /// Представляет действие с двумя параметрами - Action2 = System.Action; - + Action2 = System.Action; + /// Представляет действие с тремя параметрами - Action3 = System.Action; - + Action3 = System.Action; + /// Представляет функцию без параметров Func0 = System.Func; - + /// Представляет функцию с одним параметром - Func = System.Func; - + Func = System.Func; + /// Представляет функцию с двумя параметрами - Func2 = System.Func; - + Func2 = System.Func; + /// Представляет функцию с тремя параметрами - Func3 = System.Func; + Func3 = System.Func; /// Представляет функцию с одним параметром целого типа, возвращающую целое - IntFunc = Func; + IntFunc = Func; /// Представляет функцию с одним параметром вещественного типа, возвращающую вещественное - RealFunc = Func; + RealFunc = Func; /// Представляет функцию с одним параметром строкового типа, возвращающую строку - StringFunc = Func; - + StringFunc = Func; + /// Представляет функцию с одним параметром, возвращающую boolean Predicate = System.Predicate; - + /// Представляет функцию с двумя параметрами, возвращающую boolean - Predicate2 = function(x1: T1; x2: T2): boolean; - + Predicate2 = function(x1: T1; x2: T2): boolean; + /// Представляет функцию с тремя параметрами, возвращающую boolean - Predicate3 = function(x1: T1; x2: T2; x3: T3): boolean; + Predicate3 = function(x1: T1; x2: T2; x3: T3): boolean; /// Представляет регулярное выражение Regex = System.Text.RegularExpressions.Regex; - + /// Представляет результаты из отдельного совпадения регулярного выражения &Match = System.Text.RegularExpressions.&Match; - + /// Представляет метод, вызываемый при обнаружении совпадения в Regex.Replace MatchEvaluator = System.Text.RegularExpressions.MatchEvaluator; - + /// Представляет набор успешных совпадений регулярного выражения MatchCollection = System.Text.RegularExpressions.MatchCollection; @@ -244,37 +248,37 @@ type /// Представляет тип короткой строки фиксированной длины 255 символов ShortString = string[255]; - -//{{{--doc: Конец секции стандартных типов для документации }}} - -//------------------------------------------------------------------------------ -//Pointers -//------------------------------------------------------------------------------ - //1 //pointed to - PBoolean = ^boolean;//bool - PByte = ^byte;//byte - PShortint = ^shortint;//sbyte - //2 - PChar = ^char;//char - PSmallint = ^smallint;//short - PWord = ^word;//ushort - //4 - PPointer = ^pointer;//void* - PInteger = ^integer;//int32 - PLongword = ^longword;//uint32 - PLongint = ^longint;//int64 - //8 - PInt64 = ^int64; - PUInt64 = ^uint64;//unit64 + //{{{--doc: Конец секции стандартных типов для документации }}} - //8 - PSingle = ^single;//single - //16 - PReal = ^real;//double - PDouble = ^double;//double //ошибка, не сохранится, надо исправить + //------------------------------------------------------------------------------ + //Pointers //------------------------------------------------------------------------------ + //1 //pointed to + PBoolean = ^boolean;//bool + PByte = ^byte;//byte + PShortint = ^shortint;//sbyte + //2 + PChar = ^char;//char + PSmallint = ^smallint;//short + PWord = ^word;//ushort + //4 + PPointer = ^pointer;//void* + PInteger = ^integer;//int32 + PLongword = ^longword;//uint32 + PLongint = ^longint;//int64 + //8 + PInt64 = ^int64; + PUInt64 = ^uint64;//unit64 + + //8 + PSingle = ^single;//single + //16 + PReal = ^real;//double + PDouble = ^double;//double //ошибка, не сохранится, надо исправить + //------------------------------------------------------------------------------ + // ----------------------------------------------------- // IOSystem interface & IOStandardSystem implementation // ----------------------------------------------------- @@ -307,27 +311,27 @@ type state := 0; // 0 - нет символа в буфере char, 1 - есть символ в буфере char sym: integer; // буфер в 1 символ для моделирования Peek в консоли public - function peek: integer; virtual; // использует state и sym - function read_symbol: char; virtual; // использует state и sym - procedure read(var x: integer); virtual; - procedure read(var x: real); virtual; - procedure read(var x: char); virtual; - procedure read(var x: string); virtual; - procedure read(var x: byte); virtual; + function peek: integer; virtual;// использует state и sym + function read_symbol: char; virtual;// использует state и sym + procedure read(var x: integer); virtual; + procedure read(var x: real); virtual; + procedure read(var x: char); virtual; + procedure read(var x: string); virtual; + procedure read(var x: byte); virtual; procedure read(var x: shortint); virtual; procedure read(var x: smallint); virtual; - procedure read(var x: word); virtual; + procedure read(var x: word); virtual; procedure read(var x: longword); virtual; - procedure read(var x: int64); virtual; - procedure read(var x: uint64); virtual; - procedure read(var x: single); virtual; - procedure read(var x: boolean); virtual; - procedure readln; virtual; - procedure write(p: pointer); virtual; - procedure write(obj: object); virtual; - procedure writeln; virtual; + procedure read(var x: int64); virtual; + procedure read(var x: uint64); virtual; + procedure read(var x: single); virtual; + procedure read(var x: boolean); virtual; + procedure readln; virtual; + procedure write(p: pointer); virtual; + procedure write(obj: object); virtual; + procedure writeln; virtual; end; - + // ----------------------------------------------------- // Classes for files & typed sets // ----------------------------------------------------- @@ -359,6 +363,8 @@ type function ReadlnString: string; /// Возвращает значение типа boolean, введенное из текстового файла, и переходит на следующую строку function ReadlnBoolean: boolean; + /// Переходит в файле на следующую строку + procedure Readln; /// Записывает в текстовый файл значения procedure Write(params o: array of Object); /// Записывает в текстовый файл значения и переходит на следующую строку @@ -385,12 +391,14 @@ type function FullName: string; /// Возвращает в виде строки содержимое файла от текущего положения до конца function ReadToEnd: string; + /// Устанавливает файловый указатель на начало файла + procedure Reset; end; /// Тип текстового файла TextFile = Text; - -type + +type // Вспомогательный тип для диапазонного типа ///-- Diapason = record @@ -399,13 +407,13 @@ type constructor(_low, _high: integer); constructor(_low, _high: object); end; - + ///-- {TypedSetComparer = class(System.Collections.IEqualityComparer) public function Equals(x: System.Object; y: System.Object): boolean; public function GetHashCode(obj: System.Object): integer; end;} - + type // Вспомогательный тип для множества ///-- @@ -449,8 +457,8 @@ type end; type -// Base class for typed and binary files -///-- + // Base class for typed and binary files + ///-- AbstractBinaryFile = class private fi: FileInfo; @@ -468,11 +476,17 @@ type procedure Erase; /// Переименовывает файл, давая ему имя newname procedure Rename(newname: string); - ///- Write(f: file; a,b,...) + ///- f.Write(a,b,...) /// Выводит значения a,b,... в двоичный файл procedure Write(params vals: array of object); + /// Устанавливает файловый указатель на начало файла + procedure Reset; + /// Возвращает имя файла + function Name: string; + /// Возвращает полное имя файла + function FullName: string; end; - + // Class for typed files ///-- TypedFile = sealed class(AbstractBinaryFile) @@ -489,8 +503,6 @@ type function FilePos: int64; /// Возвращает количество элементов в типизированном файле function FileSize: int64; - /// Устанавливает текущую позицию файлового указателя в типизированном файле на элемент с номером n - procedure Seek(n: int64); end; // Class for binary files @@ -505,7 +517,7 @@ type /// Устанавливает текущую позицию файлового указателя в бестиповом файле на байт с номером n procedure Seek(n: int64); end; - + //{{{doc: Начало секции интерфейса для документации }}} // ----------------------------------------------------- @@ -544,6 +556,27 @@ procedure Read(var x: boolean); /// Вводит значения a,b,... с клавиатуры и осуществляет переход на следующую строку procedure Readln; +/// Вводит числовое значение x клавиатуры. Возвращает False если при вводе произошла ошибка +function TryRead(var x: integer): boolean; +///-- +function TryRead(var x: real): boolean; +///-- +function TryRead(var x: byte): boolean; +///-- +function TryRead(var x: shortint): boolean; +///-- +function TryRead(var x: smallint): boolean; +///-- +function TryRead(var x: word): boolean; +///-- +function TryRead(var x: longword): boolean; +///-- +function TryRead(var x: int64): boolean; +///-- +function TryRead(var x: uint64): boolean; +///-- +function TryRead(var x: single): boolean; + /// Возвращает значение типа integer, введенное с клавиатуры function ReadInteger: integer; /// Возвращает значение типа real, введенное с клавиатуры @@ -566,6 +599,75 @@ function ReadlnString: string; /// Возвращает значение типа boolean, введенное с клавиатуры, и переходит на следующую строку ввода function ReadlnBoolean: boolean; +/// Возвращает кортеж из двух значений типа integer, введенных с клавиатуры +function ReadInteger2: (integer, integer); +/// Возвращает кортеж из двух значений типа real, введенных с клавиатуры +function ReadReal2: (real, real); +/// Возвращает кортеж из двух значений типа char, введенных с клавиатуры +function ReadChar2: (char, char); +/// Возвращает кортеж из двух значений типа string, введенных с клавиатуры +function ReadString2: (string, string); +/// Возвращает кортеж из двух значений типа integer, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnInteger2: (integer, integer); +/// Возвращает кортеж из двух значений типа real, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnReal2: (real, real); +/// Возвращает кортеж из двух значений типа char, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnChar2: (char, char); +/// Возвращает кортеж из двух значений типа string, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnString2: (string, string); + +/// Возвращает кортеж из трёх значений типа integer, введенных с клавиатуры +function ReadInteger3: (integer, integer, integer); +/// Возвращает кортеж из трёх значений типа real, введенных с клавиатуры +function ReadReal3: (real, real, real); +/// Возвращает кортеж из трёх значений типа char, введенных с клавиатуры +function ReadChar3: (char, char, char); +/// Возвращает кортеж из трёх значений типа string, введенных с клавиатуры +function ReadString3: (string, string, string); +/// Возвращает кортеж из двух значений типа integer, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnInteger3: (integer, integer, integer); +/// Возвращает кортеж из двух значений типа real, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnReal3: (real, real, real); +/// Возвращает кортеж из двух значений типа char, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnChar3: (char, char, char); +/// Возвращает кортеж из двух значений типа string, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnString3: (string, string, string); + +/// Возвращает кортеж из двух значений типа integer, введенных с клавиатуры +function ReadInteger2(prompt: string): (integer, integer); +/// Возвращает кортеж из двух значений типа real, введенных с клавиатуры +function ReadReal2(prompt: string): (real, real); +/// Возвращает кортеж из двух значений типа char, введенных с клавиатуры +function ReadChar2(prompt: string): (char, char); +/// Возвращает кортеж из двух значений типа string, введенных с клавиатуры +function ReadString2(prompt: string): (string, string); +/// Возвращает кортеж из двух значений типа integer, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnInteger2(prompt: string): (integer, integer); +/// Возвращает кортеж из двух значений типа real, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnReal2(prompt: string): (real, real); +/// Возвращает кортеж из двух значений типа char, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnChar2(prompt: string): (char, char); +/// Возвращает кортеж из двух значений типа string, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnString2(prompt: string): (string, string); + +/// Возвращает кортеж из трёх значений типа integer, введенных с клавиатуры +function ReadInteger3(prompt: string): (integer, integer, integer); +/// Возвращает кортеж из трёх значений типа real, введенных с клавиатуры +function ReadReal3(prompt: string): (real, real, real); +/// Возвращает кортеж из трёх значений типа char, введенных с клавиатуры +function ReadChar3(prompt: string): (char, char, char); +/// Возвращает кортеж из трёх значений типа string, введенных с клавиатуры +function ReadString3(prompt: string): (string, string, string); +/// Возвращает кортеж из двух значений типа integer, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnInteger3(prompt: string): (integer, integer, integer); +/// Возвращает кортеж из двух значений типа real, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnReal3(prompt: string): (real, real, real); +/// Возвращает кортеж из двух значений типа char, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnChar3(prompt: string): (char, char, char); +/// Возвращает кортеж из двух значений типа string, введенных с клавиатуры, и переходит на следующую строку ввода +function ReadlnString3(prompt: string): (string, string, string); + + /// Выводит приглашение к вводу и возвращает значение типа integer, введенное с клавиатуры function ReadInteger(prompt: string): integer; /// Выводит приглашение к вводу и возвращает значение типа real, введенное с клавиатуры @@ -939,7 +1041,7 @@ function GetCurrentDir: string; function RemoveDir(s: string): boolean; /// Переименовывает файл name, давая ему новое имя newname. Возвращает True, если файл успешно переименован function RenameFile(name, newname: string): boolean; -/// Устанавивает текущий каталог. Возвращает True, если каталог успешно удален +/// Устанавливает текущий каталог. Возвращает True, если каталог успешно удален function SetCurrentDir(s: string): boolean; /// Изменяет расширение файла с именем name на newext @@ -1057,6 +1159,8 @@ function Abs(x: int64): int64; function Abs(x: uint64): uint64; ///-- function Abs(x: real): real; +///-- +function Abs(x: single): single; /// Возвращает синус числа x function Sin(x: real): real; /// Возвращает гиперболический синус числа x @@ -1080,6 +1184,8 @@ function ArcTan(x: real): real; function Exp(x: real): real; /// Возвращает натуральный логарифм числа x function Ln(x: real): real; +/// Возвращает натуральный логарифм числа x +function Log(x: real): real; /// Возвращает логарифм числа x по основанию 2 function Log2(x: real): real; /// Возвращает десятичный логарифм числа x @@ -1107,13 +1213,15 @@ function Sqr(x: uint64): uint64; function Sqr(x: real): real; /// Возвращает x в степени y function Power(x, y: real): real; -/// Возвращает x в степени y -function Power(x, y: integer): real; +/// Возвращает x в целой степени n +function Power(x: real; n: integer): real; /// Возвращает x в степени y function Power(x: BigInteger; y: integer): BigInteger; /// Возвращает x, округленное до ближайшего целого. Если вещественное находится посередине между двумя целыми, ///то округление осуществляется к ближайшему четному (банковское округление): Round(2.5)=2, Round(3.5)=4 function Round(x: real): integer; +/// Возвращает x, округленное до ближайшего вещественного с digits знаками после десятичной точки +function Round(x: real; digits: integer): real; /// Возвращает x, округленное до ближайшего длинного целого function RoundBigInteger(x: real): BigInteger; /// Возвращает целую часть вещественного числа x @@ -1143,6 +1251,18 @@ function Random(maxValue: integer): integer; function Random(a, b: integer): integer; /// Возвращает случайное вещественное в диапазоне [0..1) function Random: real; +/// Возвращает кортеж из двух случайных целых в диапазоне от 0 до maxValue-1 +function Random2(maxValue: integer): (integer, integer); +/// Возвращает кортеж из двух случайных целых в диапазоне от a до b +function Random2(a, b: integer): (integer, integer); +/// Возвращает кортеж из двух случайных вещественных в диапазоне [0..1) +function Random2: (real, real); +/// Возвращает кортеж из трех случайных целых в диапазоне от 0 до maxValue-1 +function Random3(maxValue: integer): (integer, integer, integer); +/// Возвращает кортеж из трех случайных целых в диапазоне от a до b +function Random3(a, b: integer): (integer, integer, integer); +/// Возвращает кортеж из трех случайных вещественных в диапазоне [0..1) +function Random3: (real, real, real); ///-function Max(a: число, b: число): число; /// Возвращает максимальное из чисел a,b @@ -1210,9 +1330,29 @@ function Odd(i: uint64): boolean; //>> Функции для работы с комплексными числами # Functions for Complex numbers // ----------------------------------------------------- /// Конструирует комплексное число с вещественной частью re и мнимой частью im -function Cplx(re,im: real): Complex; -/// Вычисляет квадратный корень из комплексного числа +function Cplx(re, im: real): Complex; +/// Конструирует комплексное число по полярным координатам +function CplxFromPolar(magnitude, phase: real): Complex; +/// Возвращает квадратный корень из комплексного числа function Sqrt(c: Complex): Complex; +/// Возвращает модуль комплексного числа +function Abs(c: Complex): Complex; +/// Возвращает комплексно сопряженное число +function Conjugate(c: Complex): Complex; +/// Возвращает косинус комплексного числа +function Cos(c: Complex): Complex; +/// Возвращает экспоненту комплексного числа +function Exp(c: Complex): Complex; +/// Возвращает натуральный логарифм комплексного числа +function Ln(c: Complex): Complex; +/// Возвращает натуральный логарифм комплексного числа +function Log(c: Complex): Complex; +/// Возвращает десятичный логарифм комплексного числа +function Log10(c: Complex): Complex; +/// Возвращает степень комплексного числа +function Power(c, power: Complex): Complex; +/// Возвращает синус комплексного числа +function Sin(c: Complex): Complex; // ----------------------------------------------------- //>> Процедуры для работы со стандартными множествами # Subroutines for set of T @@ -1522,8 +1662,12 @@ procedure Sort(l: List; cmp: (T,T)->integer); procedure Sort(l: List; less: (T,T)->boolean); /// Изменяет порядок элементов в динамическом массиве на противоположный procedure Reverse(a: array of T); -/// Изменяет порядок элементов на противоположный в диапазоне динамического массива длины length начиная с индекса index -procedure Reverse(a: array of T; index,length: integer); +/// Изменяет порядок элементов на противоположный в диапазоне динамического массива длины count, начиная с индекса index +procedure Reverse(a: array of T; index, count: integer); +/// Изменяет порядок элементов в списке на противоположный +procedure Reverse(a: List); +/// Изменяет порядок элементов на противоположный в диапазоне списка длины count, начиная с индекса index +procedure Reverse(a: List; index, count: integer); /// Перемешивает динамический массив случайным образом procedure Shuffle(a: array of T); /// Перемешивает список случайным образом @@ -1533,15 +1677,15 @@ procedure Shuffle(l: List); //>> Подпрограммы для генерации последовательностей # Subroutines for sequence generation // ----------------------------------------------------- /// Возвращает последовательность целых от a до b -function Range(a,b: integer): sequence of integer; +function Range(a, b: integer): sequence of integer; /// Возвращает последовательность символов от c1 до c2 -function Range(c1,c2: char): sequence of char; +function Range(c1, c2: char): sequence of char; /// Возвращает последовательность вещественных в точках разбиения отрезка [a,b] на n равных частей (Используйте Partition) -function Range(a,b: real; n: integer): sequence of real; +function Range(a, b: real; n: integer): sequence of real; /// Возвращает последовательность вещественных в точках разбиения отрезка [a,b] на n равных частей -function Partition(a,b: real; n: integer): sequence of real; +function Partition(a, b: real; n: integer): sequence of real; /// Возвращает последовательность целых от a до b с шагом step -function Range(a,b,step: integer): sequence of integer; +function Range(a, b, step: integer): sequence of integer; /// Возвращает последовательность указанных элементов function Seq(params a: array of T): sequence of T; /// Возвращает последовательность из n случайных целых элементов @@ -1551,20 +1695,20 @@ function SeqRandomInteger(n: integer := 10; a: integer := 0; b: integer := 100): /// Возвращает последовательность из n случайных вещественных элементов function SeqRandomReal(n: integer := 10; a: real := 0; b: real := 10): sequence of real; /// Возвращает последовательность из count элементов, заполненных значениями f(i) -function SeqGen(count: integer; f: integer -> T): sequence of T; +function SeqGen(count: integer; f: integer->T): sequence of T; /// Возвращает последовательность из count элементов, заполненных значениями f(i), начиная с i=from -function SeqGen(count: integer; f: integer -> T; from: integer): sequence of T; +function SeqGen(count: integer; f: integer->T; from: integer): sequence of T; /// Возвращает последовательность из count элементов, начинающуюся с first, с функцией next перехода от предыдущего к следующему -function SeqGen(count: integer; first: T; next: T -> T): sequence of T; +function SeqGen(count: integer; first: T; next: T->T): sequence of T; /// Возвращает последовательность из count элементов, начинающуюся с first и second, ///с функцией next перехода от двух предыдущих к следующему -function SeqGen(count: integer; first,second: T; next: (T,T) -> T): sequence of T; +function SeqGen(count: integer; first, second: T; next: (T,T) ->T): sequence of T; /// Возвращает последовательность элементов с начальным значением first, ///функцией next перехода от предыдущего к следующему и условием pred продолжения последовательности -function SeqWhile(first: T; next: T -> T; pred: T -> boolean): sequence of T; +function SeqWhile(first: T; next: T->T; pred: T->boolean): sequence of T; /// Возвращает последовательность элементов, начинающуюся с first и second, ///с функцией next перехода от двух предыдущих к следующему и условием pred продолжения последовательности -function SeqWhile(first,second: T; next: (T,T) -> T; pred: T -> boolean): sequence of T; +function SeqWhile(first, second: T; next: (T,T) ->T; pred: T->boolean): sequence of T; /// Возвращает последовательность из count элементов x function SeqFill(count: integer; x: T): sequence of T; @@ -1576,25 +1720,25 @@ function ReadSeqReal(n: integer): sequence of real; function ReadSeqString(n: integer): sequence of string; /// Выводит приглашение к вводу и возвращает последовательность из n целых, введенных с клавиатуры -function ReadSeqInteger(const prompt: string; n: integer): sequence of integer; +function ReadSeqInteger(prompt: string; n: integer): sequence of integer; /// Выводит приглашение к вводу и возвращает последовательность из n вещественных, введенных с клавиатуры -function ReadSeqReal(const prompt: string; n: integer): sequence of real; +function ReadSeqReal(prompt: string; n: integer): sequence of real; /// Выводит приглашение к вводу и возвращает последовательность из n строк, введенных с клавиатуры -function ReadSeqString(const prompt: string; n: integer): sequence of string; +function ReadSeqString(prompt: string; n: integer): sequence of string; /// Возвращает последовательность целых, вводимых с клавиатуры пока выполняется определенное условие -function ReadSeqIntegerWhile(cond: integer -> boolean): sequence of integer; +function ReadSeqIntegerWhile(cond: integer->boolean): sequence of integer; /// Возвращает последовательность вещественных, вводимых с клавиатуры пока выполняется определенное условие -function ReadSeqRealWhile(cond: real -> boolean): sequence of real; +function ReadSeqRealWhile(cond: real->boolean): sequence of real; /// Возвращает последовательность строк, вводимых с клавиатуры пока выполняется определенное условие -function ReadSeqStringWhile(cond: string -> boolean): sequence of string; +function ReadSeqStringWhile(cond: string->boolean): sequence of string; /// Выводит приглашение к вводу и возвращает последовательность целых, вводимых с клавиатуры пока выполняется определенное условие -function ReadSeqIntegerWhile(const prompt: string; cond: integer -> boolean): sequence of integer; +function ReadSeqIntegerWhile(prompt: string; cond: integer->boolean): sequence of integer; /// Выводит приглашение к вводу и возвращает последовательность вещественных, вводимых с клавиатуры пока выполняется определенное условие -function ReadSeqRealWhile(const prompt: string; cond: real -> boolean): sequence of real; +function ReadSeqRealWhile(prompt: string; cond: real->boolean): sequence of real; /// Выводит приглашение к вводу и возвращает последовательность строк, вводимых с клавиатуры пока выполняется определенное условие -function ReadSeqStringWhile(const prompt: string; cond: string -> boolean): sequence of string; +function ReadSeqStringWhile(prompt: string; cond: string->boolean): sequence of string; // ----------------------------------------------------- //>> Подпрограммы для генерации динамических массивов # Subroutines for array of T generation @@ -1610,13 +1754,13 @@ function ArrRandomInteger(n: integer := 10; a: integer := 0; b: integer := 100): /// Возвращает массив размера n, заполненный случайными вещественными значениями function ArrRandomReal(n: integer := 10; a: real := 0; b: real := 10): array of real; /// Возвращает массив из count элементов, заполненных значениями gen(i) -function ArrGen(count: integer; gen: integer -> T): array of T; +function ArrGen(count: integer; gen: integer->T): array of T; /// Возвращает массив из count элементов, заполненных значениями gen(i), начиная с i=from -function ArrGen(count: integer; gen: integer -> T; from: integer): array of T; +function ArrGen(count: integer; gen: integer->T; from: integer): array of T; /// Возвращает массив из count элементов, начинающихся с first, с функцией next перехода от предыдущего к следующему -function ArrGen(count: integer; first: T; next: T -> T): array of T; +function ArrGen(count: integer; first: T; next: T->T): array of T; /// Возвращает массив из count элементов, начинающихся с first и second, с функцией next перехода от двух предыдущих к следующему -function ArrGen(count: integer; first,second: T; next: (T,T) -> T): array of T; +function ArrGen(count: integer; first, second: T; next: (T,T) ->T): array of T; /// Возвращает массив из count элементов x function ArrFill(count: integer; x: T): array of T; @@ -1628,11 +1772,11 @@ function ReadArrReal(n: integer): array of real; function ReadArrString(n: integer): array of string; /// Выводит приглашение к вводу и возвращает массив из n целых, введенных с клавиатуры -function ReadArrInteger(const prompt: string; n: integer): array of integer; +function ReadArrInteger(prompt: string; n: integer): array of integer; /// Выводит приглашение к вводу и возвращает массив из n вещественных, введенных с клавиатуры -function ReadArrReal(const prompt: string; n: integer): array of real; +function ReadArrReal(prompt: string; n: integer): array of real; /// Выводит приглашение к вводу и возвращает массив из n строк, введенных с клавиатуры -function ReadArrString(const prompt: string; n: integer): array of string; +function ReadArrString(prompt: string; n: integer): array of string; // ----------------------------------------------------- //>> Подпрограммы для матриц # Subroutines for matrixes @@ -1644,28 +1788,33 @@ function MatrRandomInteger(m: integer := 5; n: integer := 5; a: integer := 0; b: /// Возвращает двумерный массив размера m x n, заполненный случайными вещественными значениями function MatrRandomReal(m: integer := 5; n: integer := 5; a: real := 0; b: real := 10): array [,] of real; /// Возвращает двумерный массив размера m x n, заполненный элементами x -function MatrFill(m,n: integer; x: T): array [,] of T; +function MatrFill(m, n: integer; x: T): array [,] of T; /// Возвращает двумерный массив размера m x n, заполненный элементами x -function MatrGen(m,n: integer; gen: (integer,integer)->T): array [,] of T; +function MatrGen(m, n: integer; gen: (integer,integer)->T): array [,] of T; /// Транспонирует двумерный массив function Transpose(a: array [,] of T): array [,] of T; +/// Возвращает матрицу m на n целых, введенных с клавиатуры +function ReadMatrInteger(m, n: integer): array [,] of integer; +/// Возвращает матрицу m на n вещественных, введенных с клавиатуры +function ReadMatrReal(m, n: integer): array [,] of real; + // ----------------------------------------------------- //>> Подпрограммы для создания кортежей # Subroutines for tuple generation // ----------------------------------------------------- ///- function Rec(x1: T1, x2: T2,...): (T1,T2,...); /// Возвращает кортеж из элементов разных типов -function Rec(x1: T1; x2: T2): System.Tuple; +function Rec(x1: T1; x2: T2): System.Tuple; ///-- -function Rec(x1: T1; x2: T2; x3: T3): (T1,T2,T3); +function Rec(x1: T1; x2: T2; x3: T3): (T1, T2, T3); ///-- -function Rec(x1: T1; x2: T2; x3: T3; x4: T4): (T1,T2,T3,T4); +function Rec(x1: T1; x2: T2; x3: T3; x4: T4): (T1, T2, T3, T4); ///-- -function Rec(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5): (T1,T2,T3,T4,T5); +function Rec(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5): (T1, T2, T3, T4, T5); ///-- -function Rec(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5; x6: T6): (T1,T2,T3,T4,T5,T6); +function Rec(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5; x6: T6): (T1, T2, T3, T4, T5, T6); ///-- -function Rec(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5; x6: T6; x7: T7): (T1,T2,T3,T4,T5,T6,T7); +function Rec(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5; x6: T6; x7: T7): (T1, T2, T3, T4, T5, T6, T7); // ----------------------------------------------------- //>> Короткие функции Lst, LLst, HSet, SSet, Dict, KV # Short functions Lst, HSet, SSet, Dict, KV @@ -1688,9 +1837,17 @@ function SSet(params a: array of T): SortedSet; function SSet(a: sequence of T): SortedSet; /// Возвращает словарь пар элементов (ключ, значение) function Dict(params pairs: array of KeyValuePair): Dictionary; +/// Возвращает словарь пар элементов (ключ, значение) +function Dict(params pairs: array of (TKey, TVal)): Dictionary; /// Возвращает пару элементов (ключ, значение) function KV(key: TKey; value: TVal): KeyValuePair; +// ----------------------------------------------------- +//>> Вспомогательные функции для pattern matching +// ----------------------------------------------------- + +function __TypeCheckAndAssignForIsMatch(obj: object; var res: T): boolean; + //{{{--doc: Конец секции интерфейса для документации }}} @@ -1723,16 +1880,16 @@ type public function ToString: string; override; end; - + RangeException = class(SystemException) end; CommandLineArgumentOutOfRangeException = class(SystemException) end; - + // ----------------------------------------------------- // Общедоступные переменные // ----------------------------------------------------- var -/// Содержит аргумены командой строки, с которыми была запущена программа + /// Содержит аргумены командой строки, с которыми была запущена программа CommandLineArgs: array of string; /// Стандартный текстовый файл для вывода. Связывается процедурой Assign с файлом на диске, после чего весь вывод на консоль перенаправляется в этот файл output: TextFile; @@ -1820,7 +1977,8 @@ procedure omp_set_nested(nested: integer); ///-- function omp_get_nested: integer; ///-- -var OMP_NESTED: boolean := false; +var + OMP_NESTED: boolean := false; // ----------------------------------------------------- // Internal typed sets operations @@ -1877,7 +2035,7 @@ procedure TypedSetInitWithShortString(var st: TypedSet; len: integer); // ----------------------------------------------------- // Internal classes // ----------------------------------------------------- -type +type ///-- GCHandlersController = class(System.Collections.IEnumerable) private @@ -1889,7 +2047,7 @@ type function GetCounter(obj: Object): integer; function GetEnumerator: System.Collections.IEnumerator; end; - + type ///-- PointerOutput = class @@ -1899,6 +2057,67 @@ type constructor(ptr: pointer); end; +type + ///-- + __ConceptSingleton = class where T: constructor; + class _instance: T; + class inited: boolean := false; + public + class function &Instance: T; + begin + if inited = false then + begin + inited := true; + _instance := new T; + end; + + Result := _instance; + end; + end; + + +type + ///-- + __TypeclassRestrictedFunctionAttribute = class(Attribute) + public + constructor; + begin + end; + end; + + + ///-- + __TypeclassGenericParameterAttribute = class(Attribute) + public + constructor(instanceName: string); + begin + end; + end; + + ///-- + __TypeclassAttribute = class(Attribute) + public + constructor(typeclassName: string); + begin + end; + end; + + ///-- + __TypeclassMemberAttribute = class(Attribute) + public + constructor; + begin + end; + end; + + ///-- + __TypeclassInstanceAttribute = class(Attribute) + public + constructor(instanceName: string); + begin + end; + end; + // ----------------------------------------------------- // Internal procedures for PABCRTL.dll // ----------------------------------------------------- @@ -1909,18 +2128,24 @@ procedure __InitPABCSystem; ///-- procedure __FinalizeModule__; +// ----------------------------------------------------- +// DQNToNullable for dot_question_node +// ----------------------------------------------------- + +function DQNToNullable(v: integer): Nullable; + implementation var - rnd: System.Random; + rnd := new System.Random; // ENCultureInfo: System.Globalization.CultureInfo; nfi: System.Globalization.NumberFormatInfo; LastReadChar := #0; AnsiOrdChrEncoding := Encoding.GetEncoding(1251); __one_char := new char[1]; __one_byte := new byte[1]; - StartTime: DateTime; // Для Milliseconds - + StartTime: DateTime;// Для Milliseconds + const WRITELN_IN_BINARYFILE_ERROR_MESSAGE = 'Операция Writeln не применима к бинарным файлам!!Writeln is not applicable to binary files'; InternalNullBasedArrayName = 'NullBasedArray'; @@ -1940,6 +2165,7 @@ const PARAMETER_STEP_MUST_BE_GREATER_0 = 'Параметр step должен быть > 0!!The step parameter must be not greater than 0'; PARAMETER_FROM_OUT_OF_RANGE = 'Параметр from за пределами диапазона!!The from parameter out of bounds'; PARAMETER_TO_OUT_OF_RANGE = 'Параметр to за пределами диапазона!!The to parameter out of bounds'; + ARR_LENGTH_MUST_BE_MATCH_TO_MATR_SIZE = 'Размер одномерного массива не согласован с размером двумерного массива!!The 1-dim array length does not match 2-dim array size'; // ----------------------------------------------------- // WINAPI @@ -1947,7 +2173,8 @@ const function WINAPI_AllocConsole: longword; external 'kernel32.dll' name 'AllocConsole'; -var console_alloc: boolean := false; +var + console_alloc: boolean := false; // ----------------------------------------------------- // Internal functions @@ -1960,12 +2187,12 @@ begin Result := locale as string else Result := 'ru'; -end; +end; function GetTranslation(message: string): string; begin var cur_locale := GetCurrentLocale(); - var arr := message.Split(new string[1]('!!'),StringSplitOptions.None); + var arr := message.Split(new string[1]('!!'), StringSplitOptions.None); if (cur_locale = 'en') and (arr.Length > 1) then Result := arr[1] else @@ -2064,12 +2291,12 @@ end; // ----------------------------------------------------- constructor Diapason.Create(_low, _high: integer); begin - low := _low; high := _high; + low := _low;high := _high; end; constructor Diapason.Create(_low, _high: object); begin - clow := _low; chigh := _high; + clow := _low;chigh := _high; end; // ----------------------------------------------------- @@ -2277,7 +2504,7 @@ begin else Result := true; end; -function convert_elem(obj: object): object; // для TypedSet +function convert_elem(obj: object): object;// для TypedSet begin var t := obj.GetType; if t.IsEnum then @@ -2486,9 +2713,9 @@ end; class function TypedSet.operator implicit(s: TypedSet): HashSet; begin var hs := new HashSet(); - foreach key: T in s.ht.Keys do + foreach var key in s.ht.Keys do begin - hs.Add(key); + hs.Add(T(key)); end; Result := hs; end; @@ -2894,18 +3121,12 @@ begin end; end; -function TypedFile.ToString: string; -begin - Result := string.Format('file of {0}', ElementType); -end; +function TypedFile.ToString := Format('file of {0}', ElementType); // ----------------------------------------------------- // BinaryFile // ----------------------------------------------------- -function BinaryFile.ToString: string; -begin - Result := 'file'; -end; +function BinaryFile.ToString: string := 'file'; // ----------------------------------------------------- // GCHandlersController @@ -2972,16 +3193,16 @@ function RedefinedToString(o: object): System.Reflection.MethodInfo; begin var t := o.GetType; var meth: System.Reflection.MethodInfo := nil; - while t<>typeof(Object) do + while t <> typeof(Object) do begin - meth := t.GetMethod('ToString',System.Reflection.BindingFlags.Public or - System.Reflection.BindingFlags.Instance or - System.Reflection.BindingFlags.DeclaredOnly,nil,new System.Type[0],nil); - if meth<>nil then + meth := t.GetMethod('ToString', System.Reflection.BindingFlags.Public or + System.Reflection.BindingFlags.&Instance or + System.Reflection.BindingFlags.DeclaredOnly, nil, new System.Type[0], nil); + if meth <> nil then break; t := t.BaseType; end; - if (t=typeof(Object)) or (t=typeof(System.ValueType)) then + if (t = typeof(Object)) or (t = typeof(System.ValueType)) then Result := nil else Result := meth; end; @@ -2989,55 +3210,55 @@ end; function ArrNToString(a: System.Array; indexes: array of integer; i: integer): string; forward; function StructuredObjectToString(o: Object; n: integer := 0): string; -const +const nmax = 100; nmax1 = 30; begin - if o is System.Reflection.Pointer then - Result := PointerToString(System.Reflection.Pointer.Unbox(o)) - else if o=nil then + if o = nil then Result := 'nil' + else if o is System.Reflection.Pointer then + Result := PointerToString(System.Reflection.Pointer.Unbox(o)) else if (o.GetType = typeof(real)) or (o.GetType = typeof(decimal)) or (o.GetType = typeof(single)) then Result := FormatFloatNumber(o.ToString) else if (o.GetType = typeof(Complex)) then begin var c := Complex(o); - Result := '('+StructuredObjectToString(c.Real)+','+StructuredObjectToString(c.Imaginary)+')'; + Result := '(' + StructuredObjectToString(c.Real) + ',' + StructuredObjectToString(c.Imaginary) + ')'; end else if (o.GetType.IsPrimitive) or (o.GetType = typeof(string)) then Result := o.ToString else if o is System.Array then begin var a := o as System.Array; - Result := ArrNToString(a,new integer[a.Rank],0); + Result := ArrNToString(a, new integer[a.Rank], 0); end else if o is System.Collections.IEnumerable then begin var sb := new StringBuilder(); var g := (o as System.Collections.IEnumerable).GetEnumerator(); - var isdictorset := o.GetType.Name.Equals('Dictionary`2') or o.GetType.Name.Equals('SortedDictionary`2') or (o.GetType=typeof(TypedSet)) or o.GetType.Name.Equals('HashSet`1') or o.GetType.Name.Equals('SortedSet`1'); + var isdictorset := o.GetType.Name.Equals('Dictionary`2') or o.GetType.Name.Equals('SortedDictionary`2') or (o.GetType = typeof(TypedSet)) or o.GetType.Name.Equals('HashSet`1') or o.GetType.Name.Equals('SortedSet`1'); if isdictorset then sb.Append('{') else sb.Append('['); if g.MoveNext() then - sb.Append(StructuredObjectToString(g.Current,n+1)); + sb.Append(StructuredObjectToString(g.Current, n + 1)); var cnt := 1; - while g.MoveNext() and (cnt= nmax then sb.Append(',...'); - + if isdictorset then sb.Append('}') else sb.Append(']'); Result := sb.ToString; end - else if o.GetType.GetField('NullBasedArray')<>nil then + else if o.GetType.GetField('NullBasedArray') <> nil then begin var f := o.GetType.GetField('NullBasedArray'); Result := StructuredObjectToString(f.GetValue(o)); @@ -3047,31 +3268,32 @@ begin var q := RedefinedToString(o); var gg := o.GetType.FullName.StartsWith('System.Tuple'); var gg1 := o.GetType.Name.StartsWith('KeyValuePair'); - if (q<>nil) and q.IsVirtual and not gg and not gg1 then + if (q <> nil) and q.IsVirtual and not gg and not gg1 then Result := o.ToString else begin var t := o.GetType; var sb := new System.Text.StringBuilder(); sb.Append('('); - if n>nmax1 then + if n > nmax1 then sb.Append('....') else - while t<>typeof(object) do + while t <> typeof(object) do begin - var ff := t.GetFields(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.Instance or System.Reflection.BindingFlags.DeclaredOnly); - var pp := t.GetProperties(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.Instance or System.Reflection.BindingFlags.DeclaredOnly); - - for var i:=ff.Length-1 downto 0 do - sb.Insert(1,StructuredObjectToString(ff[i].GetValue(o),n+1)+','); - - for var i:=pp.Length-1 downto 0 do - sb.Insert(1,StructuredObjectToString(pp[i].GetValue(o, nil),n+1)+','); - + var ff := t.GetFields(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.&Instance or System.Reflection.BindingFlags.DeclaredOnly); + var pp := t.GetProperties(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.&Instance or System.Reflection.BindingFlags.DeclaredOnly); + + for var i := ff.Length - 1 downto 0 do + sb.Insert(1, StructuredObjectToString(ff[i].GetValue(o), n + 1) + ','); + + for var i := pp.Length - 1 downto 0 do + if pp[i].GetIndexParameters.Length = 0 then + sb.Insert(1, StructuredObjectToString(pp[i].GetValue(o, nil), n + 1) + ','); + t := t.BaseType; end; - if sb.Length>1 then - sb.Length := sb.Length-1; + if sb.Length > 1 then + sb.Length := sb.Length - 1; sb.Append(')'); Result := sb.ToString; end; @@ -3079,24 +3301,25 @@ begin end; function ArrNToString(a: System.Array; indexes: array of integer; i: integer): string; -const nmax = 100; +const + nmax = 100; begin var sb := new StringBuilder; - if i=a.Rank then + if i = a.Rank then sb.Append(StructuredObjectToString(a.GetValue(indexes))) else begin sb.Append('['); - for var k:=0 to a.GetLength(i)-1 do + for var k := 0 to a.GetLength(i) - 1 do begin indexes[i] := k; - sb.Append(ArrNToString(a,indexes,i+1)); - if (k>=nmax-1) and (k= nmax - 1) and (k < a.GetLength(i) - 1) then begin sb.Append(',...'); break end - else if k(left, right: string): boolean; -begin - result := string.CompareOrdinal(left, right) > 0; -end; +function string.operator>(left, right: string) := string.CompareOrdinal(left, right) > 0; -function string.operator>=(left, right: string): boolean; -begin - result := string.CompareOrdinal(left, right) >= 0; -end; +function string.operator>=(left, right: string) := string.CompareOrdinal(left, right) >= 0; /// Повторяет строку str n раз function string.operator*(str: string; n: integer): string; begin var sb := new StringBuilder; - for var i:=1 to n do + loop n do sb.Append(str); - result := sb.ToString; + Result := sb.ToString; end; /// Повторяет строку str n раз function string.operator*(n: integer; str: string): string; begin var sb := new StringBuilder; - for var i:=1 to n do + loop n do sb.Append(str); - result := sb.ToString; + Result := sb.ToString; end; /// Повторяет символ c n раз function char.operator*(c: char; n: integer): string; begin - var sb := new StringBuilder; - for var i:=1 to n do + if n <= 0 then + begin + Result := ''; + exit; + end; + var sb := new StringBuilder(n, n); + loop n do sb.Append(c); - result := sb.ToString; + Result := sb.ToString; end; /// Повторяет символ c n раз function char.operator*(n: integer; c: char): string; begin - var sb := new StringBuilder; - for var i:=1 to n do + if n <= 0 then + begin + Result := ''; + exit; + end; + var sb := new StringBuilder(n, n); + loop n do sb.Append(c); - result := sb.ToString; + Result := sb.ToString; end; /// Добавляет к строке str строковое представление числа n -function string.operator+(str: string; n: integer): string; -begin - result := str + n.ToString; -end; +function string.operator+(str: string; n: integer) := str + n.ToString; /// Добавляет к строке str строковое представление числа n -function string.operator+(n: integer; str: string): string; -begin - result := n.ToString + str; -end; +function string.operator+(n: integer; str: string) := n.ToString + str; /// Добавляет к строке str строковое представление числа r -function string.operator+(str: string; r: real): string; -begin - result := str + r.ToString(nfi); -end; +function string.operator+(str: string; r: real) := str + r.ToString(nfi); /// Добавляет к строке str строковое представление числа r -function string.operator+(r: real; str: string): string; -begin - result := r.ToString(nfi) + str; -end; +function string.operator+(r: real; str: string) := r.ToString(nfi) + str; procedure string.operator+=(var left: string; right: integer); begin @@ -3205,15 +3414,16 @@ end; procedure string.operator*=(var left: string; n: integer); begin var sb := new StringBuilder; - for var i:=1 to n do + loop n do sb.Append(left); left := sb.ToString; end; -function string.operator in(substr: string; str: string): boolean; -begin - Result := str.Contains(substr); -end; +function string.operator in(substr: string; str: string) := str.Contains(substr); + +procedure operator+=(var left: StringBuilder; right: string); extensionmethod := left.Append(right); + +function operator implicit(s: string): StringBuilder; extensionmethod := new StringBuilder(s); //------------------------------------------------------------------------------ // Операции для array of T @@ -3221,26 +3431,41 @@ end; /// Объединяет два массива function operator+(a, b: array of T): array of T; extensionmethod; begin - Result := new T[a.Length+b.Length]; - a.CopyTo(Result,0); - b.CopyTo(Result,a.Length); + Result := new T[a.Length + b.Length]; + a.CopyTo(Result, 0); + b.CopyTo(Result, a.Length); end; ///-- -function operator in(x: T; a: array of T): boolean; extensionmethod; +function operator in(x: T; a: array of T): boolean; extensionmethod := a.Contains(x); + +function operator*(a: array of T; n: integer): array of T; extensionmethod; begin - Result := a.Contains(x); + Result := new T[a.Length * n]; + for var i := 0 to n - 1 do + a.CopyTo(Result, a.Length * i); end; +function operator*(n: integer; a: array of T): array of T; extensionmethod := a * n; + //------------------------------------------------------------------------------ // Операции для List //------------------------------------------------------------------------------ +///-- function operator+=(a, b: List): List; extensionmethod; begin a.AddRange(b); Result := a; end; +///-- +function operator+(a, b: List): List; extensionmethod; +begin + Result := new List(a); + Result.AddRange(b); +end; + +///-- function operator+=(a: List; x: T): List; extensionmethod; begin a.Add(x); @@ -3253,14 +3478,42 @@ begin Result := Self.Contains(x); end; +///-- +function operator*(a: List; n: integer): List; extensionmethod; +begin + Result := new List(); + for var i := 1 to n do + Result.AddRange(a); +end; + +///-- +function operator*(n: integer; a: List): List; extensionmethod := a * n; + +//------------------------------------------------------------------------------ +// Операции для Stack +//------------------------------------------------------------------------------ +///-- +function operator+=(s: Stack; x: T): Stack; extensionmethod; +begin + s.Push(x); + Result := s; +end; + +//------------------------------------------------------------------------------ +// Операции для Queue +//------------------------------------------------------------------------------ +///-- +function operator+=(q: Queue; x: T): Queue; extensionmethod; +begin + q.Enqueue(x); + Result := q; +end; + //------------------------------------------------------------------------------ // Операции для HashSet //------------------------------------------------------------------------------ ///-- -function operator in(x: T; Self: HashSet): boolean; extensionmethod; -begin - Result := Self.Contains(x); -end; +function operator in(x: T; Self: HashSet): boolean; extensionmethod := Self.Contains(x); function operator+=(var Self: HashSet; x: T): HashSet; extensionmethod; begin @@ -3286,30 +3539,49 @@ begin Result := Self; end; -function operator=(x,y: HashSet): boolean; extensionmethod; +function InternalEqual(x,y: HashSet): boolean; begin - Result := x.SetEquals(y) -end; + var xn := Object.ReferenceEquals(x,nil); + var yn := Object.ReferenceEquals(y,nil); + if xn then + Result := yn + else if yn then + Result := xn + else Result := x.SetEquals(y); +end; -function operator<>(x,y: HashSet): boolean; extensionmethod; -begin - Result := not x.SetEquals(y) -end; +function operator=(x,y: HashSet): boolean; extensionmethod := InternalEqual(x,y); -function operator-(x,y: HashSet): HashSet; extensionmethod; +function operator<>(x,y: HashSet); extensionmethod := not InternalEqual(x,y); + +function operator-(x, y: HashSet): HashSet; extensionmethod; begin var v := new HashSet(x); v.ExceptWith(y); Result := v; end; -function operator+(x,y: HashSet): HashSet; extensionmethod; +function operator+(x, y: HashSet): HashSet; extensionmethod; begin var v := new HashSet(x); v.UnionWith(y); Result := v; end; +function operator+(x: HashSet; y: T): HashSet; extensionmethod; +begin + var v := new HashSet(x); + v.Add(y); + Result := v; +end; + +function operator-(x: HashSet; y: T): HashSet; extensionmethod; +begin + var v := new HashSet(x); + v.Remove(y); + Result := v; +end; + function operator*(x,y: HashSet): HashSet; extensionmethod; begin var v := new HashSet(x); @@ -3317,33 +3589,18 @@ begin Result := v; end; -function operator< (x,y: HashSet): boolean; extensionmethod; -begin - Result := x.IsProperSubsetOf(y); -end; +function operator< (x, y: HashSet); extensionmethod := x.IsProperSubsetOf(y); -function operator<= (x,y: HashSet): boolean; extensionmethod; -begin - Result := x.IsSubsetOf(y); -end; +function operator<= (x, y: HashSet); extensionmethod := x.IsSubsetOf(y); -function operator> (x,y: HashSet): boolean; extensionmethod; -begin - Result := x.IsProperSupersetOf(y); -end; +function operator> (x, y: HashSet); extensionmethod := x.IsProperSupersetOf(y); -function operator>= (x,y: HashSet): boolean; extensionmethod; -begin - Result := x.IsSupersetOf(y); -end; +function operator>= (x, y: HashSet); extensionmethod := x.IsSupersetOf(y); //------------------------------------------------------------------------------ // Операции для SortedSet //------------------------------------------------------------------------------ -function operator in(x: T; Self: SortedSet): boolean; extensionmethod; -begin - Result := Self.Contains(x); -end; +function operator in(x: T; Self: SortedSet): boolean; extensionmethod := Self.Contains(x); function operator+=(var Self: SortedSet; x: T): SortedSet; extensionmethod; begin @@ -3369,30 +3626,49 @@ begin Result := Self; end; -function operator=(x,y: SortedSet): boolean; extensionmethod; +function InternalEqual(x,y: SortedSet): boolean; begin - Result := x.SetEquals(y) -end; + var xn := Object.ReferenceEquals(x,nil); + var yn := Object.ReferenceEquals(y,nil); + if xn then + Result := yn + else if yn then + Result := xn + else Result := x.SetEquals(y); +end; -function operator<>(x,y: SortedSet): boolean; extensionmethod; -begin - Result := not x.SetEquals(y) -end; +function operator=(x,y: SortedSet): boolean; extensionmethod := InternalEqual(x,y); -function operator-(x,y: SortedSet): SortedSet; extensionmethod; +function operator<>(x, y: SortedSet); extensionmethod := not InternalEqual(x,y); + +function operator-(x, y: SortedSet): SortedSet; extensionmethod; begin var v := new SortedSet(x); v.ExceptWith(y); Result := v; end; -function operator+(x,y: SortedSet): SortedSet; extensionmethod; +function operator+(x, y: SortedSet): SortedSet; extensionmethod; begin var v := new SortedSet(x); v.UnionWith(y); Result := v; end; +function operator+(x: SortedSet; y: T): SortedSet; extensionmethod; +begin + var v := new SortedSet(x); + v.Add(y); + Result := v; +end; + +function operator-(x: SortedSet; y: T): SortedSet; extensionmethod; +begin + var v := new SortedSet(x); + v.Remove(y); + Result := v; +end; + function operator*(x,y: SortedSet): SortedSet; extensionmethod; begin var v := new SortedSet(x); @@ -3400,210 +3676,115 @@ begin Result := v; end; -function operator< (x,y: SortedSet): boolean; extensionmethod; -begin - Result := x.IsProperSubsetOf(y); -end; +function operator< (x, y: SortedSet); extensionmethod := x.IsProperSubsetOf(y); -function operator<= (x,y: SortedSet): boolean; extensionmethod; -begin - Result := x.IsSubsetOf(y); -end; +function operator<= (x, y: SortedSet); extensionmethod := x.IsSubsetOf(y); -function operator> (x,y: SortedSet): boolean; extensionmethod; -begin - Result := x.IsProperSupersetOf(y); -end; +function operator> (x, y: SortedSet); extensionmethod := x.IsProperSupersetOf(y); -function operator>= (x,y: SortedSet): boolean; extensionmethod; -begin - Result := x.IsSupersetOf(y); -end; +function operator>= (x, y: SortedSet): boolean; extensionmethod := x.IsSupersetOf(y); //------------------------------------------------------------------------------ // Операции для Dictionary, SortedDictionary, SortedList //------------------------------------------------------------------------------ -function Dictionary.operator in(key: K; d: Dictionary): boolean; +function Dictionary.operator in(key: K; d: Dictionary): boolean; begin Result := d.ContainsKey(key); end; -function SortedDictionary.operator in(key: K; d: SortedDictionary): boolean; +function SortedDictionary.operator in(key: K; d: SortedDictionary): boolean; begin Result := d.ContainsKey(key); end; -function SortedList.operator in(key: K; d: SortedList): boolean; +function SortedList.operator in(key: K; d: SortedList): boolean; begin Result := d.ContainsKey(key); end; +//------------------------------------------------------------------------------ +// ** +//------------------------------------------------------------------------------ + +function operator**(x: real; n: integer): real; extensionmethod := Power(x, n); + +function operator**(x, y: integer): real; extensionmethod := Power(real(x), y); + +function operator**(x, y: real): real; extensionmethod := Power(x, y); + +function operator**(x, y: Complex): Complex; extensionmethod := Power(x, y); + +function operator**(x: BigInteger; y: integer): BigInteger; extensionmethod := Power(x, y); + //------------------------------------------------------------------------------ // Операции для BigInteger //------------------------------------------------------------------------------ -function BigInteger.operator/(p: BigInteger; q: real): real; -begin - Result := real(p)/q; -end; +function BigInteger.operator/(p: BigInteger; q: real) := real(p)/q; -function BigInteger.operator/(q: real; p: BigInteger): real; -begin - Result := q/real(p); -end; +function BigInteger.operator/(q: real; p: BigInteger) := q/real(p); -function BigInteger.operator>(p: BigInteger; q: integer): boolean; -begin - Result := p > BigInteger.Create(q); -end; +function BigInteger.operator>(p: BigInteger; q: integer) := p > BigInteger.Create(q); -function BigInteger.operator>(p: integer; q: BigInteger): boolean; -begin - Result := BigInteger.Create(p) > q; -end; +function BigInteger.operator>(p: integer; q: BigInteger) := BigInteger.Create(p) > q; -function BigInteger.operator<(p: BigInteger; q: integer): boolean; -begin - Result := p < BigInteger.Create(q); -end; +function BigInteger.operator<(p: BigInteger; q: integer) := p < BigInteger.Create(q); -function BigInteger.operator<(p: integer; q: BigInteger): boolean; -begin - Result := BigInteger.Create(p) < q; -end; +function BigInteger.operator<(p: integer; q: BigInteger) := BigInteger.Create(p) < q; -function BigInteger.operator>=(p: BigInteger; q: integer): boolean; -begin - Result := p >= BigInteger.Create(q); -end; +function BigInteger.operator>=(p: BigInteger; q: integer) := p >= BigInteger.Create(q); -function BigInteger.operator>=(p: integer; q: BigInteger): boolean; -begin - Result := BigInteger.Create(p) >= q; -end; +function BigInteger.operator>=(p: integer; q: BigInteger) := BigInteger.Create(p) >= q; -function BigInteger.operator<=(p: BigInteger; q: integer): boolean; -begin - Result := p <= BigInteger.Create(q); -end; +function BigInteger.operator<=(p: BigInteger; q: integer) := p <= BigInteger.Create(q); -function BigInteger.operator<=(p: integer; q: BigInteger): boolean; -begin - Result := BigInteger.Create(p) <= q; -end; +function BigInteger.operator<=(p: integer; q: BigInteger) := BigInteger.Create(p) <= q; -function BigInteger.operator=(p: BigInteger; q: integer): boolean; -begin - Result := p = BigInteger.Create(q); -end; +function BigInteger.operator=(p: BigInteger; q: integer) := p = BigInteger.Create(q); -function BigInteger.operator=(p: integer; q: BigInteger): boolean; -begin - Result := BigInteger.Create(p) = q; -end; +function BigInteger.operator=(p: integer; q: BigInteger) := BigInteger.Create(p) = q; -function BigInteger.operator<>(p: BigInteger; q: integer): boolean; -begin - Result := p <> BigInteger.Create(q); -end; +function BigInteger.operator<>(p: BigInteger; q: integer) := p <> BigInteger.Create(q); -function BigInteger.operator<>(p: integer; q: BigInteger): boolean; -begin - Result := BigInteger.Create(p) <> q; -end; +function BigInteger.operator<>(p: integer; q: BigInteger) := BigInteger.Create(p) <> q; -procedure BigInteger.operator+=(var p: BigInteger; q: BigInteger); -begin - p := p + q; -end; +procedure BigInteger.operator+=(var p: BigInteger; q: BigInteger) := p := p + q; -procedure BigInteger.operator*=(var p: BigInteger; q: BigInteger); -begin - p := p * q; -end; +procedure BigInteger.operator*=(var p: BigInteger; q: BigInteger) := p := p * q; -procedure BigInteger.operator-=(var p: BigInteger; q: BigInteger); -begin - p := p - q; -end; +procedure BigInteger.operator-=(var p: BigInteger; q: BigInteger) := p := p - q; -function BigInteger.operator div(p,q: BigInteger): BigInteger; -begin - Result := BigInteger.Divide(p,q); -end; +//function BigInteger.operator div(p,q: BigInteger) := BigInteger.Divide(p,q); -function BigInteger.operator mod(p,q: BigInteger): BigInteger; -begin - Result := BigInteger.Remainder(p,q); -end; +//function BigInteger.operator mod(p,q: BigInteger) := BigInteger.Remainder(p,q); -function BigInteger.operator-(p: BigInteger): BigInteger; -begin - Result := BigInteger.Negate(p) -end; - -{function BigInteger.operator+(p: BigInteger): BigInteger; -begin - Result := p -end; - -function BigInteger.operator+(p,q: BigInteger): BigInteger; -begin - Result := BigInteger.Add(p,q); -end;} +function BigInteger.operator-(p: BigInteger) := BigInteger.Negate(p); //------------------------------------------------------------------------------ // Операции для Complex //------------------------------------------------------------------------------ -function operator-(Self: Complex): Complex; extensionmethod; -begin - Result := Complex.Negate(Self); -end; +function operator-(Self: Complex): Complex; extensionmethod := Complex.Negate(Self); -function operator implicit(c: (real,real)): Complex; extensionmethod; -begin - Result := Cplx(c[0],c[1]); -end; +function operator implicit(c: (real,real)): Complex; extensionmethod := Cplx(c[0],c[1]); -function operator implicit(c: (real,integer)): Complex; extensionmethod; -begin - Result := Cplx(c[0],c[1]); -end; +function operator implicit(c: (real,integer)): Complex; extensionmethod := Cplx(c[0],c[1]); -function operator implicit(c: (integer,real)): Complex; extensionmethod; -begin - Result := Cplx(c[0],c[1]); -end; +function operator implicit(c: (integer,real)): Complex; extensionmethod := Cplx(c[0],c[1]); -function operator implicit(c: (integer,integer)): Complex; extensionmethod; -begin - Result := Cplx(c[0],c[1]); -end; +function operator implicit(c: (integer,integer)): Complex; extensionmethod := Cplx(c[0],c[1]); -procedure operator+=(var c: Complex; x: Complex); extensionmethod; -begin - c := c + x; -end; +procedure operator+=(var c: Complex; x: Complex); extensionmethod := c := c + x; -procedure operator*=(var c: Complex; x: Complex); extensionmethod; -begin - c := c * x; -end; +procedure operator*=(var c: Complex; x: Complex); extensionmethod := c := c * x; -procedure operator-=(var c: Complex; x: Complex); extensionmethod; -begin - c := c - x; -end; +procedure operator-=(var c: Complex; x: Complex); extensionmethod := c := c - x; -procedure operator/=(var c: Complex; x: Complex); extensionmethod; -begin - c := c / x; -end; +procedure operator/=(var c: Complex; x: Complex); extensionmethod := c := c / x; //------------------------------------------------------------------------------ // Операции для sequence of T //------------------------------------------------------------------------------ ///-- -function operator+(a,b: sequence of T): sequence of T; extensionmethod; +function operator+(a, b: sequence of T): sequence of T; extensionmethod; begin Result := a.Concat(b); end; @@ -3625,14 +3806,14 @@ end; function operator*(a: sequence of T; n: integer): sequence of T; extensionmethod; begin Result := System.Linq.Enumerable.Empty&(); - for var i:=1 to n do + loop n do Result := Result.Concat(a); end; ///-- function operator*(n: integer; a: sequence of T): sequence of T; extensionmethod; begin - Result := a*n; + Result := a * n; end; ///-- @@ -3644,101 +3825,26 @@ end; // Функции для последовательностей и динамических массивов // ----------------------------------------------------------------------------- -type -// Вспомогательный класс для генерации всех последовательностей - SeqBase = class(IEnumerable,IEnumerator) - public - function System.Collections.IEnumerable.GetEnumerator(): System.Collections.IEnumerator; - begin - Result := Self; - end; - - function GetEnumerator(): IEnumerator; - begin - Result := Self; - end; - - function get_Current: T; virtual; - begin - Result := default(T); - end; - - function System.Collections.IEnumerator.get_Current(): object; - begin - Result := Self.get_Current(); - end; - - function MoveNext(): boolean; virtual; - begin - Result := True; - end; - - procedure Dispose(); virtual; - begin - end; - - procedure Reset(); - begin - end; - end; - -// Вспомогательный класс для генерации целых последовательностей - SeqBaseInteger = class(IEnumerable,IEnumerator) - public - function System.Collections.IEnumerable.GetEnumerator(): System.Collections.IEnumerator; - begin - Result := Self; - end; - - function GetEnumerator(): IEnumerator; - begin - Result := Self; - end; - - function get_Current: integer; virtual; - begin - Result := 0; - end; - - function System.Collections.IEnumerator.get_Current(): object; - begin - Result := Self.get_Current(); - end; - - function MoveNext(): boolean; virtual; - begin - Result := True; - end; - - procedure Dispose(); virtual; - begin - end; - - procedure Reset(); - begin - end; - end; - function Range(a, b: integer): sequence of integer; begin - if b else Result := System.Linq.Enumerable.Range(a, b - a + 1); end; -function Range(c1,c2: char): sequence of char; +function Range(c1, c2: char): sequence of char; begin - Result := Range(integer(c1),integer(c2)).Select(x->Chr(x)); + Result := Range(integer(c1), integer(c2)).Select(x -> Chr(x)); end; -function Range(a,b: real; n: integer): sequence of real; +function Range(a, b: real; n: integer): sequence of real; begin - if n=0 then + if n = 0 then raise new System.ArgumentException('n=0'); - if n<0 then + if n < 0 then raise new System.ArgumentException('n<0'); var r := a; - var h := (b-a)/n; + var h := (b - a) / n; for var i := 0 to n do begin yield r; @@ -3746,78 +3852,78 @@ begin end; end; -function Partition(a,b: real; n: integer): sequence of real; +function Partition(a, b: real; n: integer): sequence of real; begin - Result := Range(a,b,n) + Result := Range(a, b, n) end; type ArithmSeq = auto class - a,step: integer; + a, step: integer; function f(x: integer): integer; begin - Result := x*step+a; + Result := x * step + a; end; end; function Range(a, b, step: integer): sequence of integer; begin - if step=0 then + if step = 0 then raise new System.ArgumentException('step=0'); - if (step>0) and (ba) then + if (step > 0) and (b < a) or (step < 0) and (b > a) then begin Result := System.Linq.Enumerable.Empty&; exit; end; - var n := abs((b-a) div step) + 1; + var n := abs((b - a) div step) + 1; var ar: ArithmSeq; {if step<0 then ar := new ArithmSeq(b,step) - else} ar := new ArithmSeq(a,step); + else} ar := new ArithmSeq(a, step); Result := System.Linq.Enumerable.Range(0, n).Select(ar.f); end; -function ArrRandom(n: integer; a: integer; b: integer): array of integer; +function ArrRandom(n: integer; a: integer; b: integer): array of integer; begin Result := new integer[n]; - for var i:=0 to Result.Length-1 do - Result[i] := Random(a,b); + for var i := 0 to Result.Length - 1 do + Result[i] := Random(a, b); end; function ArrRandomInteger(n: integer; a: integer; b: integer): array of integer; begin - Result := ArrRandom(n,a,b); + Result := ArrRandom(n, a, b); end; function ArrRandomReal(n: integer; a: real; b: real): array of real; begin Result := new real[n]; - for var i:=0 to Result.Length-1 do - Result[i] := Random()*(b-a)+a; + for var i := 0 to Result.Length - 1 do + Result[i] := Random() * (b - a) + a; end; function SeqRandom(n: integer; a: integer; b: integer): sequence of integer; begin - for var i:=1 to n do - yield Random(a,b) + loop n do + yield Random(a, b) end; function SeqRandomInteger(n: integer; a: integer; b: integer): sequence of integer; begin - for var i:=1 to n do - yield Random(a,b) + loop n do + yield Random(a, b) end; function SeqRandomReal(n: integer; a: real; b: real): sequence of real; begin - for var i:=1 to n do - yield Random()*(b-a)+a + loop n do + yield Random() * (b - a) + a end; function Arr(params a: array of T): array of T; begin Result := new T[a.Length]; - System.Array.Copy(a,Result,a.Length); + System.Array.Copy(a, Result, a.Length); end; function Arr(a: sequence of T): array of T; @@ -3828,7 +3934,7 @@ end; function Seq(params a: array of T): sequence of T; begin var res := new T[a.Length]; - System.Array.Copy(a,res,a.Length); + System.Array.Copy(a, res, a.Length); Result := res; end; @@ -3841,68 +3947,66 @@ begin first := next(first); yield first; end; - //Result := IterateClass&.Create(first,next).Select(x->T(x)); end; /// Возвращает бесконечную рекуррентную последовательность элементов, задаваемую начальными элементами first, second и функцией next -function Iterate(first,second: T; next: (T,T)->T): sequence of T; +function Iterate(first, second: T; next: (T,T)->T): sequence of T; begin yield first; yield second; while True do begin - var nxt := next(first,second); + var nxt := next(first, second); yield nxt; first := second; second := nxt; end; -// Result := Iterate2Class&.Create(first,second,next).Select(x->T(x)); end; -function SeqGen(count: integer; first: T; next: T -> T): sequence of T; +function SeqGen(count: integer; first: T; next: T->T): sequence of T; begin - if count<1 then - raise new System.ArgumentOutOfRangeException('count',count,GetTranslation(PARAMETER_COUNT_MUST_BE_GREATER_0)); - Result := Iterate(first,next).Take(count); -end; - -function SeqGen(count: integer; first,second: T; next: (T,T) -> T): sequence of T; -begin - if count<1 then - raise new System.ArgumentOutOfRangeException('count',count,GetTranslation(PARAMETER_COUNT_MUST_BE_GREATER_0)); - Result := Iterate(first,second,next).Take(count); -end; - -function SeqWhile(first: T; next: T -> T; pred: T -> boolean): sequence of T; -begin - Result := Iterate(first,next).TakeWhile(pred); -end; - -function SeqWhile(first,second: T; next: (T,T) -> T; pred: T -> boolean): sequence of T; -begin - Result := Iterate(first,second,next).TakeWhile(pred); + if count < 1 then + raise new System.ArgumentOutOfRangeException('count', count, GetTranslation(PARAMETER_COUNT_MUST_BE_GREATER_0)); + Result := Iterate(first, next).Take(count); end; -function ArrGen(count: integer; first: T; next: T -> T): array of T; +function SeqGen(count: integer; first, second: T; next: (T,T) ->T): sequence of T; begin - if count<1 then - raise new System.ArgumentOutOfRangeException('count',count,GetTranslation(PARAMETER_COUNT_MUST_BE_GREATER_0)); + if count < 1 then + raise new System.ArgumentOutOfRangeException('count', count, GetTranslation(PARAMETER_COUNT_MUST_BE_GREATER_0)); + Result := Iterate(first, second, next).Take(count); +end; + +function SeqWhile(first: T; next: T->T; pred: T->boolean): sequence of T; +begin + Result := Iterate(first, next).TakeWhile(pred); +end; + +function SeqWhile(first, second: T; next: (T,T) ->T; pred: T->boolean): sequence of T; +begin + Result := Iterate(first, second, next).TakeWhile(pred); +end; + +function ArrGen(count: integer; first: T; next: T->T): array of T; +begin + if count < 1 then + raise new System.ArgumentOutOfRangeException('count', count, GetTranslation(PARAMETER_COUNT_MUST_BE_GREATER_0)); var a := new T[count]; a[0] := first; - for var i:=1 to a.Length-1 do - a[i] := next(a[i-1]); + for var i := 1 to a.Length - 1 do + a[i] := next(a[i - 1]); Result := a; end; -function ArrGen(count: integer; first,second: T; next: (T,T) -> T): array of T; +function ArrGen(count: integer; first, second: T; next: (T,T) ->T): array of T; begin - if count<2 then - raise new System.ArgumentOutOfRangeException('count',count,GetTranslation(PARAMETER_COUNT_MUST_BE_GREATER_1)); + if count < 2 then + raise new System.ArgumentOutOfRangeException('count', count, GetTranslation(PARAMETER_COUNT_MUST_BE_GREATER_1)); var a := new T[count]; a[0] := first; a[1] := second; - for var i:=2 to a.Length-1 do - a[i] := next(a[i-2],a[i-1]); + for var i := 2 to a.Length - 1 do + a[i] := next(a[i - 2], a[i - 1]); Result := a; end; @@ -3936,47 +4040,47 @@ end;} function ArrFill(count: integer; x: T): array of T; begin Result := new T[count]; - for var i:=0 to Result.Length-1 do + for var i := 0 to Result.Length - 1 do Result[i] := x; end; -function ArrGen(count: integer; gen: integer -> T; from: integer): array of T; +function ArrGen(count: integer; gen: integer->T; from: integer): array of T; begin Result := new T[count]; - for var i:=0 to Result.Length-1 do - Result[i] := gen(i+from); + for var i := 0 to Result.Length - 1 do + Result[i] := gen(i + from); end; -function ArrGen(count: integer; gen: integer -> T): array of T; +function ArrGen(count: integer; gen: integer->T): array of T; begin Result := new T[count]; - for var i:=0 to Result.Length-1 do + for var i := 0 to Result.Length - 1 do Result[i] := gen(i); end; function SeqFill(count: integer; x: T): sequence of T; begin - Result := System.Linq.Enumerable.Repeat(x,count); + Result := System.Linq.Enumerable.Repeat(x, count); end; -function SeqGen(count: integer; f: integer -> T; from: integer): sequence of T; +function SeqGen(count: integer; f: integer->T; from: integer): sequence of T; begin - Result := Range(from,count+from-1).Select(f) + Result := Range(from, count + from - 1).Select(f) end; -function SeqGen(count: integer; f: integer -> T): sequence of T; +function SeqGen(count: integer; f: integer->T): sequence of T; begin - Result := Range(0,count-1).Select(f) + Result := Range(0, count - 1).Select(f) end; function ReadArrInteger(n: integer): array of integer; begin Result := new integer[n]; - for var i:=0 to Result.Length-1 do + for var i := 0 to Result.Length - 1 do Result[i] := ReadInteger; end; -function ReadArrInteger(const prompt: string; n: integer): array of integer; +function ReadArrInteger(prompt: string; n: integer): array of integer; begin Print(prompt); Result := ReadArrInteger(n); @@ -3985,11 +4089,11 @@ end; function ReadArrReal(n: integer): array of real; begin Result := new real[n]; - for var i:=0 to Result.Length-1 do + for var i := 0 to Result.Length - 1 do Result[i] := ReadReal; end; -function ReadArrReal(const prompt: string; n: integer): array of real; +function ReadArrReal(prompt: string; n: integer): array of real; begin Print(prompt); Result := ReadArrReal(n); @@ -3998,11 +4102,11 @@ end; function ReadArrString(n: integer): array of string; begin Result := new string[n]; - for var i:=0 to Result.Length-1 do + for var i := 0 to Result.Length - 1 do Result[i] := ReadString; end; -function ReadArrString(const prompt: string; n: integer): array of string; +function ReadArrString(prompt: string; n: integer): array of string; begin Print(prompt); Result := ReadArrString(n); @@ -4010,10 +4114,10 @@ end; function ReadSeqInteger(n: integer): sequence of integer; begin - Result := Range(1,n).Select(i->ReadInteger()); + Result := Range(1, n).Select(i -> ReadInteger()); end; -function ReadSeqInteger(const prompt: string; n: integer): sequence of integer; +function ReadSeqInteger(prompt: string; n: integer): sequence of integer; begin Print(prompt); Result := ReadSeqInteger(n); @@ -4021,10 +4125,10 @@ end; function ReadSeqReal(n: integer): sequence of real; begin - Result := Range(1,n).Select(i->ReadReal()); + Result := Range(1, n).Select(i -> ReadReal()); end; -function ReadSeqReal(const prompt: string; n: integer): sequence of real; +function ReadSeqReal(prompt: string; n: integer): sequence of real; begin Print(prompt); Result := ReadSeqReal(n); @@ -4032,16 +4136,16 @@ end; function ReadSeqString(n: integer): sequence of string; begin - Result := Range(1,n).Select(i->ReadString()); + Result := Range(1, n).Select(i -> ReadString()); end; -function ReadSeqString(const prompt: string; n: integer): sequence of string; +function ReadSeqString(prompt: string; n: integer): sequence of string; begin Print(prompt); Result := ReadSeqString(n); end; -function ReadSeqIntegerWhile(cond: integer -> boolean): sequence of integer; +function ReadSeqIntegerWhile(cond: integer->boolean): sequence of integer; begin while True do begin @@ -4052,7 +4156,7 @@ begin end; end; -function ReadSeqRealWhile(cond: real -> boolean): sequence of real; +function ReadSeqRealWhile(cond: real->boolean): sequence of real; begin while True do begin @@ -4063,7 +4167,7 @@ begin end; end; -function ReadSeqStringWhile(cond: string -> boolean): sequence of string; +function ReadSeqStringWhile(cond: string->boolean): sequence of string; begin while True do begin @@ -4074,19 +4178,19 @@ begin end; end; -function ReadSeqIntegerWhile(const prompt: string; cond: integer -> boolean): sequence of integer; +function ReadSeqIntegerWhile(prompt: string; cond: integer->boolean): sequence of integer; begin Print(prompt); Result := ReadSeqIntegerWhile(cond); end; -function ReadSeqRealWhile(const prompt: string; cond: real -> boolean): sequence of real; +function ReadSeqRealWhile(prompt: string; cond: real->boolean): sequence of real; begin Print(prompt); Result := ReadSeqRealWhile(cond); end; -function ReadSeqStringWhile(const prompt: string; cond: string -> boolean): sequence of string; +function ReadSeqStringWhile(prompt: string; cond: string->boolean): sequence of string; begin Print(prompt); Result := ReadSeqStringWhile(cond); @@ -4095,35 +4199,17 @@ end; // ----------------------------------------------------------------------------- // Функции Rec для создания кортежей // ----------------------------------------------------------------------------- -function Rec(x1: T1; x2: T2): System.Tuple; -begin - Result := Tuple.Create(x1,x2); -end; +function Rec(x1: T1; x2: T2) := Tuple.Create(x1, x2); -function Rec(x1: T1; x2: T2; x3: T3): (T1,T2,T3); -begin - Result := Tuple.Create(x1,x2,x3); -end; +function Rec(x1: T1; x2: T2; x3: T3) := Tuple.Create(x1, x2, x3); -function Rec(x1: T1; x2: T2; x3: T3; x4: T4): (T1,T2,T3,T4); -begin - Result := Tuple.Create(x1,x2,x3,x4); -end; +function Rec(x1: T1; x2: T2; x3: T3; x4: T4) := Tuple.Create(x1, x2, x3, x4); -function Rec(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5): (T1,T2,T3,T4,T5); -begin - Result := Tuple.Create(x1,x2,x3,x4,x5); -end; +function Rec(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5) := Tuple.Create(x1, x2, x3, x4, x5); -function Rec(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5; x6: T6): (T1,T2,T3,T4,T5,T6); -begin - Result := Tuple.Create(x1,x2,x3,x4,x5,x6); -end; +function Rec(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5; x6: T6) := Tuple.Create(x1, x2, x3, x4, x5, x6); -function Rec(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5; x6: T6; x7: T7): (T1,T2,T3,T4,T5,T6,T7); -begin - Result := Tuple.Create(x1,x2,x3,x4,x5,x6,x7); -end; +function Rec(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5; x6: T6; x7: T7) := Tuple.Create(x1, x2, x3, x4, x5, x6, x7); // ----------------------------------------------------------------------------- // Функции Lst, LLst, Dict, KV, HSet, SSet @@ -4175,11 +4261,38 @@ begin Result.Add(pairs[i].Key, pairs[i].Value); end; +function Dict(params pairs: array of (TKey, TVal)): Dictionary; +begin + Result := new Dictionary(); + for var i := 0 to pairs.Length - 1 do + Result.Add(pairs[i][0], pairs[i][1]); +end; + function KV(key: TKey; value: TVal): KeyValuePair; begin Result := new KeyValuePair(key, value); end; +function __TypeCheckAndAssignForIsMatch(obj: object; var res: T): boolean; +begin + if obj is T then + begin + res := T(obj); + Result := true; + end + else + begin + res := default(T); + Result := false; + end; +end; + +///-- +procedure Deconstruct(self: T; var res: T); extensionmethod; +begin + res := self; +end; + {function read_lexem: string; var c: char; @@ -4222,7 +4335,6 @@ function read_lexem(f: Text): string; var c: char; i: integer; - sb: System.Text.StringBuilder; begin if f.fi = nil then raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED)); @@ -4232,7 +4344,7 @@ begin i := f.sr.Read(); until not char.IsWhiteSpace(char(i)); // pass spaces c := char(i); - sb := System.Text.StringBuilder.Create; + var sb := System.Text.StringBuilder.Create; repeat sb.Append(c); i := f.sr.Peek(); @@ -4253,11 +4365,11 @@ function IOStandardSystem.peek: integer; begin if not console_alloc then AllocConsole; -// SSM 29.11.14 + // SSM 29.11.14 if state = 1 then // в sym - символ, считанный предыдущим Peek Result := sym else // в sym ничего нет - begin + begin state := 1; sym := Console.Read(); // считываение в буфер Result := sym; @@ -4268,7 +4380,7 @@ function IOStandardSystem.read_symbol: char; begin if not console_alloc then AllocConsole; -// SSM 29.11.14 + // SSM 29.11.14 if state = 1 then // в sym - символ, считанный предыдущим Peek begin state := 0; @@ -4313,12 +4425,12 @@ begin var sb := new System.Text.StringBuilder; var c := read_symbol; if (c <> #13) and (c <> #10) then - sb.Append(c); + sb.Append(c); while (c <> #13) and (c <> #10) do begin - c := read_symbol; - sb.Append(c); - c := char(peek()); + c := read_symbol; + sb.Append(c); + c := char(peek()); end; x := sb.ToString; end @@ -4388,9 +4500,15 @@ begin else raise new System.FormatException('Входная строка имела неверный формат'); end; -procedure IOStandardSystem.readln; +procedure IOStandardSystem.readln; // SSM 4.11.17 - проверять правку, потенциально могут быть ошибки begin - while CurrentIOSystem.read_symbol <> END_OF_LINE_SYMBOL do; + // while CurrentIOSystem.read_symbol <> END_OF_LINE_SYMBOL do; // было + while True do + begin + var sym := CurrentIOSystem.read_symbol; + if (sym = END_OF_LINE_SYMBOL) or (sym = char(-1)) then + exit; + end; end; procedure IOStandardSystem.write(obj: object); @@ -4421,11 +4539,11 @@ end; // ----------------------------------------------------- // Read - Readln // ----------------------------------------------------- -procedure read; +procedure Read; begin end; -procedure readln; +procedure Readln; begin if input.sr <> nil then input.sr.ReadLine @@ -4438,7 +4556,7 @@ begin end; end; -procedure read(var x: integer); +procedure Read(var x: integer); begin if input.sr <> nil then read(input, x) @@ -4451,7 +4569,7 @@ begin end; end; -procedure read(var x: real); +procedure Read(var x: real); begin if input.sr <> nil then read(input, x) @@ -4464,7 +4582,7 @@ begin end; end; -procedure read(var x: char); +procedure Read(var x: char); begin if input.sr <> nil then read(input, x) @@ -4477,7 +4595,7 @@ begin end; end; -procedure read(var x: string); +procedure Read(var x: string); begin if input.sr <> nil then read(input, x) @@ -4490,7 +4608,7 @@ begin end; end; -procedure read(var x: byte); +procedure Read(var x: byte); begin if input.sr <> nil then read(input, x) @@ -4503,7 +4621,7 @@ begin end; end; -procedure read(var x: shortint); +procedure Read(var x: shortint); begin if input.sr <> nil then read(input, x) @@ -4516,7 +4634,7 @@ begin end; end; -procedure read(var x: smallint); +procedure Read(var x: smallint); begin if input.sr <> nil then read(input, x) @@ -4529,7 +4647,7 @@ begin end; end; -procedure read(var x: word); +procedure Read(var x: word); begin if input.sr <> nil then read(input, x) @@ -4542,7 +4660,7 @@ begin end; end; -procedure read(var x: longword); +procedure Read(var x: longword); begin if input.sr <> nil then read(input, x) @@ -4555,7 +4673,7 @@ begin end; end; -procedure read(var x: int64); +procedure Read(var x: int64); begin if input.sr <> nil then read(input, x) @@ -4568,7 +4686,7 @@ begin end; end; -procedure read(var x: uint64); +procedure Read(var x: uint64); begin if input.sr <> nil then read(input, x) @@ -4581,7 +4699,7 @@ begin end; end; -procedure read(var x: single); +procedure Read(var x: single); begin if input.sr <> nil then read(input, x) @@ -4594,7 +4712,7 @@ begin end; end; -procedure read(var x: boolean); +procedure Read(var x: boolean); begin if input.sr <> nil then read(input, x) @@ -4607,6 +4725,107 @@ begin end; end; +function TryRead(var x: integer): boolean; +begin + Result := True; + try + Read(x) + except + Result := False; + end +end; + +function TryRead(var x: real): boolean; +begin + Result := True; + try + Read(x) + except + Result := False; + end +end; + +function TryRead(var x: byte): boolean; +begin + Result := True; + try + Read(x) + except + Result := False; + end +end; + +function TryRead(var x: shortint): boolean; +begin + Result := True; + try + Read(x) + except + Result := False; + end +end; + +function TryRead(var x: smallint): boolean; +begin + Result := True; + try + Read(x) + except + Result := False; + end +end; + +function TryRead(var x: word): boolean; +begin + Result := True; + try + Read(x) + except + Result := False; + end +end; + +function TryRead(var x: longword): boolean; +begin + Result := True; + try + Read(x) + except + Result := False; + end +end; + +function TryRead(var x: int64): boolean; +begin + Result := True; + try + Read(x) + except + Result := False; + end +end; + +function TryRead(var x: uint64): boolean; +begin + Result := True; + try + Read(x) + except + Result := False; + end +end; + +function TryRead(var x: single): boolean; +begin + Result := True; + try + Read(x) + except + Result := False; + end +end; + + function ReadInteger: integer; begin var x: integer; @@ -4672,6 +4891,71 @@ begin readln(); end; +function ReadInteger2 := (ReadInteger, ReadInteger); + +function ReadReal2 := (ReadReal, ReadReal); + +function ReadChar2 := (ReadChar, ReadChar); + +function ReadString2 := (ReadString, ReadString); + +function ReadlnInteger2 := (ReadInteger, ReadlnInteger); + +function ReadlnReal2 := (ReadReal, ReadlnReal); + +function ReadlnChar2 := (ReadChar, ReadlnChar); + +function ReadlnString2 := (ReadString, ReadlnString); + +function ReadInteger3 := (ReadInteger, ReadInteger, ReadInteger); + +function ReadReal3 := (ReadReal, ReadReal, ReadReal); + +function ReadChar3 := (ReadChar, ReadChar, ReadChar); + +function ReadString3 := (ReadString, ReadString, ReadString); + +function ReadlnInteger3 := (ReadInteger, ReadInteger, ReadlnInteger); + +function ReadlnReal3 := (ReadReal, ReadReal, ReadlnReal); + +function ReadlnChar3 := (ReadChar, ReadChar, ReadlnChar); + +function ReadlnString3 := (ReadString, ReadString, ReadlnString); + +function ReadInteger2(prompt: string) := (ReadInteger(prompt), ReadInteger); + +function ReadReal2(prompt: string) := (ReadReal(prompt), ReadReal); + +function ReadChar2(prompt: string) := (ReadChar(prompt), ReadChar); + +function ReadString2(prompt: string) := (ReadString(prompt), ReadString); + +function ReadlnInteger2(prompt: string) := (ReadInteger(prompt), ReadlnInteger); + +function ReadlnReal2(prompt: string) := (ReadReal(prompt), ReadlnReal); + +function ReadlnChar2(prompt: string) := (ReadChar(prompt), ReadlnChar); + +function ReadlnString2(prompt: string) := (ReadString(prompt), ReadlnString); + +function ReadInteger3(prompt: string) := (ReadInteger(prompt), ReadInteger, ReadInteger); + +function ReadReal3(prompt: string) := (ReadReal(prompt), ReadReal, ReadReal); + +function ReadChar3(prompt: string) := (ReadChar(prompt), ReadChar, ReadChar); + +function ReadString3(prompt: string) := (ReadString(prompt), ReadString, ReadString); + +function ReadlnInteger3(prompt: string) := (ReadInteger(prompt), ReadInteger, ReadlnInteger); + +function ReadlnReal3(prompt: string) := (ReadReal(prompt), ReadReal, ReadlnReal); + +function ReadlnChar3(prompt: string) := (ReadChar(prompt), ReadChar, ReadlnChar); + +function ReadlnString3(prompt: string) := (ReadString(prompt), ReadString, ReadlnString); + + // Read with prompt function ReadInteger(prompt: string): integer; @@ -4830,7 +5114,7 @@ begin raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED)); if f.sr = nil then raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED_FOR_READING)); - + x := f.sr.ReadLine; if x = nil then x := ''; @@ -5081,14 +5365,19 @@ begin Result := PABCSystem.ReadlnBoolean(Self); end; +procedure Text.Readln; +begin + PABCSystem.Readln(Self); +end; + procedure Text.Write(params o: array of Object); begin - PABCSystem.Write(Self,o); + PABCSystem.Write(Self, o); end; procedure Text.Writeln(params o: array of Object); begin - PABCSystem.Writeln(Self,o); + PABCSystem.Writeln(Self, o); end; function Text.Eof: boolean; @@ -5133,19 +5422,25 @@ end; function Text.Name: string; begin - Result := fi.Name + Result := fi.Name end; function Text.FullName: string; begin - Result := fi.FullName + Result := fi.FullName end; function Text.ReadToEnd: string; begin - Result := sr.ReadToEnd + Result := sr.ReadToEnd end; +procedure Text.Reset; +begin + PABCSystem.Reset(Self); +end; + + // ----------------------------------------------------- // AbstractBinaryFile methods // ----------------------------------------------------- @@ -5179,6 +5474,23 @@ begin PABCSystem.Write(Self, vals); end; +procedure AbstractBinaryFile.Reset; +begin + PABCSystem.Reset(Self); +end; + +function AbstractBinaryFile.Name: string; +begin + Result := fi.Name +end; + +function AbstractBinaryFile.FullName: string; +begin + Result := fi.FullName +end; + + + // ----------------------------------------------------- // TypedFile & BinaryFile methods // ----------------------------------------------------- @@ -5192,11 +5504,6 @@ begin Result := PABCSystem.FileSize(Self); end; -procedure TypedFile.Seek(n: int64); -begin - PABCSystem.Seek(Self, n); -end; - function BinaryFile.FilePos: int64; begin Result := PABCSystem.FilePos(Self); @@ -5360,20 +5667,20 @@ begin raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED)); if f.sw = nil then raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED_FOR_WRITING)); - + f.sw.Write(StructuredObjectToString(val)); {if val = nil then begin - f.sw.Write('nil'); - exit; + f.sw.Write('nil'); + exit; end; case System.Type.GetTypeCode(val.GetType) of - TypeCode.Double, - TypeCode.Single, - TypeCode.Decimal: - f.sw.Write(FormatFloatNumber(val.ToString)); + TypeCode.Double, + TypeCode.Single, + TypeCode.Decimal: + f.sw.Write(FormatFloatNumber(val.ToString)); else - f.sw.Write(val) + f.sw.Write(val) end;} end; @@ -5389,7 +5696,7 @@ begin raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED)); if f.sw = nil then raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED_FOR_WRITING)); - + f.sw.WriteLine; end; @@ -5515,7 +5822,7 @@ end; procedure Reset(f: Text); begin - Reset(f,DefaultEncoding) + Reset(f, DefaultEncoding) end; procedure Reset(f: Text; en: Encoding); @@ -5540,18 +5847,18 @@ end; procedure Reset(f: Text; name: string); begin - Reset(f,name,DefaultEncoding) + Reset(f, name, DefaultEncoding) end; procedure Reset(f: Text; name: string; en: Encoding); begin assign(f, name); - reset(f,en); + reset(f, en); end; procedure Rewrite(f: Text); begin - Rewrite(f,DefaultEncoding) + Rewrite(f, DefaultEncoding) end; procedure Rewrite(f: Text; en: Encoding); @@ -5575,18 +5882,18 @@ end; procedure Rewrite(f: Text; name: string); begin - Rewrite(f,name,DefaultEncoding) + Rewrite(f, name, DefaultEncoding) end; procedure Rewrite(f: Text; name: string; en: Encoding); begin Assign(f, name); - Rewrite(f,en); + Rewrite(f, en); end; procedure Append(f: Text); begin - Append(f,DefaultEncoding) + Append(f, DefaultEncoding) end; procedure Append(f: Text; en: Encoding); @@ -5598,48 +5905,48 @@ end; procedure Append(f: Text; name: string); begin - Append(f,name,DefaultEncoding) + Append(f, name, DefaultEncoding) end; procedure Append(f: Text; name: string; en: Encoding); begin Assign(f, name); - Append(f,en); + Append(f, en); end; function OpenRead(fname: string): Text; begin - Result := OpenRead(fname,DefaultEncoding) + Result := OpenRead(fname, DefaultEncoding) end; function OpenRead(fname: string; en: Encoding): Text; begin var f: Text := new Text; - Reset(f,fname,en); + Reset(f, fname, en); Result := f; end; function OpenWrite(fname: string): Text; begin - Result := OpenWrite(fname,DefaultEncoding) + Result := OpenWrite(fname, DefaultEncoding) end; function OpenWrite(fname: string; en: Encoding): Text; begin var f: Text := new Text; - Rewrite(f,fname,en); + Rewrite(f, fname, en); Result := f; end; function OpenAppend(fname: string): Text; begin - Result := OpenAppend(fname,DefaultEncoding) + Result := OpenAppend(fname, DefaultEncoding) end; function OpenAppend(fname: string; en: Encoding): Text; begin var f: Text := new Text; - Append(f,fname,en); + Append(f, fname, en); Result := f; end; @@ -5662,8 +5969,6 @@ begin end; function SeekEof(f: Text): boolean; -var - i: integer; begin if f.sw <> nil then raise new IOException(GetTranslation(SEEKEOF_FOR_TEXT_WRITEOPENED)); @@ -5672,7 +5977,7 @@ begin repeat if f.sr.EndOfStream then break; - i := f.sr.Peek; + var i := f.sr.Peek; if not char.IsWhiteSpace(char(i)) then break; f.sr.Read; @@ -5728,62 +6033,62 @@ end; // ----------------------------------------------------- function ReadLines(path: string): sequence of string; begin - Result := ReadLines(path,DefaultEncoding); + Result := ReadLines(path, DefaultEncoding); end; function ReadLines(path: string; en: Encoding): sequence of string; begin - Result := System.IO.File.ReadLines(path,en); + Result := System.IO.File.ReadLines(path, en); end; function ReadAllLines(path: string): array of string; begin - Result := ReadAllLines(path,DefaultEncoding); + Result := ReadAllLines(path, DefaultEncoding); end; function ReadAllLines(path: string; en: Encoding): array of string; begin - Result := System.IO.File.ReadAllLines(path,en); + Result := System.IO.File.ReadAllLines(path, en); end; function ReadAllText(path: string): string; begin - Result := ReadAllText(path,DefaultEncoding); + Result := ReadAllText(path, DefaultEncoding); end; function ReadAllText(path: string; en: Encoding): string; begin - Result := System.IO.File.ReadAllText(path,en); + Result := System.IO.File.ReadAllText(path, en); end; procedure WriteLines(path: string; ss: sequence of string); begin - WriteLines(path,ss,DefaultEncoding); + WriteLines(path, ss, DefaultEncoding); end; procedure WriteLines(path: string; ss: sequence of string; en: Encoding); begin - System.IO.File.WriteAllLines(path,ss,en); + System.IO.File.WriteAllLines(path, ss, en); end; procedure WriteAllLines(path: string; ss: array of string); begin - WriteAllLines(path,ss,DefaultEncoding); + WriteAllLines(path, ss, DefaultEncoding); end; procedure WriteAllLines(path: string; ss: array of string; en: Encoding); begin - System.IO.File.WriteAllLines(path,ss,en); + System.IO.File.WriteAllLines(path, ss, en); end; procedure WriteAllText(path: string; s: string); begin - System.IO.File.WriteAllText(path,s,DefaultEncoding); + System.IO.File.WriteAllText(path, s, DefaultEncoding); end; procedure WriteAllText(path: string; s: string; en: Encoding); begin - System.IO.File.WriteAllText(path,s,en); + System.IO.File.WriteAllText(path, s, en); end; // ----------------------------------------------------- @@ -5908,18 +6213,18 @@ begin with f.br do case System.Type.GetTypeCode(t) of TypeCode.Boolean: Result := ReadBoolean; - TypeCode.Byte: Result := ReadByte; - TypeCode.Char: Result := ReadChar; + TypeCode.Byte: Result := ReadByte; + TypeCode.Char: Result := ReadChar; TypeCode.Decimal: Result := ReadDecimal; - TypeCode.Double: Result := ReadDouble; - TypeCode.Int16: Result := ReadInt16; - TypeCode.Int32: Result := ReadInt32; - TypeCode.Int64: Result := ReadInt64; - TypeCode.UInt16: Result := ReadUInt16; - TypeCode.UInt32: Result := ReadUInt32; - TypeCode.UInt64: Result := ReadUInt64; - TypeCode.SByte: Result := ReadSByte; - TypeCode.Single: Result := ReadSingle; + TypeCode.Double: Result := ReadDouble; + TypeCode.Int16: Result := ReadInt16; + TypeCode.Int32: Result := ReadInt32; + TypeCode.Int64: Result := ReadInt64; + TypeCode.UInt16: Result := ReadUInt16; + TypeCode.UInt32: Result := ReadUInt32; + TypeCode.UInt64: Result := ReadUInt64; + TypeCode.SByte: Result := ReadSByte; + TypeCode.Single: Result := ReadSingle; end; end @@ -6195,7 +6500,7 @@ end; // ----------------------------------------------------- function PascalABCVersion: string; begin - Result := '3.2.0.1364'; + Result := '3.2.0.1364'{PABC_VERSION}; end; function ParamCount: integer; @@ -6310,17 +6615,18 @@ begin //var currentLine := stackTrace.GetFrame(ind).GetFileLineNumber(); //var currentFile := stackTrace.GetFrame(ind).GetFileName(); if not IsWDE then - System.Diagnostics.Debug.Assert(cond,'Файл '+sourceFile+', строка '+line.ToString()) + System.Diagnostics.Debug.Assert(cond, 'Файл ' + sourceFile + ', строка ' + line.ToString()) else if not cond then begin - var err := 'Сбой подтверждения: '+Environment.NewLine+'Файл '+sourceFile+', строка '+line.ToString(); + var err := 'Сбой подтверждения: ' + Environment.NewLine + 'Файл ' + sourceFile + ', строка ' + line.ToString(); writeln(err); System.Threading.Thread.Sleep(500); raise new Exception(); end; end else - System.Diagnostics.Debug.Assert(cond); + //System.Diagnostics.Debug.Assert(cond); + System.Diagnostics.Contracts.Contract.Assert(cond,'Файл '+sourceFile+', строка '+line.ToString()) end; procedure Assert(cond: boolean; message: string; sourceFile: string; line: integer); @@ -6334,17 +6640,18 @@ begin //var currentLine := stackTrace.GetFrame(ind).GetFileLineNumber(); //var currentFile := stackTrace.GetFrame(ind).GetFileName(); if not IsWDE then - System.Diagnostics.Debug.Assert(cond,'Файл '+sourceFile+', строка '+line.ToString()+': '+message) + System.Diagnostics.Debug.Assert(cond, 'Файл ' + sourceFile + ', строка ' + line.ToString() + ': ' + message) else if not cond then begin - var err := 'Сбой подтверждения: '+message+Environment.NewLine+'Файл '+sourceFile+', строка '+line.ToString(); - writeln(err); + var err := 'Сбой подтверждения: ' + message + Environment.NewLine + 'Файл ' + sourceFile + ', строка ' + line.ToString(); + Writeln(err); System.Threading.Thread.Sleep(500); raise new Exception(); end; end else - System.Diagnostics.Debug.Assert(cond, message); + //System.Diagnostics.Debug.Assert(cond, message); + System.Diagnostics.Contracts.Contract.Assert(cond,'Файл '+sourceFile+', строка '+line.ToString() + ': ' + message) end; function DiskFree(diskname: string): int64; @@ -6397,7 +6704,8 @@ begin Result := DiskSize(ConvertDiskToDiskName(disk)); end; -var curr_time := DateTime.Now; +var + curr_time := DateTime.Now; function Milliseconds: integer; begin @@ -6457,32 +6765,29 @@ begin System.Diagnostics.Process.Start(filename) end; -procedure Execute(filename: string; args: string); -begin - System.Diagnostics.Process.Start(filename, args) -end; +procedure Execute(filename: string; args: string) := System.Diagnostics.Process.Start(filename, args); // ----------------------------------------------------- // EnumerateFiles, EnumerateDirectories // ----------------------------------------------------- function EnumerateFiles(path: string; searchPattern: string): sequence of string; begin - Result := System.IO.Directory.EnumerateFiles(path,searchPattern,System.IO.SearchOption.TopDirectoryOnly) + Result := System.IO.Directory.EnumerateFiles(path, searchPattern, System.IO.SearchOption.TopDirectoryOnly) end; function EnumerateAllFiles(path: string; searchPattern: string): sequence of string; begin - Result := System.IO.Directory.EnumerateFiles(path,searchPattern,System.IO.SearchOption.AllDirectories) + Result := System.IO.Directory.EnumerateFiles(path, searchPattern, System.IO.SearchOption.AllDirectories) end; function EnumerateDirectories(path: string): sequence of string; begin - Result := System.IO.Directory.EnumerateDirectories(path,'*.*',System.IO.SearchOption.TopDirectoryOnly) + Result := System.IO.Directory.EnumerateDirectories(path, '*.*', System.IO.SearchOption.TopDirectoryOnly) end; function EnumerateAllDirectories(path: string): sequence of string; begin - Result := System.IO.Directory.EnumerateDirectories(path,'*.*',System.IO.SearchOption.AllDirectories) + Result := System.IO.Directory.EnumerateDirectories(path, '*.*', System.IO.SearchOption.AllDirectories) end; // ----------------------------------------------------- @@ -6504,7 +6809,7 @@ function ExtractFilePath(fname: string): string; begin var fi := new System.IO.FileInfo(fname); Result := fi.DirectoryName; - if (Result.Length > 0) and (Result[Result.Length] <> '\') and (Result[Result.Length] <> '/') then + if (Result.Length > 0) and (Result[Result.Length] <> '\') and (Result[Result.Length] <> '/') then Result += '\'; end; @@ -6618,188 +6923,115 @@ begin Result := Math.Abs(x); end; -function Sin(x: real): real; +function Abs(x: single): single; begin - Result := Math.Sin(x); + Result := Math.Abs(x); end; -function Sinh(x: real): real; +function Sin(x: real) := Math.Sin(x); + +function Sinh(x: real) := Math.Sinh(x); + +function Cos(x: real) := Math.Cos(x); + +function Cosh(x: real) := Math.Cosh(x); + +function Tan(x: real) := Math.Tan(x); + +function Tanh(x: real) := Math.Tanh(x); + +function ArcSin(x: real) := Math.Asin(x); + +function ArcCos(x: real) := Math.Acos(x); + +function ArcTan(x: real) := Math.Atan(x); + +function Exp(x: real) := Math.Exp(x); + +function Ln(x: real) := Math.Log(x); + +function Log(x: real) := Math.Log(x); + +function Log2(x: real) := LogN(2, x); + +function Log10(x: real) := Math.Log10(x); + +function LogN(base, x: real) := Math.Log(x) / Math.Log(base); + +function Sqrt(x: real) := Math.Sqrt(x); + +function Sqr(x: integer): int64 := x * x; + +function Sqr(x: shortint): integer := x * x; + +function Sqr(x: smallint): integer := x * x; + +function Sqr(x: BigInteger): BigInteger := x * x; + +function Sqr(x: longword): uint64 := x * x; + +function Sqr(x: int64): int64 := x * x; + +function Sqr(x: uint64): uint64 := x * x; + +function Sqr(x: real): real := x * x; + +function Power(x, y: real): real := Math.Pow(x, y); + +//function Power(x, y: integer): real := Math.Pow(x, y); + +function Power(x: real; n: integer): real; begin - Result := Math.Sinh(x); + case n of + 0: Result := 1; + 1: Result := x; + 2: Result := x*x; + 3: Result := x*x*x; + 4: Result := x*x*x*x; + 5: Result := x*x*x*x*x; + 6: Result := x*x*x*x*x*x; + else + if n<0 then + Result := 1/Power(x,-n) + else + begin + var z := x; + var r := 1.0; + while n > 0 do + begin + if n and 1 = 1 then + r := r * z; + z := z * z; + n := n shr 1; + end; + Result := r; + end; + end; end; -function Cos(x: real): real; -begin - Result := Math.Cos(x); -end; +function Power(x: BigInteger; y: integer) := BigInteger.Pow(x, y); -function Cosh(x: real): real; -begin - Result := Math.Cosh(x); -end; +function Round(x: real) := Convert.ToInt32(Math.Round(x)); -function Tan(x: real): real; -begin - Result := Math.Tan(x); -end; +function Round(x: real; digits: integer) := Math.Round(x,digits); -function Tanh(x: real): real; -begin - Result := Math.Tanh(x); -end; +function RoundBigInteger(x: real) := BigInteger.Create(Math.Round(x)); -function ArcSin(x: real): real; -begin - Result := Math.Asin(x); -end; +function Trunc(x: real) := Convert.ToInt32(Math.Truncate(x)); -function ArcCos(x: real): real; -begin - Result := Math.Acos(x); -end; +function TruncBigInteger(x: real) := BigInteger.Create(Math.Truncate(x)); -function ArcTan(x: real): real; -begin - Result := Math.Atan(x); -end; +function Int(x: real) := x >= 0 ? Math.Floor(x) : Math.Ceiling(x); -function Exp(x: real): real; -begin - Result := Math.Exp(x); -end; +function Frac(x: real) := x - Int(x); -function Ln(x: real): real; -begin - Result := Math.Log(x); -end; +function Floor(x: real) := Convert.ToInt32(Math.Floor(x)); -function Log2(x: real): real; -begin - Result := LogN(2, x); -end; +function Ceil(x: real) := Convert.ToInt32(Math.Ceiling(x)); -function Log10(x: real): real; -begin - Result := Math.Log10(x); -end; +function RadToDeg(x: real) := x * 180 / Pi; -function LogN(base, x: real): real; -begin - Result := Math.Log(x) / Math.Log(base); -end; - -function Sqrt(x: real): real; -begin - Result := Math.Sqrt(x); -end; - -function Sqr(x: integer): int64; -begin - Result := x * x; -end; - -function Sqr(x: shortint): integer; -begin - Result := x * x; -end; - -function Sqr(x: smallint): integer; -begin - Result := x * x; -end; - -function Sqr(x: BigInteger): BigInteger; -begin - Result := x * x; -end; - -function Sqr(x: longword): uint64; -begin - Result := x * x; -end; - -function Sqr(x: int64): int64; -begin - Result := x * x; -end; - -function Sqr(x: uint64): uint64; -begin - Result := x * x; -end; - -function Sqr(x: real): real; -begin - Result := x * x; -end; - -function Power(x, y: real): real; -begin - Result := Math.Pow(x, y); -end; - -function Power(x, y: integer): real; -begin - Result := Math.Pow(x, y); -end; - -function Power(x: BigInteger; y: integer): BigInteger; -begin - Result := BigInteger.Pow(x, y) -end; - -function Round(x: real): integer; -begin - Result := Convert.ToInt32(Math.Round(x)); -end; - -function RoundBigInteger(x: real): BigInteger; -begin - Result := BigInteger.Create(Math.Round(x)); -end; - -function Trunc(x: real): integer; -begin - Result := Convert.ToInt32(Math.Truncate(x)); -end; - -function TruncBigInteger(x: real): BigInteger; -begin - Result := BigInteger.Create(Math.Truncate(x)); -end; - -function Int(x: real): real; -begin - //if x>=0 then - // Result := Math.Floor(x) - //else Result := Math.Ceiling(x); - Result := x >= 0 ? Math.Floor(x) : Math.Ceiling(x); -end; - -function Frac(x: real): real; -begin - Result := x - Int(x); -end; - -function Floor(x: real): integer; -begin - Result := Convert.ToInt32(Math.Floor(x)); -end; - -function Ceil(x: real): integer; -begin - Result := Convert.ToInt32(Math.Ceiling(x)); -end; - -function RadToDeg(x: real): real; -begin - Result := x * 180 / Pi; -end; - -function DegToRad(x: real): real; -begin - Result := x * Pi / 180; -end; +function DegToRad(x: real) := x * Pi / 180; procedure Randomize; begin @@ -6811,10 +7043,7 @@ begin rnd := new System.Random(seed); end; -function Random(MaxValue: integer): integer; -begin - Result := rnd.Next(MaxValue); -end; +function Random(MaxValue: integer) := rnd.Next(MaxValue); function Random(a, b: integer): integer; begin @@ -6822,10 +7051,20 @@ begin Result := rnd.Next(a, b + 1); end; -function Random: real; -begin - Result := rnd.NextDouble; -end; +function Random := rnd.NextDouble; + +function Random2(maxValue: integer) := (Random(maxValue), Random(maxValue)); + +function Random2(a, b: integer) := (Random(a, b), Random(a, b)); + +function Random2 := (Random, Random); + +function Random3(maxValue: integer) := (Random(maxValue), Random(maxValue), Random(maxValue)); + +function Random3(a, b: integer) := (Random(a, b), Random(a, b), Random(a, b)); + +function Random3 := (Random, Random, Random); + function Max(a, b: byte): byte; begin @@ -6854,7 +7093,7 @@ end; function Max(a, b: BigInteger): BigInteger; begin - Result := BigInteger.Max(a,b); + Result := BigInteger.Max(a, b); end; function Max(a, b: longword): longword; @@ -6904,7 +7143,7 @@ end; function Min(a, b: BigInteger): BigInteger; begin - Result := BigInteger.Min(a,b); + Result := BigInteger.Min(a, b); end; function Min(a, b: longword): longword; @@ -6947,41 +7186,42 @@ begin result := (i mod 2) <> 0; end; -function Odd(i: integer): boolean; -begin - result := (i mod 2) <> 0; -end; +function Odd(i: integer) := (i mod 2) <> 0; function Odd(i: BigInteger): boolean; begin Result := not i.IsEven; end; -function Odd(i: longword): boolean; -begin - result := (i mod 2) <> 0; -end; +function Odd(i: longword) := (i mod 2) <> 0; -function Odd(i: int64): boolean; -begin - result := (i mod 2) <> 0; -end; +function Odd(i: int64) := (i mod 2) <> 0; -function Odd(i: uint64): boolean; -begin - result := (i mod 2) <> 0; -end; +function Odd(i: uint64) := (i mod 2) <> 0; -function Cplx(re,im: real): Complex; -begin - Result := new Complex(re,im); -end; +function Cplx(re, im: real) := new Complex(re, im); -function Sqrt(c: Complex): Complex; -begin - Result := Complex.Sqrt(c); -end; +function CplxFromPolar(magnitude, phase: real) := Complex.FromPolarCoordinates(magnitude, phase); +function Sqrt(c: Complex) := Complex.Sqrt(c); + +function Abs(c: Complex) := Complex.Abs(c); + +function Conjugate(c: Complex) := Complex.Conjugate(c); + +function Cos(c: Complex) := Complex.Cos(c); + +function Exp(c: Complex) := Complex.Exp(c); + +function Log(c: Complex) := Complex.Log(c); + +function Ln(c: Complex) := Complex.Log(c); + +function Log10(c: Complex) := Complex.Log10(c); + +function Power(c, power: Complex) := Complex.Pow(c, power); + +function Sin(c: Complex) := Complex.Sin(c); // ----------------------------------------------------- // Dynamic arrays: implementation @@ -7026,12 +7266,12 @@ end; procedure Sort(a: array of T; cmp: (T,T)->integer); begin - System.Array.Sort(a,cmp); + System.Array.Sort(a, cmp); end; procedure Sort(a: array of T; less: (T,T)->boolean); begin - System.Array.Sort(a,(x,y)->less(x,y)?-1:(less(y,x)?1:0)); + System.Array.Sort(a, (x, y)-> less(x, y) ? -1 : (less(y, x) ? 1 : 0)); end; procedure Sort(l: List); @@ -7046,7 +7286,7 @@ end; procedure Sort(l: List; less: (T,T)->boolean); begin - l.Sort((x,y)->less(x,y)?-1:(less(y,x)?1:0)); + l.Sort((x, y)-> less(x, y) ? -1 : (less(y, x) ? 1 : 0)); end; procedure Reverse(a: array of T); @@ -7054,23 +7294,34 @@ begin System.Array.Reverse(a); end; -procedure Reverse(a: array of T; index,length: integer); +procedure Reverse(a: array of T; index, count: integer); begin - System.Array.Reverse(a,index,length); + System.Array.Reverse(a, index, count); end; +procedure Reverse(a: List); +begin + a.Reverse +end; + +procedure Reverse(a: List; index, count: integer); +begin + a.Reverse(index, count) +end; + + procedure Shuffle(a: array of T); begin var n := a.Length; - for var i:=0 to n-1 do - Swap(a[i],a[Random(n)]); + for var i := 0 to n - 1 do + Swap(a[i], a[Random(n)]); end; procedure Shuffle(l: List); begin var n := l.Count; - for var i:=0 to n-1 do - begin + for var i := 0 to n - 1 do + begin var v := l[i]; l[i] := l[Random(n)]; l[Random(n)] := v; @@ -7204,51 +7455,47 @@ end; function Pos(subs, s: string; from: integer): integer; begin - if (subs = nil) or (subs.Length = 0) then + if (subs = nil) or (subs.Length = 0) or (from > s.Length) then Result := 0 - else Result := s.IndexOf(subs, from - 1,System.StringComparison.Ordinal) + 1; + else Result := s.IndexOf(subs, from - 1, System.StringComparison.Ordinal) + 1; end; -function PosEx(subs, s: string; from: integer): integer; -begin - if (subs = nil) or (subs.Length = 0) then - Result := 0 - else Result := s.IndexOf(subs, from - 1,System.StringComparison.Ordinal) + 1; -end; +function PosEx(subs, s: string; from: integer) := Pos(subs,s,from); function LastPos(subs, s: string): integer; begin if (subs = nil) or (subs.Length = 0) then Result := 0 - else Result := s.LastIndexOf(subs, s.Length - 1,System.StringComparison.Ordinal) + 1; + else Result := s.LastIndexOf(subs, s.Length - 1, System.StringComparison.Ordinal) + 1; end; function LastPos(subs, s: string; from: integer): integer; begin - if (subs = nil) or (subs.Length = 0) then + if (subs = nil) or (subs.Length = 0) or (from > s.Length) then Result := 0 - else Result := s.LastIndexOf(subs, from - 1,System.StringComparison.Ordinal) + 1; + else Result := s.LastIndexOf(subs, from - 1, System.StringComparison.Ordinal) + 1; end; -function Pos(c: char; s: string; from: integer): integer; +{function Pos(c: char; s: string; from: integer): integer; begin - Result := s.IndexOf(c, from - 1,System.StringComparison.Ordinal) + 1; + if from > s.Length then + Result := 0; + Result := s.IndexOf(c, from - 1, System.StringComparison.Ordinal) + 1; end; -function PosEx(c: char; s: string; from: integer): integer; -begin - Result := s.IndexOf(c, from - 1,System.StringComparison.Ordinal) + 1; -end; +function PosEx(c: char; s: string; from: integer) := Pos(c,s,from); function LastPos(c: char; s: string): integer; begin - Result := s.LastIndexOf(c, s.Length - 1,System.StringComparison.Ordinal) + 1; + Result := s.LastIndexOf(c, s.Length - 1, System.StringComparison.Ordinal) + 1; end; function LastPos(c: char; s: string; from: integer): integer; begin - Result := s.LastIndexOf(c, from - 1,System.StringComparison.Ordinal) + 1; -end; + if from > s.Length then + Result := 0; + Result := s.LastIndexOf(c, from - 1, System.StringComparison.Ordinal) + 1; +end;} function Length(s: string): integer; begin @@ -7279,7 +7526,7 @@ begin s := s.Substring(0, n) else if s.Length < n then if n <= sz then - s += new string(' ', n - s.Length ) + s += new string(' ', n - s.Length) else s += new String(' ', sz - s.Length) end; @@ -7292,12 +7539,6 @@ begin if index > s.Length + 1 then index := s.Length + 1; s := s.Insert(index - 1, source); - { try - s := s.Insert(index - 1, source); - except - on e: System.Exception do - s := s.Insert(s.Length, source); - end;} end; procedure InsertInShortString(source: string; var s: string; index, n: integer); @@ -7338,14 +7579,6 @@ begin if index + count - 1 > s.Length then count := s.Length - index + 1; Result := s.SubString(index - 1, count); - { try - if index - 1 >= s.Length then - Result := '' - else Result := s.SubString(index - 1, count); - except - on e: System.Exception do - Result := s.Substring(index - 1, s.Length - index + 1); - end;} end; function Concat(s1, s2: string): string; @@ -7560,7 +7793,7 @@ end; function TryStrToFloat(s: string; var value: real): boolean; begin - try + try Result := True; value := Convert.ToDouble(s, nfi); except @@ -7571,7 +7804,7 @@ end; function TryStrToFloat(s: string; var value: single): boolean; begin - try + try Result := True; value := Convert.ToSingle(s, nfi); except @@ -7675,7 +7908,7 @@ end; procedure Val(s: string; var value: single; var err: integer); begin - try + try err := 0; value := Convert.ToSingle(s, nfi); except @@ -7833,7 +8066,7 @@ end; //------------------------------------------------------------------------------ //PRED-SUCC -function succ(x: boolean): boolean; +function succ(x: boolean): boolean; begin Result := not x; end; @@ -7908,7 +8141,7 @@ begin Result := x - 1; end; -function pred(x: integer): integer; +function pred(x: integer): integer; begin Result := x - 1; end; @@ -7949,16 +8182,16 @@ end; // Возвращает бесконечную рекуррентную последовательность элементов, задаваемую начальным элементом и функцией next ///-- -function Iterate(Self: T; next: T -> T): sequence of T; extensionmethod; +function Iterate(Self: T; next: T->T): sequence of T; extensionmethod; begin - Result := Iterate&(Self,next); + Result := Iterate&(Self, next); end; // Возвращает бесконечную рекуррентную последовательность элементов, задаваемую начальным элементом, следующим за ним элементом и функцией next ///-- -function Iterate(Self,second: T; next: (T,T) -> T): sequence of T; extensionmethod; +function Iterate(Self, second: T; next: (T,T) ->T): sequence of T; extensionmethod; begin - Result := Iterate&(Self,second,next); + Result := Iterate&(Self, second, next); end; /// Возвращает бесконечную последовательность целых от текущего значения с шагом 1 @@ -8009,6 +8242,107 @@ begin end; end; +// ----------------------------------------------------- +//>> Фиктивная секция XXX - не удалять! # XXX +// ----------------------------------------------------- +type + AdjGroupClass = class + private + cur: T; + enm: IEnumerator; + fin: boolean; + public + constructor Create(a: sequence of T); + begin + enm := a.GetEnumerator(); + fin := enm.MoveNext; + if fin then + cur := enm.Current; + end; + + function TakeGroup: sequence of T; + begin + yield cur; + fin := enm.movenext; + while fin do + begin + if enm.current = cur then + yield enm.current + else + begin + cur := enm.Current; + break; + end; + fin := enm.movenext; + end; + end; + end; + +//------------------------------------------------------------------------------ +//>> Метод расширения Print для элементарных типов # Print for elementary types +//------------------------------------------------------------------------------ +function Print(Self: integer): integer; extensionmethod; +begin + PABCSystem.Print(Self); + Result := Self; +end; + +function Print(Self: real): real; extensionmethod; +begin + PABCSystem.Print(Self); + Result := Self; +end; + +function Print(Self: char): char; extensionmethod; +begin + PABCSystem.Print(Self); + Result := Self; +end; + +function Print(Self: boolean): boolean; extensionmethod; +begin + PABCSystem.Print(Self); + Result := Self; +end; + +function Print(Self: BigInteger): BigInteger; extensionmethod; +begin + PABCSystem.Print(Self); + Result := Self; +end; + +function Println(Self: integer): integer; extensionmethod; +begin + PABCSystem.Println(Self); + Result := Self; +end; + +function Println(Self: real): real; extensionmethod; +begin + PABCSystem.Println(Self); + Result := Self; +end; + +function Println(Self: char): char; extensionmethod; +begin + PABCSystem.Println(Self); + Result := Self; +end; + +function Println(Self: boolean): boolean; extensionmethod; +begin + PABCSystem.Println(Self); + Result := Self; +end; + +function Println(Self: BigInteger): BigInteger; extensionmethod; +begin + PABCSystem.Println(Self); + Result := Self; +end; + + + //------------------------------------------------------------------------------ //>> Методы расширения для sequence of T # Extension methods for sequence of T //------------------------------------------------------------------------------ @@ -8017,18 +8351,18 @@ function Print(Self: sequence of T; delim: string): sequence of T; extensionm begin var g := Self.GetEnumerator(); if g.MoveNext() then - write(g.Current); + Write(g.Current); while g.MoveNext() do - if delim<>'' then - write(delim, g.Current) - else write(g.Current); - Result := Self; + if delim <> '' then + Write(delim, g.Current) + else Write(g.Current); + Result := Self; end; /// Выводит последовательность на экран, используя пробел в качестве разделителя function Print(Self: sequence of T): sequence of T; extensionmethod; begin - if typeof(T)=typeof(char) then + if typeof(T) = typeof(char) then Result := Self.Print('') else Result := Self.Print(PrintDelimDefault); @@ -8045,7 +8379,7 @@ end; /// Выводит последовательность на экран, используя пробел качестве разделителя, и переходит на новую строку function Println(Self: sequence of T): sequence of T; extensionmethod; begin - if typeof(T)=typeof(char) then + if typeof(T) = typeof(char) then Result := Self.Println('') else Result := Self.Println(PrintDelimDefault); @@ -8054,7 +8388,14 @@ end; /// Выводит последовательность строк в файл function WriteLines(Self: sequence of string; fname: string): sequence of string; extensionmethod; begin - WriteLines(fname,Self); + WriteLines(fname, Self); + Result := Self +end; + +/// Выводит последовательность, каждый элемент выводится на новой строке +function PrintLines(Self: sequence of T): sequence of T; extensionmethod; +begin + Self.Println(NewLine); Result := Self end; @@ -8091,7 +8432,7 @@ begin var i := 0; foreach x: T in Self do begin - action(x,i); + action(x, i); i += 1; end; end; @@ -8130,51 +8471,51 @@ end; // Partition, ZipTuple, UnZipTuple, Interleave, Numerate, Tabulate, Pairwise, Batch /// Возвращает первый элемент последовательности с минимальным значением ключа -function MinBy(Self: sequence of T; selector: T -> TKey): T; extensionmethod; +function MinBy(Self: sequence of T; selector: T->TKey): T; extensionmethod; begin if selector = nil then raise new ArgumentNullException('selector'); if not Self.Any() then raise new InvalidOperationException('Empty sequence'); - + var comp := Comparer&.Default; - Result := Self.Aggregate((min,x)-> comp.Compare(selector(x),selector(min))<0 ? x : min); + Result := Self.Aggregate((min, x)-> comp.Compare(selector(x), selector(min)) < 0 ? x : min); end; /// Возвращает первый элемент последовательности с максимальным значением ключа -function MaxBy(Self: sequence of T; selector: T -> TKey): T; extensionmethod; +function MaxBy(Self: sequence of T; selector: T->TKey): T; extensionmethod; begin if selector = nil then raise new ArgumentNullException('selector'); if not Self.Any() then raise new InvalidOperationException('Empty sequence'); - + var comp := Comparer&.Default; - Result := Self.Aggregate((max,x)-> comp.Compare(selector(x),selector(max))>0 ? x : max); + Result := Self.Aggregate((max, x)-> comp.Compare(selector(x), selector(max)) > 0 ? x : max); end; /// Возвращает последний элемент последовательности с минимальным значением ключа -function LastMinBy(Self: sequence of T; selector: T -> TKey): T; extensionmethod; +function LastMinBy(Self: sequence of T; selector: T->TKey): T; extensionmethod; begin if selector = nil then raise new ArgumentNullException('selector'); if not Self.Any() then raise new InvalidOperationException('Empty sequence'); - + var comp := Comparer&.Default; - Result := Self.Aggregate((min,x)-> comp.Compare(selector(x),selector(min))<=0 ? x : min); + Result := Self.Aggregate((min, x)-> comp.Compare(selector(x), selector(min)) <= 0 ? x : min); end; /// Возвращает последний элемент последовательности с максимальным значением ключа -function LastMaxBy(Self: sequence of T; selector: T -> TKey): T; extensionmethod; +function LastMaxBy(Self: sequence of T; selector: T->TKey): T; extensionmethod; begin if selector = nil then raise new ArgumentNullException('selector'); if not Self.Any() then raise new InvalidOperationException('Empty sequence'); - + var comp := Comparer&.Default; - Result := Self.Aggregate((max,x)-> comp.Compare(selector(x),selector(max))>=0 ? x : max); + Result := Self.Aggregate((max, x)-> comp.Compare(selector(x), selector(max)) >= 0 ? x : max); end; /// Возвращает последние count элементов последовательности @@ -8190,35 +8531,31 @@ begin end; /// Декартово произведение последовательностей -function Cartesian(Self: sequence of T; b: sequence of T1): sequence of (T,T1); extensionmethod; +function Cartesian(Self: sequence of T; b: sequence of T1): sequence of (T, T1); extensionmethod; begin - if b=nil then + if b = nil then raise new System.ArgumentNullException('b'); - - foreach var x in Self do - foreach var y in b do - yield (x,y) - //Result := Self.Select(x->b.Select(y->(x,y))).SelectMany(x->x); + foreach var x in Self do + foreach var y in b do + yield (x, y) end; /// Декартово произведение последовательностей -function Cartesian(Self: sequence of T; b: sequence of T1; func: (T,T1)->T2): sequence of T2; extensionmethod; +function Cartesian(Self: sequence of T; b: sequence of T1; func: (T,T1)->T2): sequence of T2; extensionmethod; begin - if b=nil then + if b = nil then raise new System.ArgumentNullException('b'); - + foreach var x in Self do - foreach var y in b do - yield func(x,y) - -// Result := Self.Select(x->b.Select(y->(x,y))).SelectMany(x->x).Select(x->func(x[0],x[1])); + foreach var y in b do + yield func(x, y) end; /// Разбивает последовательности на две в позиции ind -function SplitAt(Self: sequence of T; ind: integer): (sequence of T,sequence of T); extensionmethod; +function SplitAt(Self: sequence of T; ind: integer): (sequence of T, sequence of T); extensionmethod; begin - Result := (Self.Take(ind),Self.Skip(ind)); + Result := (Self.Take(ind), Self.Skip(ind)); end; // ToDo: то же для TakeWhile @@ -8226,63 +8563,63 @@ end; // ToDo: SequenceCompare /// Разделяет последовательности на две по заданному условию -function Partition(Self: sequence of T; cond: T->boolean): (sequence of T,sequence of T); extensionmethod; +function Partition(Self: sequence of T; cond: T->boolean): (sequence of T, sequence of T); extensionmethod; begin - Result := (Self.Where(cond),Self.Where(x->not cond(x))); + Result := (Self.Where(cond), Self.Where(x -> not cond(x))); end; /// Разделяет последовательности на две по заданному условию, в котором участвует индекс -function Partition(Self: sequence of T; cond: (T,integer)->boolean): (sequence of T,sequence of T); extensionmethod; +function Partition(Self: sequence of T; cond: (T,integer)->boolean): (sequence of T, sequence of T); extensionmethod; begin - Result := (Self.Where(cond),Self.Where((x,i)->not cond(x,i))); + Result := (Self.Where(cond), Self.Where((x, i)-> not cond(x, i))); end; /// Объединяет две последовательности в последовательность двухэлементных кортежей -function ZipTuple(Self: sequence of T; a: sequence of T1): sequence of (T,T1); extensionmethod; +function ZipTuple(Self: sequence of T; a: sequence of T1): sequence of (T, T1); extensionmethod; begin - if a=nil then + if a = nil then raise new System.ArgumentNullException('a'); - Result := Self.Zip(a,(x,y)->(x,y)); + Result := Self.Zip(a, (x, y)-> (x, y)); end; /// Объединяет три последовательности в последовательность трехэлементных кортежей -function ZipTuple(Self: sequence of T; a: sequence of T1; b: sequence of T2): sequence of (T,T1,T2); extensionmethod; +function ZipTuple(Self: sequence of T; a: sequence of T1; b: sequence of T2): sequence of (T, T1, T2); extensionmethod; begin - if a=nil then + if a = nil then raise new System.ArgumentNullException('a'); - if b=nil then + if b = nil then raise new System.ArgumentNullException('b'); - Result := Self.Zip(a,(x,y)->(x,y)).Zip(b,(p,z)->(p[0],p[1],z)); + Result := Self.Zip(a, (x, y)-> (x, y)).Zip(b, (p, z)-> (p[0], p[1], z)); end; /// Объединяет четыре последовательности в последовательность четырехэлементных кортежей -function ZipTuple(Self: sequence of T; a: sequence of T1; b: sequence of T2; c: sequence of T3): sequence of (T,T1,T2,T3); extensionmethod; +function ZipTuple(Self: sequence of T; a: sequence of T1; b: sequence of T2; c: sequence of T3): sequence of (T, T1, T2, T3); extensionmethod; begin - if a=nil then + if a = nil then raise new System.ArgumentNullException('a'); - if b=nil then + if b = nil then raise new System.ArgumentNullException('b'); - if c=nil then + if c = nil then raise new System.ArgumentNullException('c'); - Result := Self.Zip(a,(x,y)->(x,y)).Zip(b,(p,z)->(p[0],p[1],z)).Zip(c,(p,z)->(p[0],p[1],p[2],z)); + Result := Self.Zip(a, (x, y)-> (x, y)).Zip(b, (p, z)-> (p[0], p[1], z)).Zip(c, (p, z)-> (p[0], p[1], p[2], z)); end; /// Разъединяет последовательность двухэлементных кортежей на две последовательности -function UnZipTuple(Self: sequence of (T,T1)): (sequence of T,sequence of T1); extensionmethod; +function UnZipTuple(Self: sequence of (T, T1)): (sequence of T, sequence of T1); extensionmethod; begin - Result := (Self.Select(x->x[0]),Self.Select(x->x[1])) + Result := (Self.Select(x -> x[0]), Self.Select(x -> x[1])) end; /// Разъединяет последовательность трехэлементных кортежей на три последовательности -function UnZipTuple(Self: sequence of (T,T1,T2)): (sequence of T,sequence of T1,sequence of T2); extensionmethod; +function UnZipTuple(Self: sequence of (T, T1, T2)): (sequence of T, sequence of T1, sequence of T2); extensionmethod; begin - Result := (Self.Select(x->x[0]),Self.Select(x->x[1]),Self.Select(x->x[2])) + Result := (Self.Select(x -> x[0]), Self.Select(x -> x[1]), Self.Select(x -> x[2])) end; /// Разъединяет последовательность четырехэлементных кортежей на четыре последовательности -function UnZipTuple(Self: sequence of (T,T1,T2,T3)): (sequence of T,sequence of T1,sequence of T2,sequence of T3); extensionmethod; +function UnZipTuple(Self: sequence of (T, T1, T2, T3)): (sequence of T, sequence of T1, sequence of T2, sequence of T3); extensionmethod; begin - Result := (Self.Select(x->x[0]),Self.Select(x->x[1]),Self.Select(x->x[2]),Self.Select(x->x[3])) + Result := (Self.Select(x -> x[0]), Self.Select(x -> x[1]), Self.Select(x -> x[2]), Self.Select(x -> x[3])) end; // ToDo - сделать UnZipTuple с функцией-проекцией @@ -8290,128 +8627,128 @@ end; /// Чередует элементы двух последовательностей function Interleave(Self: sequence of T; a: sequence of T): sequence of T; extensionmethod; begin - if a=nil then + if a = nil then raise new System.ArgumentNullException('a'); - Result := Self.ZipTuple(a).SelectMany(x->Seq(x[0],x[1])) + Result := Self.ZipTuple(a).SelectMany(x -> Seq(x[0], x[1])) end; /// Чередует элементы трех последовательностей -function Interleave(Self: sequence of T; a,b: sequence of T): sequence of T; extensionmethod; +function Interleave(Self: sequence of T; a, b: sequence of T): sequence of T; extensionmethod; begin - if a=nil then + if a = nil then raise new System.ArgumentNullException('a'); - if b=nil then + if b = nil then raise new System.ArgumentNullException('b'); - Result := Self.ZipTuple(a,b).SelectMany(x->Seq(x[0],x[1],x[2])) + Result := Self.ZipTuple(a, b).SelectMany(x -> Seq(x[0], x[1], x[2])) end; /// Чередует элементы четырех последовательностей -function Interleave(Self: sequence of T; a,b,c: sequence of T): sequence of T; extensionmethod; +function Interleave(Self: sequence of T; a, b, c: sequence of T): sequence of T; extensionmethod; begin - if a=nil then + if a = nil then raise new System.ArgumentNullException('a'); - if b=nil then + if b = nil then raise new System.ArgumentNullException('b'); - if c=nil then + if c = nil then raise new System.ArgumentNullException('c'); - Result := Self.ZipTuple(a,b,c).SelectMany(x->Seq(x[0],x[1],x[2],x[3])) + Result := Self.ZipTuple(a, b, c).SelectMany(x -> Seq(x[0], x[1], x[2], x[3])) end; /// Нумерует последовательность с единицы -function Numerate(Self: sequence of T): sequence of (integer,T); extensionmethod; +function Numerate(Self: sequence of T): sequence of (integer, T); extensionmethod; begin Result := 1.Step.ZipTuple(Self); end; /// Нумерует последовательность с номера from -function Numerate(Self: sequence of T; from: integer): sequence of (integer,T); extensionmethod; +function Numerate(Self: sequence of T; from: integer): sequence of (integer, T); extensionmethod; begin Result := from.Step.ZipTuple(Self); end; /// Табулирует функцию последовательностью -function Tabulate(Self: sequence of T; F: T->T1): sequence of (T,T1); extensionmethod; +function Tabulate(Self: sequence of T; F: T->T1): sequence of (T, T1); extensionmethod; begin - Result := Self.Select(x->(x,f(x))); + Result := Self.Select(x -> (x, f(x))); end; /// Превращает последовательность в последовательность пар соседних элементов -function Pairwise(Self: sequence of T): sequence of (T,T); extensionmethod; +function Pairwise(Self: sequence of T): sequence of (T, T); extensionmethod; begin var previous: T; var it := Self.GetEnumerator(); if (it.MoveNext()) then - previous := it.Current; - + previous := it.Current; + while (it.MoveNext()) do begin - yield (previous,it.Current); + yield (previous, it.Current); previous := it.Current; end end; /// Превращает последовательность в последовательность пар соседних элементов, применяет func к каждой паре полученных элементов и получает новую последовательность -function Pairwise(Self: sequence of T; func:(T,T)->Res): sequence of Res; extensionmethod; +function Pairwise(Self: sequence of T; func: (T,T)->Res): sequence of Res; extensionmethod; begin var previous: T; var it := Self.GetEnumerator(); if (it.MoveNext()) then - previous := it.Current; - + previous := it.Current; + while (it.MoveNext()) do begin - yield func(previous,it.Current); + yield func(previous, it.Current); previous := it.Current; end -// Result := Self.ZipTuple(Self.Skip(1)).Select(x->func(x[0],x[1])); + // Result := Self.ZipTuple(Self.Skip(1)).Select(x->func(x[0],x[1])); end; /// Разбивает последовательность на серии длины size function Batch(Self: sequence of T; size: integer): sequence of sequence of T; extensionmethod; begin - Result := SeqWhile(Self,v->v.Skip(size),v->v.Count>0).Select(v->v.Take(size)) + Result := SeqWhile(Self, v -> v.Skip(size), v -> v.Count > 0).Select(v -> v.Take(size)) end; /// Разбивает последовательность на серии длины size и применяет проекцию к каждой серии -function Batch(Self: sequence of T; size: integer; proj: Func,Res>): sequence of Res; extensionmethod; +function Batch(Self: sequence of T; size: integer; proj: Func, Res>): sequence of Res; extensionmethod; begin - Result := SeqWhile(Self,v->v.Skip(size),v->v.Count>0).Select(v->v.Take(size)).Select(ss->proj(ss)); + Result := SeqWhile(Self, v -> v.Skip(size), v -> v.Count > 0).Select(v -> v.Take(size)).Select(ss -> proj(ss)); end; ///-- -function SliceSeqImpl(Self: sequence of T; from,step,count: integer): sequence of T; +function SliceSeqImpl(Self: sequence of T; from, step, count: integer): sequence of T; begin if step <= 0 then raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_GREATER_0)); - + if from < 0 then raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE)); - - Result := Self.Skip(from).Where((x,i)->i mod step = 0) + + Result := Self.Skip(from).Where((x, i)-> i mod step = 0) end; /// Возвращает срез последовательности от номера from с шагом step > 0 -function Slice(Self: sequence of T; from,step: integer): sequence of T; extensionmethod; +function Slice(Self: sequence of T; from, step: integer): sequence of T; extensionmethod; begin if step <= 0 then raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_GREATER_0)); - + if from < 0 then raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE)); - - Result := Self.Skip(from).Where((x,i)->i mod step = 0) + + Result := Self.Skip(from).Where((x, i)-> i mod step = 0) end; /// Возвращает срез последовательности от номера from с шагом step > 0 длины не более count -function Slice(Self: sequence of T; from,step,count: integer): sequence of T; extensionmethod; +function Slice(Self: sequence of T; from, step, count: integer): sequence of T; extensionmethod; begin if step <= 0 then raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_GREATER_0)); - + if from < 0 then raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE)); - - Result := Self.Skip(from).Where((x,i)->i mod step = 0).Take(count) + + Result := Self.Skip(from).Where((x, i)-> i mod step = 0).Take(count) end; // Дополнения июль 2016: Incremental @@ -8496,7 +8833,7 @@ begin end;} /// Возвращает последовательность разностей соседних элементов исходной последовательности. В качестве функции разности используется func -function Incremental(Self: sequence of T; func: (T,T)->T1): sequence of T1; extensionmethod; +function Incremental(Self: sequence of T; func: (T,T)->T1): sequence of T1; extensionmethod; begin var iter := Self.GetEnumerator(); if iter.MoveNext() then @@ -8505,14 +8842,14 @@ begin while iter.MoveNext() do begin var nextItem := iter.Current; - yield func(prevItem,nextItem); + yield func(prevItem, nextItem); prevItem := nextItem; end end end; /// Возвращает последовательность разностей соседних элементов исходной последовательности. В качестве функции разности используется func -function Incremental(Self: sequence of T; func: (T,T,integer)->T1): sequence of T1; extensionmethod; +function Incremental(Self: sequence of T; func: (T,T,integer)->T1): sequence of T1; extensionmethod; begin var iter := Self.GetEnumerator(); if iter.MoveNext() then @@ -8523,12 +8860,22 @@ begin begin var nextItem := iter.Current; ind += 1; - yield func(prevItem,nextItem,ind); + yield func(prevItem, nextItem, ind); prevItem := nextItem; end end end; +/// Группирует одинаковые подряд идущие элементы, получая последовательность массивов +function AdjacentGroup(Self: sequence of T): sequence of array of T; extensionmethod; +begin + var c := new AdjGroupClass(Self); + while c.fin do + yield c.TakeGroup().ToArray; +end; + +// ToDo Сделать AdjacentGroup с функцией сравнения + // ----------------------------------------------------- //>> Методы расширения типа List # Extension methods for List T // ----------------------------------------------------- @@ -8537,23 +8884,147 @@ end; function Shuffle(Self: List): List; extensionmethod; begin var n := Self.Count; - for var i:=0 to n-1 do - begin - var r := PABCSystem.Random(n); + for var i := 0 to n - 1 do + begin + var r := PABCSystem.Random(n); var v := Self[i]; Self[i] := Self[r]; Self[r] := v; end; - Result := Self; + Result := Self; +end; + +/// Находит первую пару подряд идущих одинаковых элементов и возвращает индекс первого элемента пары. Если не найден, возвращается -1 +function AdjacentFind(Self: IList; start: integer := 0): integer; extensionmethod; +begin + Result := -1; + for var i := start to Self.Count - 2 do + if Self[i] = Self[i + 1] then + begin + Result := i; + exit; + end; +end; + +/// Находит первую пару подряд идущих одинаковых элементов, используя функцию сравнения eq, и возвращает индекс первого элемента пары. Если не найден, возвращается -1 +function AdjacentFind(Self: IList; eq: (T,T)->boolean; start: integer := 0): integer; extensionmethod; +begin + Result := -1; + for var i := start to Self.Count - 2 do + if eq(Self[i], Self[i + 1]) then + begin + Result := i; + exit; + end; +end; + +/// Возвращает индекс первого минимального элемента начиная с позиции index +function IndexMin(Self: IList; index: integer := 0): integer; extensionmethod;where T: IComparable; +begin + var min := Self[index]; + Result := index; + for var i := index + 1 to Self.Count - 1 do + if Self[i].CompareTo(min) < 0 then + begin + Result := i; + min := Self[i]; + end; +end; + +/// Возвращает индекс первого максимального элемента начиная с позиции index +function IndexMax(self: IList; index: integer := 0): integer; extensionmethod;where T: System.IComparable; +begin + var max := Self[index]; + Result := index; + for var i := index + 1 to Self.Count - 1 do + if Self[i].CompareTo(max) > 0 then + begin + Result := i; + max := Self[i]; + end; +end; + +/// Возвращает индекс последнего минимального элемента +function LastIndexMin(Self: IList): integer; extensionmethod;where T: System.IComparable; +begin + var min := Self[Self.Count - 1]; + Result := Self.Count - 1; + for var i := Self.Count - 2 downto 0 do + if Self[i].CompareTo(min) < 0 then + begin + Result := i; + min := Self[i]; + end; +end; + +/// Возвращает индекс последнего минимального элемента в диапазоне [0,index-1] +function LastIndexMin(Self: IList; index: integer): integer; extensionmethod;where T: System.IComparable; +begin + var min := Self[index]; + Result := index; + for var i := index - 1 downto 0 do + if Self[i].CompareTo(min) < 0 then + begin + Result := i; + min := Self[i]; + end; +end; + +/// Возвращает индекс последнего максимального элемента +function LastIndexMax(Self: IList): integer; extensionmethod;where T: System.IComparable; +begin + var max := Self[Self.Count - 1]; + Result := Self.Count - 1; + for var i := Self.Count - 2 downto 0 do + if Self[i].CompareTo(max) > 0 then + begin + Result := i; + max := Self[i]; + end; +end; + +/// Возвращает индекс последнего минимального элемента в диапазоне [0,index-1] +function LastIndexMax(Self: IList; index: integer): integer; extensionmethod;where T: System.IComparable; +begin + var max := Self[index]; + Result := index; + for var i := index - 1 downto 0 do + if Self[i].CompareTo(max) > 0 then + begin + Result := i; + max := Self[i]; + end; +end; + +/// Заменяет в массиве или списке все вхождения одного значения на другое +procedure Replace(Self: IList; oldValue, newValue: T); extensionmethod; +begin + for var i := 0 to Self.Count - 1 do + if Self[i] = oldValue then + Self[i] := newValue; +end; + +/// Преобразует элементы массива или списка по заданному правилу +procedure Transform(Self: IList; f: T->T); extensionmethod; +begin + for var i := 0 to Self.Count - 1 do + Self[i] := f(Self[i]); +end; + +/// Заполняет элементы массива или списка значениями, вычисляемыми по некоторому правилу +procedure Fill(Self: IList; f: integer->T); extensionmethod; +begin + for var i := 0 to Self.Count - 1 do + Self[i] := f(i); end; ///-- -function CreateSliceFromListInternal(Self: List; from,step,count: integer): List; +function CreateSliceFromListInternal(Self: List; from, step, count: integer): List; begin Result := new List(count); var f := from; - for var i:=0 to count-1 do + loop count do begin Result.Add(Self[f]); f += step; @@ -8561,51 +9032,40 @@ begin end; ///-- -procedure CorrectCountForSlice(Len,from,step: integer; var count: integer); +procedure CorrectCountForSlice(Len, from, step: integer; var count: integer); begin if step = 0 then raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0)); - + if count < 0 then raise new ArgumentException(GetTranslation(PARAMETER_COUNT_MUST_BE_GREATER_0)); - + if (from < 0) or (from > Len - 1) then raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE)); - + var cnt := step > 0 ? Len - from : from + 1; - var cntstep := (cnt-1) div abs(step) + 1; + var cntstep := (cnt - 1) div abs(step) + 1; if count > cntstep then count := cntstep; end; ///-- -function SliceListImpl(Self: List; from,step,count: integer): List; +function SliceListImpl(Self: List; from, step, count: integer): List; begin - CorrectCountForSlice(Self.Count,from,step,count); - {if step = 0 then - raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0)); - - if (from < 0) or (from > Self.Count - 1) then - raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE)); - - var cnt := step > 0 ? Self.Count - from : from + 1; - var cntstep := (cnt-1) div abs(step) + 1; - if count > cntstep then - count := cntstep;} - - Result := CreateSliceFromListInternal(Self,from,step,count); + CorrectCountForSlice(Self.Count, from, step, count); + Result := CreateSliceFromListInternal(Self, from, step, count); end; /// Возвращает срез списка от индекса from с шагом step -function Slice(Self: List; from,step: integer): List; extensionmethod; +function Slice(Self: List; from, step: integer): List; extensionmethod; begin - Result := SliceListImpl(Self,from,step,integer.MaxValue); + Result := SliceListImpl(Self, from, step, integer.MaxValue); end; /// Возвращает срез списка от индекса from с шагом step длины не более count -function Slice(Self: List; from,step,count: integer): List; extensionmethod; +function Slice(Self: List; from, step, count: integer): List; extensionmethod; begin - Result := SliceListImpl(Self,from,step,count); + Result := SliceListImpl(Self, from, step, count); end; /// Удаляет последний элемент. Если элементов нет, генерирует исключение @@ -8615,56 +9075,50 @@ begin Result := Self; end; -procedure CorrectFromTo(situation: integer; Len: integer; var from,&to: integer; step: integer); +procedure CorrectFromTo(situation: integer; Len: integer; var from, &to: integer; step: integer); begin - if step>0 then + if step > 0 then begin case situation of - 1: from := 0; - 2: &to := Len; - 3: begin - from := 0; - &to := Len; - end; + 1: from := 0; + 2: &to := Len; + 3: (from, &to) := (0, Len) end; end else begin case situation of - 1: from := Len - 1; - 2: &to := -1; - 3: begin - from := Len - 1; - &to := -1; - end; + 1: from := Len - 1; + 2: &to := -1; + 3: (from, &to) := (Len - 1, -1); end; end; end; ///-- -function CorrectFromToAndCalcCountForSystemSliceQuestion(situation: integer; Len: integer; var from,&to: integer; step: integer): integer; +function CorrectFromToAndCalcCountForSystemSliceQuestion(situation: integer; Len: integer; var from, &to: integer; step: integer): integer; begin if step = 0 then raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0)); - - CorrectFromTo(situation,Len,from,&to,step); - - if step>0 then + + CorrectFromTo(situation, Len, from, &to, step); + + if step > 0 then begin - if from<0 then + if from < 0 then from += (step - from - 1) div step * step; // from может оказаться > Len - 1 - var m := min(Len,&to); + var m := Min(Len,&to); if from >= m then Result := 0 - else Result := (m - from - 1) div step + 1 + else Result := (m - from - 1) div step + 1 end else begin if from > Len - 1 then from -= (from - Len - step) div step * step; // from может оказаться < 0 - var m := max(&to,-1); + var m := Max(&to,-1); if from <= m then Result := 0 else Result := (from - m - 1) div (-step) + 1 @@ -8672,105 +9126,106 @@ begin end; ///-- -function CheckAndCorrectFromToAndCalcCountForSystemSlice(situation: integer; Len: integer; var from,&to: integer; step: integer): integer; +function CheckAndCorrectFromToAndCalcCountForSystemSlice(situation: integer; Len: integer; var from, &to: integer; step: integer): integer; begin -// situation = 0 - все параметры присутствуют -// situation = 1 - from отсутствует -// situation = 2 - to отсутствует -// situation = 3 - from и to отсутствуют + // situation = 0 - все параметры присутствуют + // situation = 1 - from отсутствует + // situation = 2 - to отсутствует + // situation = 3 - from и to отсутствуют if step = 0 then raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0)); - - if (situation=0) or (situation=2) then + + if (situation = 0) or (situation = 2) then if (from < 0) or (from > Len - 1) then raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE)); - - if (situation=0) or (situation=1) then + + if (situation = 0) or (situation = 1) then if (&to < -1) or (&to > Len) then raise new ArgumentException(GetTranslation(PARAMETER_TO_OUT_OF_RANGE)); - - CorrectFromTo(situation,Len,from,&to,step); - + + CorrectFromTo(situation, Len, from, &to, step); + var count: integer; - if step>0 then + if step > 0 then begin var cnt := &to - from; - if cnt<=0 then + if cnt <= 0 then count := 0 - else count := (cnt-1) div step + 1; + else count := (cnt - 1) div step + 1; end else begin var cnt := from - &to; - if cnt<=0 then + if cnt <= 0 then count := 0 - else count := (cnt-1) div (-step) + 1; + else count := (cnt - 1) div (-step) + 1; end; - + Result := count; end; ///-- -procedure CheckStepAndCorrectFromTo(situation: integer; Len: integer; var from,&to: integer; step: integer); +procedure CheckStepAndCorrectFromTo(situation: integer; Len: integer; var from, &to: integer; step: integer); begin -// situation = 0 - все параметры присутствуют -// situation = 1 - from отсутствует -// situation = 2 - to отсутствует -// situation = 3 - from и to отсутствуют + // situation = 0 - все параметры присутствуют + // situation = 1 - from отсутствует + // situation = 2 - to отсутствует + // situation = 3 - from и to отсутствуют if step = 0 then raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0)); - + {if (situation=0) or (situation=2) then if (from < 0) or (from > Len - 1) then raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE)); - + if (situation=0) or (situation=1) then if (&to < -1) or (&to > Len) then raise new ArgumentException(GetTranslation(PARAMETER_TO_OUT_OF_RANGE));} - - CorrectFromTo(situation,Len,from,&to,step); -end; - -///-- -function SystemSliceListImpl(Self: List; situation: integer; from,&to: integer; step: integer := 1): List; -begin - var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation,Self.Count,from,&to,step); - - Result := CreateSliceFromListInternal(Self,from,step,count); -end; - -///-- -function SystemSlice(Self: List; situation: integer; from,&to: integer): List; extensionmethod; -begin - Result := SystemSliceListImpl(Self,situation,from,&to,1); -end; - -///-- -function SystemSlice(Self: List; situation: integer; from,&to,step: integer): List; extensionmethod; -begin - Result := SystemSliceListImpl(Self,situation,from,&to,step); -end; - -///-- -function SystemSliceListImplQuestion(Self: List; situation: integer; from,&to: integer; step: integer := 1): List; -begin - var count := CorrectFromToAndCalcCountForSystemSliceQuestion(situation,Self.Count,from,&to,step); - Result := CreateSliceFromListInternal(Self,from,step,count); + CorrectFromTo(situation, Len, from, &to, step); +end; + +///-- +function SystemSliceListImpl(Self: List; situation: integer; from, &to: integer; step: integer := 1): List; +begin + var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation, Self.Count, from, &to, step); + + Result := CreateSliceFromListInternal(Self, from, step, count); end; ///-- -function SystemSliceQuestion(Self: List; situation: integer; from,&to: integer): List; extensionmethod; +function SystemSlice(Self: List; situation: integer; from, &to: integer): List; extensionmethod; begin - Result := SystemSliceListImplQuestion(Self,situation,from,&to,1); + Result := SystemSliceListImpl(Self, situation, from, &to, 1); end; ///-- -function SystemSliceQuestion(Self: List; situation: integer; from,&to,step: integer): List; extensionmethod; +function SystemSlice(Self: List; situation: integer; from, &to, step: integer): List; extensionmethod; begin - Result := SystemSliceListImplQuestion(Self,situation,from,&to,step); + Result := SystemSliceListImpl(Self, situation, from, &to, step); end; + +///-- +function SystemSliceListImplQuestion(Self: List; situation: integer; from, &to: integer; step: integer := 1): List; +begin + var count := CorrectFromToAndCalcCountForSystemSliceQuestion(situation, Self.Count, from, &to, step); + + Result := CreateSliceFromListInternal(Self, from, step, count); +end; + +///-- +function SystemSliceQuestion(Self: List; situation: integer; from, &to: integer): List; extensionmethod; +begin + Result := SystemSliceListImplQuestion(Self, situation, from, &to, 1); +end; + +///-- +function SystemSliceQuestion(Self: List; situation: integer; from, &to, step: integer): List; extensionmethod; +begin + Result := SystemSliceListImplQuestion(Self, situation, from, &to, step); +end; + // ----------------------------------------------------- //>> Методы расширения типа array [,] of T # Extension methods for array [,] of T // ----------------------------------------------------- @@ -8786,42 +9241,46 @@ begin Result := Self.GetLength(1); end; +/// Вывод двумерного массива, w - ширина поля вывода function Print(Self: array [,] of T; w: integer := 4): array [,] of T; extensionmethod; begin - for var i:=0 to Self.RowCount-1 do - begin - for var j:=0 to Self.ColCount-1 do + for var i := 0 to Self.RowCount - 1 do + begin + for var j := 0 to Self.ColCount - 1 do begin - var elem := Self[i,j]; + var elem := Self[i, j]; var s := StructuredObjectToString(elem); Write(s.PadLeft(w)); end; Writeln; end; - Result := Self; + Result := Self; end; +/// Вывод двумерного вещественного массива по формату :w:f function Print(Self: array [,] of real; w: integer := 7; f: integer := 2): array [,] of real; extensionmethod; begin - for var i:=0 to Self.RowCount-1 do - begin - for var j:=0 to Self.ColCount-1 do - Write(FormatValue(Self[i,j],w,f)); + for var i := 0 to Self.RowCount - 1 do + begin + for var j := 0 to Self.ColCount - 1 do + Write(FormatValue(Self[i, j], w, f)); Writeln; end; - Result := Self; + Result := Self; end; +/// Вывод двумерного массива и переход на следующую строку, w - ширина поля вывода function Println(Self: array [,] of T; w: integer := 4): array [,] of T; extensionmethod; begin Self.Print(w); - Result := Self; + Result := Self; end; +/// Вывод двумерного вещественного массива по формату :w:f и переход на следующую строку function Println(Self: array [,] of real; w: integer := 7; f: integer := 2): array [,] of real; extensionmethod; begin - Self.Print(w,f); - Result := Self; + Self.Print(w, f); + Result := Self; end; /// k-тая строка двумерного массива @@ -8829,8 +9288,8 @@ function Row(Self: array [,] of T; k: integer): array of T; extensionmethod; begin var n := Self.ColCount; var res := new T[n]; - for var j:=0 to n-1 do - res[j] := Self[k,j]; + for var j := 0 to n - 1 do + res[j] := Self[k, j]; Result := res; end; @@ -8839,103 +9298,189 @@ function Col(Self: array [,] of T; k: integer): array of T; extensionmethod; begin var m := Self.RowCount; var res := new T[m]; - for var i:=0 to m-1 do - res[i] := Self[i,k]; + for var i := 0 to m - 1 do + res[i] := Self[i, k]; Result := res; end; /// k-тая строка двумерного массива как последовательность function RowSeq(Self: array [,] of T; k: integer): sequence of T; extensionmethod; begin - for var j:=0 to Self.ColCount-1 do - yield Self[k,j]; + for var j := 0 to Self.ColCount - 1 do + yield Self[k, j]; end; /// k-тый столбец двумерного массива как последовательность function ColSeq(Self: array [,] of T; k: integer): sequence of T; extensionmethod; begin - for var i:=0 to Self.RowCount-1 do - yield Self[i,k]; + for var i := 0 to Self.RowCount - 1 do + yield Self[i, k]; end; /// Возвращает последовательность строк двумерного массива function Rows(Self: array [,] of T): sequence of sequence of T; extensionmethod; begin - for var i:=0 to Self.RowCount-1 do + for var i := 0 to Self.RowCount - 1 do yield Self.RowSeq(i); end; /// Возвращает последовательность столбцов двумерного массива function Cols(Self: array [,] of T): sequence of sequence of T; extensionmethod; begin - for var j:=0 to Self.ColCount-1 do + for var j := 0 to Self.ColCount - 1 do yield Self.ColSeq(j); end; /// Меняет местами две строки двумерного массива с номерами k1 и k2 -procedure SwapRows(Self: array [,] of T; k1,k2: integer); extensionmethod; +procedure SwapRows(Self: array [,] of T; k1, k2: integer); extensionmethod; begin - for var j:=0 to Self.ColCount-1 do - Swap(Self[k1,j],Self[k2,j]) + for var j := 0 to Self.ColCount - 1 do + Swap(Self[k1, j], Self[k2, j]) end; /// Меняет местами два столбца двумерного массива с номерами k1 и k2 -procedure SwapCols(Self: array [,] of T; k1,k2: integer); extensionmethod; +procedure SwapCols(Self: array [,] of T; k1, k2: integer); extensionmethod; begin - for var i:=0 to Self.RowCount-1 do - Swap(Self[i,k1],Self[i,k2]) + for var i := 0 to Self.RowCount - 1 do + Swap(Self[i, k1], Self[i, k2]) end; +/// Меняет строку k двумерного массива на другую строку +procedure SetRow(Self: array [,] of T; k: integer; a: array of T); extensionmethod; +begin + if a.Length <> Self.ColCount then + raise new System.ArgumentException(GetTranslation(ARR_LENGTH_MUST_BE_MATCH_TO_MATR_SIZE)); + for var j := 0 to Self.ColCount - 1 do + Self[k, j] := a[j] +end; + +/// Меняет столбец k двумерного массива на другой столбец +procedure SetCol(Self: array [,] of T; k: integer; a: array of T); extensionmethod; +begin + if a.Length <> Self.RowCount then + raise new System.ArgumentException(GetTranslation(ARR_LENGTH_MUST_BE_MATCH_TO_MATR_SIZE)); + for var i := 0 to Self.RowCount - 1 do + Self[i, k] := a[i] +end; + +/// Возвращает по заданному двумерному массиву последовательность (a[i,j],i,j) +function ElementsWithIndexes(Self: array [,] of T): sequence of (T, integer, integer); extensionmethod; +begin + for var i := 0 to Self.RowCount - 1 do + for var j := 0 to Self.ColCount - 1 do + yield (Self[i, j], i, j) +end; + +/// Возвращает по заданному двумерному массиву последовательность его элементов по строкам +function ElementsByRow(Self: array [,] of T): sequence of T; extensionmethod; +begin + for var i := 0 to Self.RowCount - 1 do + for var j := 0 to Self.ColCount - 1 do + yield Self[i, j] +end; + +/// Возвращает по заданному двумерному массиву последовательность его элементов по столбцам +function ElementsByCol(Self: array [,] of T): sequence of T; extensionmethod; +begin + for var j := 0 to Self.ColCount - 1 do + for var i := 0 to Self.RowCount - 1 do + yield Self[i, j] +end; + +/// Преобразует элементы двумерного массива и возвращает преобразованный массив +function ConvertAll(Self: array [,] of T; converter: T->T1): array [,] of T1; extensionmethod; +begin + Result := new T1[Self.RowCount, Self.ColCount]; + for var i := 0 to Self.RowCount - 1 do + for var j := 0 to Self.ColCount - 1 do + Result[i, j] := converter(Self[i, j]); +end; + +/// Преобразует элементы двумерного массива по заданному правилу +procedure Transform(Self: array [,] of T; f: T->T); extensionmethod; +begin + for var i := 0 to Self.RowCount - 1 do + for var j := 0 to Self.ColCount - 1 do + Self[i, j] := f(Self[i, j]); +end; + +/// Заполняет элементы двумерного массива значениями, вычисляемыми по некоторому правилу +procedure Fill(Self: array [,] of T; f: (integer,integer) ->T); extensionmethod; +begin + for var i := 0 to Self.RowCount - 1 do + for var j := 0 to Self.ColCount - 1 do + Self[i, j] := f(i, j); +end; + +// ----------------------------------------------------- +//>> Фиктивная секция YYY - не удалять! # YYY +// ----------------------------------------------------- // Реализация операций с матрицами - только после введения RowCount и ColCount -function MatrRandom(m: integer; n: integer; a,b: integer): array [,] of integer; +function MatrRandom(m: integer; n: integer; a, b: integer): array [,] of integer; begin - Result := new integer[m,n]; - for var i:=0 to Result.RowCount-1 do - for var j:=0 to Result.ColCount-1 do - Result[i,j] := Random(a,b); + Result := new integer[m, n]; + for var i := 0 to Result.RowCount - 1 do + for var j := 0 to Result.ColCount - 1 do + Result[i, j] := Random(a, b); end; -function MatrRandomInteger(m: integer; n: integer; a,b: integer): array [,] of integer; +function MatrRandomInteger(m: integer; n: integer; a, b: integer): array [,] of integer; begin - Result := new integer[m,n]; - for var i:=0 to Result.RowCount-1 do - for var j:=0 to Result.ColCount-1 do - Result[i,j] := Random(a,b); + Result := new integer[m, n]; + for var i := 0 to Result.RowCount - 1 do + for var j := 0 to Result.ColCount - 1 do + Result[i, j] := Random(a, b); end; -function MatrRandomReal(m: integer; n: integer; a,b: real): array [,] of real; +function MatrRandomReal(m: integer; n: integer; a, b: real): array [,] of real; begin - Result := new real[m,n]; - for var i:=0 to Result.RowCount-1 do - for var j:=0 to Result.ColCount-1 do - Result[i,j] := Random()*(b-a) + a; + Result := new real[m, n]; + for var i := 0 to Result.RowCount - 1 do + for var j := 0 to Result.ColCount - 1 do + Result[i, j] := Random() * (b - a) + a; end; -function MatrFill(m,n: integer; x: T): array [,] of T; +function MatrFill(m, n: integer; x: T): array [,] of T; begin - Result := new T[m,n]; - for var i:=0 to Result.RowCount-1 do - for var j:=0 to Result.ColCount-1 do - Result[i,j] := x; + Result := new T[m, n]; + for var i := 0 to Result.RowCount - 1 do + for var j := 0 to Result.ColCount - 1 do + Result[i, j] := x; end; -function MatrGen(m,n: integer; gen: (integer,integer)->T): array [,] of T; +function MatrGen(m, n: integer; gen: (integer,integer)->T): array [,] of T; begin - Result := new T[m,n]; - for var i:=0 to Result.RowCount-1 do - for var j:=0 to Result.ColCount-1 do - Result[i,j] := gen(i,j); + Result := new T[m, n]; + for var i := 0 to Result.RowCount - 1 do + for var j := 0 to Result.ColCount - 1 do + Result[i, j] := gen(i, j); end; function Transpose(a: array [,] of T): array [,] of T; begin var m := a.RowCount; var n := a.ColCount; - Result := new T[n,m]; - for var i:=0 to Result.RowCount-1 do - for var j:=0 to Result.ColCount-1 do - Result[i,j] := a[j,i] + Result := new T[n, m]; + for var i := 0 to Result.RowCount - 1 do + for var j := 0 to Result.ColCount - 1 do + Result[i, j] := a[j, i] +end; + +function ReadMatrInteger(m, n: integer): array [,] of integer; +begin + Result := new integer[m, n]; + for var i := 0 to m - 1 do + for var j := 0 to n - 1 do + Result[i, j] := ReadInteger; +end; + +function ReadMatrReal(m, n: integer): array [,] of real; +begin + Result := new real[m, n]; + for var i := 0 to m - 1 do + for var j := 0 to n - 1 do + Result[i, j] := ReadReal; end; // ----------------------------------------------------- @@ -8950,12 +9495,12 @@ end; function Shuffle(Self: array of T): array of T; extensionmethod; begin var n := Self.Length; - for var i:=0 to n-1 do - Swap(Self[i],Self[Random(n)]); - Result := Self; + for var i := 0 to n - 1 do + Swap(Self[i], Self[Random(n)]); + Result := Self; end; -/// Находит первую пару подряд идущих одинаковых элементов и возвращает индекс первого элемента пары. Если не найден, возвращается -1 +{/// Находит первую пару подряд идущих одинаковых элементов и возвращает индекс первого элемента пары. Если не найден, возвращается -1 function AdjacentFind(Self: array of T; start: integer := 0): integer; extensionmethod; begin Result := -1; @@ -8977,113 +9522,68 @@ begin Result := i; exit; end; -end; - -///-- -type - AdjGroupClass = class - private - cur: T; - enm: IEnumerator; - fin: boolean; - public - constructor Create(a: sequence of T); - begin - enm := a.GetEnumerator(); - fin := enm.MoveNext; - if fin then - cur := enm.Current; - end; - - function TakeGroup: sequence of T; - begin - yield cur; - fin := enm.movenext; - while fin do - begin - if enm.current = cur then - yield enm.current - else - begin - cur := enm.Current; - break; - end; - fin := enm.movenext; - end; - end; - end; - -/// Группирует одинаковые подряд идущие элементы, получая последовательность последовательностей -function AdjacentGroup(Self: sequence of T): sequence of sequence of T; extensionmethod; -begin - var c := new AdjGroupClass(Self); - while c.fin do - yield c.TakeGroup(); -end; - -//ToDo Сделать AdjacentGroup с функцией сравнения +end;} /// Возвращает минимальный элемент -function Min(Self: array of T): T; extensionmethod; where T: System.IComparable; +function Min(Self: array of T): T; extensionmethod;where T: System.IComparable; begin Result := Self[0]; - for var i:=1 to Self.Length-1 do - if Self[i].CompareTo(Result)<0 then + for var i := 1 to Self.Length - 1 do + if Self[i].CompareTo(Result) < 0 then Result := Self[i]; end; -/// Возвращает максинимальный элемент -function Max(Self: array of T): T; extensionmethod; where T: System.IComparable; +/// Возвращает максимальный элемент +function Max(Self: array of T): T; extensionmethod;where T: System.IComparable; begin Result := Self[0]; - for var i:=1 to Self.Length-1 do - if Self[i].CompareTo(Result)>0 then + for var i := 1 to Self.Length - 1 do + if Self[i].CompareTo(Result) > 0 then Result := Self[i]; end; /// Возвращает минимальный элемент -function Min(Self: array of integer): integer; extensionmethod; +function Min(Self: array of integer): integer; extensionmethod; begin Result := Self[0]; - for var i:=1 to Self.Length-1 do + for var i := 1 to Self.Length - 1 do if Self[i] < Result then Result := Self[i]; end; /// Возвращает минимальный элемент -function Min(Self: array of real): real; extensionmethod; +function Min(Self: array of real): real; extensionmethod; begin Result := Self[0]; - for var i:=1 to Self.Length-1 do + for var i := 1 to Self.Length - 1 do if Self[i] < Result then Result := Self[i]; end; /// Возвращает максимальный элемент -function Max(Self: array of integer): integer; extensionmethod; +function Max(Self: array of integer): integer; extensionmethod; begin Result := Self[0]; - for var i:=1 to Self.Length-1 do + for var i := 1 to Self.Length - 1 do if Self[i] > Result then Result := Self[i]; end; /// Возвращает максимальный элемент -function Max(Self: array of real): real; extensionmethod; +function Max(Self: array of real): real; extensionmethod; begin Result := Self[0]; - for var i:=1 to Self.Length-1 do + for var i := 1 to Self.Length - 1 do if Self[i] > Result then Result := Self[i]; end; - -/// Возвращает индекс первого минимального элемента начиная с позиции start -function IndexMin(Self: array of T; start: integer := 0): integer; extensionmethod; where T: System.IComparable; +{/// Возвращает индекс первого минимального элемента начиная с позиции index +function IndexMin(Self: array of T; index: integer := 0): integer; extensionmethod; where T: System.IComparable; begin - var min := Self[start]; - Result := start; - for var i:=start+1 to Self.Length-1 do + var min := Self[index]; + Result := index; + for var i:=index+1 to Self.Length-1 do if Self[i].CompareTo(min)<0 then begin Result := i; @@ -9091,12 +9591,12 @@ begin end; end; -/// Возвращает индекс первого максимального элемента начиная с позиции start -function IndexMax(self: array of T; start: integer := 0): integer; extensionmethod; where T: System.IComparable; +/// Возвращает индекс первого максимального элемента начиная с позиции index +function IndexMax(self: array of T; index: integer := 0): integer; extensionmethod; where T: System.IComparable; begin - var max := Self[start]; - Result := start; - for var i:=start+1 to Self.Length-1 do + var max := Self[index]; + Result := index; + for var i:=index+1 to Self.Length-1 do if Self[i].CompareTo(max)>0 then begin Result := i; @@ -9117,12 +9617,12 @@ begin end; end; -/// Возвращает индекс последнего минимального элемента начиная с позиции start -function LastIndexMin(Self: array of T; start: integer): integer; extensionmethod; where T: System.IComparable; +/// Возвращает индекс последнего минимального элемента в диапазоне [0,index] +function LastIndexMin(Self: array of T; index: integer): integer; extensionmethod; where T: System.IComparable; begin - var min := Self[start]; - Result := start; - for var i:=start-1 downto 0 do + var min := Self[index]; + Result := index; + for var i:=index-1 downto 0 do if Self[i].CompareTo(min)<0 then begin Result := i; @@ -9143,12 +9643,12 @@ begin end; end; -/// Возвращает индекс последнего минимального элемента начиная с позиции start -function LastIndexMax(Self: array of T; start: integer): integer; extensionmethod; where T: System.IComparable; +/// Возвращает индекс последнего минимального элемента в диапазоне [0,index] +function LastIndexMax(Self: array of T; index: integer): integer; extensionmethod; where T: System.IComparable; begin - var max := Self[start]; - Result := start; - for var i:=start-1 downto 0 do + var max := Self[index]; + Result := index; + for var i:=index-1 downto 0 do if Self[i].CompareTo(max)>0 then begin Result := i; @@ -9167,86 +9667,93 @@ end; /// Преобразует элементы массива по заданному правилу procedure Transform(self: array of T; f: T -> T); extensionmethod; begin - for var i:=0 to self.Length-1 do - self[i] := f(self[i]); + for var i:=0 to Self.Length-1 do + Self[i] := f(Self[i]); end; +/// Заполняет элементы массива значениями, вычисляемыми по некоторому правилу +procedure Fill(Self: array of T; f: integer -> T); extensionmethod; +begin + for var i:=0 to Self.Length-1 do + Self[i] := f(i); +end;} + /// Выполняет бинарный поиск в отсортированном массиве function BinarySearch(self: array of T; x: T): integer; extensionmethod; begin - Result := System.Array.BinarySearch(self,x); + Result := System.Array.BinarySearch(self, x); end; -/// Преобразует массив одного типа в массив другого типа -function ConvertAll(self: array of T; converter: System.Converter): array of T1; extensionmethod; +/// Преобразует элементы массива и возвращает преобразованный массив +function ConvertAll(self: array of T; converter: T->T1): array of T1; extensionmethod; begin - Result := System.Array.ConvertAll(self,converter); + Result := System.Array.ConvertAll(self, t -> converter(t)); end; /// Выполняет поиск первого элемента в массиве, удовлетворяющего предикату. Если не найден, возвращается нулевое значение соответствующего типа function Find(self: array of T; p: T->boolean): T; extensionmethod; begin - Result := System.Array.Find(self,p); + Result := System.Array.Find(self, p); end; /// Выполняет поиск индекса первого элемента в массиве, удовлетворяющего предикату. Если не найден, возвращается -1 function FindIndex(self: array of T; p: T->boolean): integer; extensionmethod; begin - Result := System.Array.FindIndex(self,p); + Result := System.Array.FindIndex(self, p); end; /// Выполняет поиск индекса первого элемента в массиве, удовлетворяющего предикату, начиная с индекса start. Если не найден, возвращается -1 function FindIndex(self: array of T; start: integer; p: T->boolean): integer; extensionmethod; begin - Result := System.Array.FindIndex(self,start,p); + Result := System.Array.FindIndex(self, start, p); end; /// Возвращает в виде массива все элементы, удовлетворяющие предикату function FindAll(self: array of T; p: T->boolean): array of T; extensionmethod; begin - Result := System.Array.FindAll(self,p); + Result := System.Array.FindAll(self, p); end; /// Выполняет поиск последнего элемента в массиве, удовлетворяющего предикату. Если не найден, возвращается нулевое значение соответствующего типа function FindLast(self: array of T; p: T->boolean): T; extensionmethod; begin - Result := System.Array.FindLast(self,p); + Result := System.Array.FindLast(self, p); end; /// Выполняет поиск индекса последнего элемента в массиве, удовлетворяющего предикату. Если не найден, возвращается нулевое значение соответствующего типа function FindLastIndex(self: array of T; p: T->boolean): integer; extensionmethod; begin - Result := System.Array.FindLastIndex(self,p); + Result := System.Array.FindLastIndex(self, p); end; /// Выполняет поиск индекса последнего элемента в массиве, удовлетворяющего предикату, начиная с индекса start. Если не найден, возвращается нулевое значение соответствующего типа function FindLastIndex(self: array of T; start: integer; p: T->boolean): integer; extensionmethod; begin - Result := System.Array.FindLastIndex(self,start,p); + Result := System.Array.FindLastIndex(self, start, p); end; /// Возвращает индекс первого вхождения элемента или -1 если элемент не найден function IndexOf(self: array of T; x: T): integer; extensionmethod; begin - Result := System.Array.IndexOf(self,x); + Result := System.Array.IndexOf(self, x); end; /// Возвращает индекс первого вхождения элемента начиная с индекса start или -1 если элемент не найден function IndexOf(self: array of T; x: T; start: integer): integer; extensionmethod; begin - Result := System.Array.IndexOf(self,x,start); + Result := System.Array.IndexOf(self, x, start); end; /// Возвращает индекс последнего вхождения элемента или -1 если элемент не найден function LastIndexOf(self: array of T; x: T): integer; extensionmethod; begin - Result := System.Array.LastIndexOf(self,x); + Result := System.Array.LastIndexOf(self, x); end; /// Возвращает индекс последнего вхождения элемента начиная с индекса start или -1 если элемент не найден function LastIndexOf(self: array of T; x: T; start: integer): integer; extensionmethod; begin - Result := System.Array.LastIndexOf(self,x,start); + Result := System.Array.LastIndexOf(self, x, start); end; /// Сортирует массив по возрастанию @@ -9256,9 +9763,9 @@ begin end; /// Сортирует массив по возрастанию, используя cmp в качестве функции сравнения элементов -procedure Sort(self: array of T; cmp: (T,T) -> integer); extensionmethod; +procedure Sort(self: array of T; cmp: (T,T) ->integer); extensionmethod; begin - System.Array.Sort(self,cmp); + System.Array.Sort(self, cmp); end; /// Возвращает индекс последнего элемента массива @@ -9267,13 +9774,32 @@ function High(self: System.Array); extensionmethod := High(Self); /// Возвращает индекс первого элемента массива function Low(self: System.Array); extensionmethod := Low(Self); +/// Возвращает последовательность индексов одномерного массива +function Indexes(Self: array of T): sequence of integer; extensionmethod := Range(0, Self.Length - 1); + +/// Возвращает последовательность индексов элементов одномерного массива, удовлетворяющих условию +function IndexesOf(Self: array of T; cond: T->boolean): sequence of integer; extensionmethod; +begin + for var i := 0 to Self.High do + if cond(Self[i]) then + yield i; +end; + +/// Возвращает последовательность индексов элементов одномерного массива, удовлетворяющих условию +function IndexesOf(Self: array of T; cond: (T,integer) ->boolean): sequence of integer; extensionmethod; +begin + for var i := 0 to Self.High do + if cond(Self[i], i) then + yield i; +end; + ///-- -function CreateSliceFromArrayInternal(Self: array of T; from,step,count: integer): array of T; +function CreateSliceFromArrayInternal(Self: array of T; from, step, count: integer): array of T; begin Result := new T[count]; var f := from; - for var i:=0 to count-1 do + for var i := 0 to count - 1 do begin Result[i] := Self[f]; f += step; @@ -9281,74 +9807,74 @@ begin end; ///-- -function SliceArrayImpl(Self: array of T; from,step,count: integer): array of T; +function SliceArrayImpl(Self: array of T; from, step, count: integer): array of T; begin {if step = 0 then raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0)); - + if (from < 0) or (from > Self.Length - 1) then raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE)); - + var cnt := step > 0 ? Self.Length - from : from + 1; var cntstep := (cnt-1) div abs(step) + 1; if count > cntstep then count := cntstep;} - - CorrectCountForSlice(Self.Length,from,step,count); - - Result := CreateSliceFromArrayInternal(Self,from,step,count) + + CorrectCountForSlice(Self.Length, from, step, count); + + Result := CreateSliceFromArrayInternal(Self, from, step, count) end; /// Возвращает срез массива от индекса from с шагом step -function Slice(Self: array of T; from,step: integer): array of T; extensionmethod; +function Slice(Self: array of T; from, step: integer): array of T; extensionmethod; begin - Result := SliceArrayImpl(Self,from,step,integer.MaxValue); + Result := SliceArrayImpl(Self, from, step, integer.MaxValue); end; /// Возвращает срез массива от индекса from с шагом step длины не более count -function Slice(Self: array of T; from,step,count: integer): array of T; extensionmethod; +function Slice(Self: array of T; from, step, count: integer): array of T; extensionmethod; begin - Result := SliceArrayImpl(Self,from,step,count); + Result := SliceArrayImpl(Self, from, step, count); end; ///-- -function SystemSliceArrayImpl(Self: array of T; situation: integer; from,&to: integer; step: integer := 1): array of T; +function SystemSliceArrayImpl(Self: array of T; situation: integer; from, &to: integer; step: integer := 1): array of T; begin - var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation,Self.Length,from,&to,step); - - Result := CreateSliceFromArrayInternal(Self,from,step,count) -end; - -///-- -function SystemSlice(Self: array of T; situation: integer; from,&to: integer): array of T; extensionmethod; -begin - Result := SystemSliceArrayImpl(Self,situation,from,&to,1); -end; - -///-- -function SystemSlice(Self: array of T; situation: integer; from,&to,step: integer): array of T; extensionmethod; -begin - Result := SystemSliceArrayImpl(Self,situation,from,&to,step); -end; - -///-- -function SystemSliceArrayImplQuestion(Self: array of T; situation: integer; from,&to: integer; step: integer := 1): array of T; -begin - var count := CorrectFromToAndCalcCountForSystemSliceQuestion(situation,Self.Length,from,&to,step); + var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation, Self.Length, from, &to, step); - Result := CreateSliceFromArrayInternal(Self,from,step,count); + Result := CreateSliceFromArrayInternal(Self, from, step, count) end; ///-- -function SystemSliceQuestion(Self: array of T; situation: integer; from,&to: integer): array of T; extensionmethod; +function SystemSlice(Self: array of T; situation: integer; from, &to: integer): array of T; extensionmethod; begin - Result := SystemSliceArrayImplQuestion(Self,situation,from,&to,1); + Result := SystemSliceArrayImpl(Self, situation, from, &to, 1); end; ///-- -function SystemSliceQuestion(Self: array of T; situation: integer; from,&to,step: integer): array of T; extensionmethod; +function SystemSlice(Self: array of T; situation: integer; from, &to, step: integer): array of T; extensionmethod; begin - Result := SystemSliceArrayImplQuestion(Self,situation,from,&to,step); + Result := SystemSliceArrayImpl(Self, situation, from, &to, step); +end; + +///-- +function SystemSliceArrayImplQuestion(Self: array of T; situation: integer; from, &to: integer; step: integer := 1): array of T; +begin + var count := CorrectFromToAndCalcCountForSystemSliceQuestion(situation, Self.Length, from, &to, step); + + Result := CreateSliceFromArrayInternal(Self, from, step, count); +end; + +///-- +function SystemSliceQuestion(Self: array of T; situation: integer; from, &to: integer): array of T; extensionmethod; +begin + Result := SystemSliceArrayImplQuestion(Self, situation, from, &to, 1); +end; + +///-- +function SystemSliceQuestion(Self: array of T; situation: integer; from, &to, step: integer): array of T; extensionmethod; +begin + Result := SystemSliceArrayImplQuestion(Self, situation, from, &to, step); end; // ----------------------------------------------------- @@ -9366,24 +9892,37 @@ begin Result := Sqr(Self); end; +/// Возвращает True если значение находится между двумя другими +function Between(Self: integer; a, b: integer): boolean; extensionmethod; +begin + Result := (a <= Self) and (Self <= b) or (b <= Self) and (Self <= a); +end; + +/// Возвращает True если значение находится между двумя другими +function InRange(Self: integer; a,b: integer): boolean; extensionmethod; +begin + Result := (a <= Self) and (Self <= b) or (b <= Self) and (Self <= a); +end; + + // Дополнения февраль 2016: IsEven, IsOdd /// Возвращает, является ли целое четным function IsEven(Self: integer): boolean; extensionmethod; begin - Result := Self mod 2 = 0; + Result := Self mod 2 = 0; end; /// Возвращает, является ли целое нечетным function IsOdd(Self: integer): boolean; extensionmethod; begin - Result := Self mod 2 <> 0; + Result := Self mod 2 <> 0; end; /// Возвращает последовательность чисел от 1 до данного function Range(Self: integer): sequence of integer; extensionmethod; begin - Result := Range(1,Self); + Result := Range(1, Self); end; // Дополнения февраль 2016: &To, &Downto, Times @@ -9403,7 +9942,7 @@ end; /// Возвращает последовательность целых 0,1,...n-1 function Times(Self: integer): sequence of integer; extensionmethod; begin - Result := Range(0,Self-1); + Result := Range(0, Self - 1); end; // ----------------------------------------------------- @@ -9418,6 +9957,17 @@ end; // ----------------------------------------------------- //>> Методы расширения типа real # Extension methods for real // ----------------------------------------------------- +/// Возвращает True если значение находится между двумя другими +function Between(Self: real; a, b: real): boolean; extensionmethod; +begin + Result := (a <= Self) and (Self <= b) or (b <= Self) and (Self <= a); +end; + +function InRange(Self: real; a,b: real): boolean; extensionmethod; +begin + Result := (a <= Self) and (Self <= b) or (b <= Self) and (Self <= a); +end; + /// Возвращает квадратный корень числа function Sqrt(Self: real): real; extensionmethod; begin @@ -9436,6 +9986,12 @@ begin Result := Round(Self); end; +/// Возвращает x, округленное до ближайшего вещественного с digits знаками после десятичной точки +function Round(Self: real; digits: integer): real; extensionmethod; +begin + Result := Round(Self,digits); +end; + /// Возвращает число, округленное до ближайшего длинного целого function RoundBigInteger(Self: real): BigInteger; extensionmethod; begin @@ -9457,40 +10013,40 @@ end; /// Возвращает вещественное, отформатированное к строке с frac цифрами после десятичной точки function ToString(Self: real; frac: integer): string; extensionmethod; begin - if frac<0 then - raise new System.ArgumentOutOfRangeException('frac','frac<0'); - if frac>=100 then - raise new System.ArgumentOutOfRangeException('frac','frac>=100'); - Result := Format('{0:f'+frac+'}',Self) + if frac < 0 then + raise new System.ArgumentOutOfRangeException('frac', 'frac<0'); + if frac >= 100 then + raise new System.ArgumentOutOfRangeException('frac', 'frac>=100'); + Result := Format('{0:f' + frac + '}', Self) end; //------------------------------------------------------------------------------ //>> Методы расширения типа char # Extension methods for char //------------------------------------------------------------------------------ -/// Предыдущий символ -function Pred(Self: char): char; extensionmethod; +/// Возвращает True если значение находится между двумя другими +function Between(Self: char; a, b: char): boolean; extensionmethod; begin - Result := PABCSystem.Pred(Self); + Result := (a <= Self) and (Self <= b) or (b <= Self) and (Self <= a); end; +/// Возвращает True если значение находится между двумя другими +function InRange(Self: char; a,b: char): boolean; extensionmethod; +begin + Result := (a <= Self) and (Self <= b) or (b <= Self) and (Self <= a); +end; + +/// Предыдущий символ +function Pred(Self: char); extensionmethod := PABCSystem.Pred(Self); + /// Следующий символ -function Succ(Self: char): char; extensionmethod; -begin - Result := PABCSystem.Succ(Self); -end; +function Succ(Self: char); extensionmethod := PABCSystem.Succ(Self); /// Код символа в кодировке Unicode -function Code(Self: char): integer; extensionmethod; -begin - Result := word(Self); -end; +function Code(Self: char): integer; extensionmethod := word(Self); /// Является ли символ цифрой -function IsDigit(Self: char): boolean; extensionmethod; -begin - Result := char.IsDigit(Self); -end; +function IsDigit(Self: char); extensionmethod := char.IsDigit(Self); /// Является ли символ буквой function IsLetter(Self: char): boolean; extensionmethod; @@ -9514,7 +10070,7 @@ end; function ToDigit(Self: char): integer; extensionmethod; begin Result := OrdUnicode(Self) - OrdUnicode('0'); - if (Result<0) or (Result>=10) then + if (Result < 0) or (Result >= 10) then raise new System.FormatException('not a Digit'); end; @@ -9533,6 +10089,18 @@ end; //------------------------------------------------------------------------------ //>> Методы расширения типа string # Extension methods for string //------------------------------------------------------------------------------ +/// Возвращает True если значение находится между двумя другими +function Between(Self: string; a, b: string): boolean; extensionmethod; +begin + Result := (a <= Self) and (Self <= b) or (b <= Self) and (Self <= a); +end; + +/// Возвращает True если значение находится между двумя другими +function InRange(Self: string; a,b: string): boolean; extensionmethod; +begin + Result := (a <= Self) and (Self <= b) or (b <= Self) and (Self <= a); +end; + /// Считывает целое из строки начиная с позиции from и устанавливает from за считанным значением function ReadInteger(Self: string; var from: integer): integer; extensionmethod; begin @@ -9591,55 +10159,64 @@ end; function Inverse(Self: string): string; extensionmethod; begin var sb := new System.Text.StringBuilder(Self.Length); - for var i:= Self.Length downto 1 do + for var i := Self.Length downto 1 do sb.Append(Self[i]); Result := sb.ToString; end; -// Дополнения февраль 2016: Matches, MatchValues, Replace, Remove, Right, Left +// Дополнения февраль 2016: Matches, MatchValue, MatchValues, IsMatch, RegexReplace, Remove, Right, Left /// Заменяет в указанной строке все вхождения регулярного выражения указанной строкой замены и возвращает преобразованную строку -function Replace(Self: string; reg,repl: string; options: RegexOptions := RegexOptions.None): string; extensionmethod; +function RegexReplace(Self: string; reg, repl: string; options: RegexOptions := RegexOptions.None): string; extensionmethod; begin - Result := Regex.Replace(Self,reg,repl,options) + Result := Regex.Replace(Self, reg, repl, options) +end; + +/// Заменяет в указанной строке все вхождения регулярного выражения указанным преобразованием замены и возвращает преобразованную строку +function RegexReplace(Self: string; reg: string; repl: &Match->string; options: RegexOptions := RegexOptions.None): string; extensionmethod; +begin + Result := Regex.Replace(Self, reg, repl, options) end; /// Ищет в указанной строке все вхождения регулярного выражения и возвращает их в виде последовательности элементов типа Match function Matches(Self: string; reg: string; options: RegexOptions := RegexOptions.None): sequence of &Match; extensionmethod; begin - Result := (new Regex(reg, options)).Matches(Self).Cast&<&Match>(); + Result := (new Regex(reg, options)).Matches(Self).Cast&<&Match>(); end; /// Ищет в указанной строке первое вхождение регулярного выражения и возвращает его в виде строки function MatchValue(Self: string; reg: string; options: RegexOptions := RegexOptions.None): string; extensionmethod; begin - Result := (new Regex(reg, options)).&Match(Self).Value; + Result := (new Regex(reg, options)).&Match(Self).Value; end; /// Ищет в указанной строке все вхождения регулярного выражения и возвращает их в виде последовательности строк function MatchValues(Self: string; reg: string; options: RegexOptions := RegexOptions.None): sequence of string; extensionmethod; begin - Result := Self.Matches(reg,options).Select(m->m.Value); + Result := Self.Matches(reg, options).Select(m -> m.Value); end; +/// Удовлетворяет ли строка регулярному выражению +function IsMatch(Self: string; reg: string; options: RegexOptions := RegexOptions.None): boolean; extensionmethod := Regex.IsMatch(Self, reg, options); + /// Удаляет в строке все вхождения указанных строк function Remove(Self: string; params targets: array of string): string; extensionmethod; begin - var builder := new StringBuilder (Self); - - for var i := 0 to targets.Length-1 do - builder.Replace (targets[i], String.Empty); - - Result := builder.ToString(); + var builder := new StringBuilder(Self); + + for var i := 0 to targets.Length - 1 do + builder.Replace(targets[i], String.Empty); + + Result := builder.ToString(); end; /// Возвращает подстроку, полученную вырезанием из строки length самых правых символов function Right(Self: string; length: integer): string; extensionmethod; begin length := Max(length, 0); - + if Self.Length > length then - Result := Self.Substring(Self.Length - length, length) + Result := Self.Substring(Self.Length - length, length) else Result := Self; end; @@ -9647,18 +10224,18 @@ end; function Left(Self: string; length: integer): string; extensionmethod; begin length := Max(length, 0); - + if Self.Length > length then - Result := Self.Substring(0, length) + Result := Self.Substring(0, length) else Result := Self; end; ///-- -function CreateSliceFromStringInternal(Self: string; from,step,count: integer): string; +function CreateSliceFromStringInternal(Self: string; from, step, count: integer): string; begin var res := new StringBuilder(count); - for var i:=0 to count-1 do + loop count do begin res.Append(Self[from]); from += step; @@ -9667,87 +10244,87 @@ begin end; ///-- -function SliceStringImpl(Self: string; from,step,count: integer): string; +function SliceStringImpl(Self: string; from, step, count: integer): string; begin {if step = 0 then raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0)); - + if (from < 0) or (from > Self.Length - 1) then raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE)); - + var cnt := step > 0 ? Self.Length - from : from + 1; var cntstep := (cnt-1) div abs(step) + 1; if count > cntstep then count := cntstep;} - - CorrectCountForSlice(Self.Length,from,step,count); - Result := CreateSliceFromStringInternal(Self,from+1,step,count); + CorrectCountForSlice(Self.Length, from, step, count); + + Result := CreateSliceFromStringInternal(Self, from + 1, step, count); end; /// Возвращает срез строки от индекса from с шагом step -function Slice(Self: string; from,step: integer): string; extensionmethod; +function Slice(Self: string; from, step: integer): string; extensionmethod; begin - Result := SliceStringImpl(Self,from,step,integer.MaxValue); + Result := SliceStringImpl(Self, from, step, integer.MaxValue); end; /// Возвращает срез строки от индекса from с шагом step длины не более count -function Slice(Self: string; from,step,count: integer): string; extensionmethod; +function Slice(Self: string; from, step, count: integer): string; extensionmethod; begin - Result := SliceStringImpl(Self,from,step,count); + Result := SliceStringImpl(Self, from, step, count); end; ///-- -function SystemSliceStringImpl(Self: string; situation: integer; from,&to: integer; step: integer := 1): string; +function SystemSliceStringImpl(Self: string; situation: integer; from, &to: integer; step: integer := 1): string; begin - var fromv := from-1; - var tov := &to-1; - var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation,Self.Length,fromv,tov,step); - - Result := CreateSliceFromStringInternal(Self,fromv+1,step,count) + var fromv := from - 1; + var tov := &to - 1; + var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation, Self.Length, fromv, tov, step); + + Result := CreateSliceFromStringInternal(Self, fromv + 1, step, count) end; ///-- -function SystemSlice(Self: string; situation: integer; from,&to: integer): string; extensionmethod; +function SystemSlice(Self: string; situation: integer; from, &to: integer): string; extensionmethod; begin - Result := SystemSliceStringImpl(Self,situation,from,&to,1); + Result := SystemSliceStringImpl(Self, situation, from, &to, 1); end; ///-- -function SystemSlice(Self: string; situation: integer; from,&to,step: integer): string; extensionmethod; +function SystemSlice(Self: string; situation: integer; from, &to, step: integer): string; extensionmethod; begin - Result := SystemSliceStringImpl(Self,situation,from,&to,step); + Result := SystemSliceStringImpl(Self, situation, from, &to, step); end; ///-- -function SystemSliceStringImplQuestion(Self: string; situation: integer; from,&to: integer; step: integer := 1): string; +function SystemSliceStringImplQuestion(Self: string; situation: integer; from, &to: integer; step: integer := 1): string; begin - var fromv := from-1; - var tov := &to-1; + var fromv := from - 1; + var tov := &to - 1; - var count := CorrectFromToAndCalcCountForSystemSliceQuestion(situation,Self.Length,fromv,tov,step); + var count := CorrectFromToAndCalcCountForSystemSliceQuestion(situation, Self.Length, fromv, tov, step); - Result := CreateSliceFromStringInternal(Self,fromv+1,step,count); + Result := CreateSliceFromStringInternal(Self, fromv + 1, step, count); end; ///-- -function SystemSliceQuestion(Self: string; situation: integer; from,&to: integer): string; extensionmethod; +function SystemSliceQuestion(Self: string; situation: integer; from, &to: integer): string; extensionmethod; begin - Result := SystemSliceStringImplQuestion(Self,situation,from,&to,1); + Result := SystemSliceStringImplQuestion(Self, situation, from, &to, 1); end; ///-- -function SystemSliceQuestion(Self: string; situation: integer; from,&to,step: integer): string; extensionmethod; +function SystemSliceQuestion(Self: string; situation: integer; from, &to, step: integer): string; extensionmethod; begin - Result := SystemSliceStringImplQuestion(Self,situation,from,&to,step); + Result := SystemSliceStringImplQuestion(Self, situation, from, &to, step); end; //-------------------------------------------- //>> Методы расширения типа Func # Extension methods for Func //-------------------------------------------- /// Суперпозиция функций -function Compose (Self: T2 -> TResult; composer: T1 -> T2): T1 -> TResult; extensionmethod; +function Compose(Self: T2->TResult; composer: T1->T2): T1->TResult; extensionmethod; begin - if composer=nil then + if composer = nil then raise new System.ArgumentNullException('composer'); var Slf := Self; Result := x -> Slf(composer(x)); @@ -9766,9 +10343,9 @@ end; //>> Методы расширения IDictionary # Extension methods for IDictionary // ----------------------------------------------------------------------------- /// Возвращает в словаре значение, связанное с указанным ключом, а если такого ключа нет, то значение по умолчанию -function Get(Self: IDictionary; K: Key): Value; extensionmethod; +function Get(Self: IDictionary; K: Key): Value; extensionmethod; begin - var b := Self.TryGetValue(K,Result); + var b := Self.TryGetValue(K, Result); if not b then Result := default(Value); end; @@ -9780,9 +10357,9 @@ end; // Операции для Func //------------------------------------------------------------------------------ ///-- -function operator* (Self: T2 -> TResult; composer: T1 -> T2): T1 -> TResult; extensionmethod; +function operator*(Self: T2->TResult; composer: T1->T2): T1->TResult; extensionmethod; begin - if composer=nil then + if composer = nil then raise new System.ArgumentNullException('composer'); Result := Self.Compose(composer); end; @@ -9791,113 +10368,224 @@ end; // Операции для Tuple //------------------------------------------------------------------------------ ///-- -function operator+ (Self: (T1,T2); v: T3): (T1,T2,T3); extensionmethod; +function operator+(Self: (T1, T2); v: T3): (T1, T2, T3); extensionmethod; begin - Result := (Self[0],Self[1],v); + Result := (Self[0], Self[1], v); end; ///-- -function operator+ (Self: (T1,T2,T3); v: T4): (T1,T2,T3,T4); extensionmethod; +function operator+(Self: (T1, T2, T3); v: T4): (T1, T2, T3, T4); extensionmethod; begin - Result := (Self[0],Self[1],Self[2],v); + Result := (Self[0], Self[1], Self[2], v); end; ///-- -function operator+ (Self: (T1,T2,T3,T4); v: T5): (T1,T2,T3,T4,T5); extensionmethod; +function operator+(Self: (T1, T2, T3, T4); v: T5): (T1, T2, T3, T4, T5); extensionmethod; begin - Result := (Self[0],Self[1],Self[2],Self[3],v); + Result := (Self[0], Self[1], Self[2], Self[3], v); end; ///-- -function operator+ (Self: (T1,T2,T3,T4,T5); v: T6): (T1,T2,T3,T4,T5,T6); extensionmethod; +function operator+(Self: (T1, T2, T3, T4, T5); v: T6): (T1, T2, T3, T4, T5, T6); extensionmethod; begin - Result := (Self[0],Self[1],Self[2],Self[3],Self[4],v); + Result := (Self[0], Self[1], Self[2], Self[3], Self[4], v); end; ///-- -function operator+ (Self: (T1,T2,T3,T4,T5,T6); v: T7): (T1,T2,T3,T4,T5,T6,T7); extensionmethod; +function operator+(Self: (T1, T2, T3, T4, T5, T6); v: T7): (T1, T2, T3, T4, T5, T6, T7); extensionmethod; begin - Result := (Self[0],Self[1],Self[2],Self[3],Self[4],Self[5],v); + Result := (Self[0], Self[1], Self[2], Self[3], Self[4], Self[5], v); end; ///-- -function operator= (Self: (T1,T2); v: (T1,T2)); extensionmethod := Self.Equals( v ) ; -///-- -function operator<> (Self: (T1,T2); v: (T1,T2)); extensionmethod := not Self.Equals( v ); -///-- -function CompareToTup2(v1: (T1,T2); v2: (T1,T2)) := (v1 as System.IComparable).CompareTo(v2); -///-- -function operator< (Self: (T1,T2); v: (T1,T2)); extensionmethod := CompareToTup2(Self,v) < 0; -///-- -function operator<= (Self: (T1,T2); v: (T1,T2)); extensionmethod := CompareToTup2(Self,v) <= 0; -///-- -function operator> (Self: (T1,T2); v: (T1,T2)); extensionmethod := CompareToTup2(Self,v) > 0; -///-- -function operator>= (Self: (T1,T2); v: (T1,T2)); extensionmethod := CompareToTup2(Self,v) >= 0; +function InternalEqual (x: (T1,T2); y: (T1,T2)): boolean; +begin + var xn := Object.ReferenceEquals(x,nil); + var yn := Object.ReferenceEquals(y,nil); + if xn then + Result := yn + else if yn then + Result := xn + else Result := x.Equals(y); +end; ///-- -function operator= (Self: (T1,T2,T3); v: (T1,T2,T3)); extensionmethod := Self.Equals( v ) ; +function operator= (x: (T1,T2); y: (T1,T2)): boolean; extensionmethod := InternalEqual(x,y); ///-- -function operator<> (Self: (T1,T2,T3); v: (T1,T2,T3)); extensionmethod := not Self.Equals( v ); +function operator<> (x: (T1,T2); y: (T1,T2)): boolean; extensionmethod := not InternalEqual(x,y); ///-- -function CompareToTup3(v1: (T1,T2,T3); v2: (T1,T2,T3)) := (v1 as System.IComparable).CompareTo(v2); +function CompareToTup2(v1: (T1, T2); v2: (T1, T2)) := (v1 as System.IComparable).CompareTo(v2); ///-- -function operator< (Self: (T1,T2,T3); v: (T1,T2,T3)); extensionmethod := CompareToTup3(Self,v) < 0; +function operator<(Self: (T1, T2); v: (T1, T2)); extensionmethod := CompareToTup2(Self, v) < 0; ///-- -function operator<= (Self: (T1,T2,T3); v: (T1,T2,T3)); extensionmethod := CompareToTup3(Self,v) <= 0; +function operator<=(Self: (T1, T2); v: (T1, T2)); extensionmethod := CompareToTup2(Self, v) <= 0; ///-- -function operator> (Self: (T1,T2,T3); v: (T1,T2,T3)); extensionmethod := CompareToTup3(Self,v) > 0; +function operator>(Self: (T1, T2); v: (T1, T2)); extensionmethod := CompareToTup2(Self, v) > 0; ///-- -function operator>= (Self: (T1,T2,T3); v: (T1,T2,T3)); extensionmethod := CompareToTup3(Self,v) >= 0; +function operator>=(Self: (T1, T2); v: (T1, T2)); extensionmethod := CompareToTup2(Self, v) >= 0; ///-- -function operator= (Self: (T1,T2,T3,T4); v: (T1,T2,T3,T4)); extensionmethod := Self.Equals( v ) ; +function InternalEqual (x: (T1,T2,T3); y: (T1,T2,T3)): boolean; +begin + var xn := Object.ReferenceEquals(x,nil); + var yn := Object.ReferenceEquals(y,nil); + if xn then + Result := yn + else if yn then + Result := xn + else Result := x.Equals(y); +end; ///-- -function operator<> (Self: (T1,T2,T3,T4); v: (T1,T2,T3,T4)); extensionmethod := not Self.Equals( v ); +function operator= (x: (T1,T2,T3); y: (T1,T2,T3)); extensionmethod := InternalEqual(x,y); ///-- -function CompareToTup4(v1: (T1,T2,T3,T4); v2: (T1,T2,T3,T4)) := (v1 as System.IComparable).CompareTo(v2); +function operator<> (x: (T1,T2,T3); y: (T1,T2,T3)); extensionmethod := not InternalEqual(x,y); ///-- -function operator< (Self: (T1,T2,T3,T4); v: (T1,T2,T3,T4)); extensionmethod := CompareToTup4(Self,v) < 0; +function CompareToTup3(v1: (T1, T2, T3); v2: (T1, T2, T3)) := (v1 as System.IComparable).CompareTo(v2); ///-- -function operator<= (Self: (T1,T2,T3,T4); v: (T1,T2,T3,T4)); extensionmethod := CompareToTup4(Self,v) <= 0; +function operator<(Self: (T1, T2, T3); v: (T1, T2, T3)); extensionmethod := CompareToTup3(Self, v) < 0; ///-- -function operator> (Self: (T1,T2,T3,T4); v: (T1,T2,T3,T4)); extensionmethod := CompareToTup4(Self,v) > 0; +function operator<=(Self: (T1, T2, T3); v: (T1, T2, T3)); extensionmethod := CompareToTup3(Self, v) <= 0; ///-- -function operator>= (Self: (T1,T2,T3,T4); v: (T1,T2,T3,T4)); extensionmethod := CompareToTup4(Self,v) >= 0; +function operator>(Self: (T1, T2, T3); v: (T1, T2, T3)); extensionmethod := CompareToTup3(Self, v) > 0; +///-- +function operator>=(Self: (T1, T2, T3); v: (T1, T2, T3)); extensionmethod := CompareToTup3(Self, v) >= 0; +///-- +function InternalEqual (x: (T1,T2,T3,T4); y: (T1,T2,T3,T4)): boolean; +begin + var xn := Object.ReferenceEquals(x,nil); + var yn := Object.ReferenceEquals(y,nil); + if xn then + Result := yn + else if yn then + Result := xn + else Result := x.Equals(y); +end; +///-- +function operator= (x: (T1,T2,T3,T4); y: (T1,T2,T3,T4)); extensionmethod := InternalEqual(x,y); +///-- +function operator<> (x: (T1,T2,T3,T4); y: (T1,T2,T3,T4)); extensionmethod := not InternalEqual(x,y); +///-- +function CompareToTup4(v1: (T1, T2, T3, T4); v2: (T1, T2, T3, T4)) := (v1 as System.IComparable).CompareTo(v2); +///-- +function operator<(Self: (T1, T2, T3, T4); v: (T1, T2, T3, T4)); extensionmethod := CompareToTup4(Self, v) < 0; +///-- +function operator<=(Self: (T1, T2, T3, T4); v: (T1, T2, T3, T4)); extensionmethod := CompareToTup4(Self, v) <= 0; +///-- +function operator>(Self: (T1, T2, T3, T4); v: (T1, T2, T3, T4)); extensionmethod := CompareToTup4(Self, v) > 0; +///-- +function operator>=(Self: (T1, T2, T3, T4); v: (T1, T2, T3, T4)); extensionmethod := CompareToTup4(Self, v) >= 0; + +///-- +function InternalEqual (x: (T1,T2,T3,T4,T5); y: (T1,T2,T3,T4,T5)): boolean; +begin + var xn := Object.ReferenceEquals(x,nil); + var yn := Object.ReferenceEquals(y,nil); + if xn then + Result := yn + else if yn then + Result := xn + else Result := x.Equals(y); +end; +///-- +function operator= (x: (T1,T2,T3,T4,T5); y: (T1,T2,T3,T4,T5)); extensionmethod := InternalEqual(x,y); +///-- +function operator<> (x: (T1,T2,T3,T4,T5); y: (T1,T2,T3,T4,T5)); extensionmethod := not InternalEqual(x,y); +///-- +function CompareToTup5(v1: (T1, T2, T3, T4,T5); v2: (T1, T2, T3, T4,T5)) := (v1 as System.IComparable).CompareTo(v2); +///-- +function operator<(Self: (T1, T2, T3, T4,T5); v: (T1, T2, T3, T4,T5)); extensionmethod := CompareToTup5(Self, v) < 0; +///-- +function operator<=(Self: (T1, T2, T3, T4,T5); v: (T1, T2, T3, T4,T5)); extensionmethod := CompareToTup5(Self, v) <= 0; +///-- +function operator>(Self: (T1, T2, T3, T4,T5); v: (T1, T2, T3, T4,T5)); extensionmethod := CompareToTup5(Self, v) > 0; +///-- +function operator>=(Self: (T1, T2, T3, T4,T5); v: (T1, T2, T3, T4,T5)); extensionmethod := CompareToTup5(Self, v) >= 0; + +///-- +function InternalEqual (x: (T1,T2,T3,T4,T5,T6); y: (T1,T2,T3,T4,T5,T6)): boolean; +begin + var xn := Object.ReferenceEquals(x,nil); + var yn := Object.ReferenceEquals(y,nil); + if xn then + Result := yn + else if yn then + Result := xn + else Result := x.Equals(y); +end; +///-- +function operator= (x: (T1,T2,T3,T4,T5,T6); y: (T1,T2,T3,T4,T5,T6)); extensionmethod := InternalEqual(x,y); +///-- +function operator<> (x: (T1,T2,T3,T4,T5,T6); y: (T1,T2,T3,T4,T5,T6)); extensionmethod := not InternalEqual(x,y); +///-- +function CompareToTup5(v1: (T1, T2, T3, T4,T5,T6); v2: (T1, T2, T3, T4,T5,T6)) := (v1 as System.IComparable).CompareTo(v2); +///-- +function operator<(Self: (T1, T2, T3, T4,T5,T6); v: (T1, T2, T3, T4,T5,T6)); extensionmethod := CompareToTup5(Self, v) < 0; +///-- +function operator<=(Self: (T1, T2, T3, T4,T5,T6); v: (T1, T2, T3, T4,T5,T6)); extensionmethod := CompareToTup5(Self, v) <= 0; +///-- +function operator>(Self: (T1, T2, T3, T4,T5,T6); v: (T1, T2, T3, T4,T5,T6)); extensionmethod := CompareToTup5(Self, v) > 0; +///-- +function operator>=(Self: (T1, T2, T3, T4,T5,T6); v: (T1, T2, T3, T4,T5,T6)); extensionmethod := CompareToTup5(Self, v) >= 0; + +///-- +function InternalEqual (x: (T1,T2,T3,T4,T5,T6,T7); y: (T1,T2,T3,T4,T5,T6,T7)): boolean; +begin + var xn := Object.ReferenceEquals(x,nil); + var yn := Object.ReferenceEquals(y,nil); + if xn then + Result := yn + else if yn then + Result := xn + else Result := x.Equals(y); +end; +///-- +function operator= (x: (T1,T2,T3,T4,T5,T6,T7); y: (T1,T2,T3,T4,T5,T6,T7)); extensionmethod := InternalEqual(x,y); +///-- +function operator<> (x: (T1,T2,T3,T4,T5,T6,T7); y: (T1,T2,T3,T4,T5,T6,T7)); extensionmethod := not InternalEqual(x,y); +///-- +function CompareToTup5(v1: (T1, T2, T3, T4,T5,T6,T7); v2: (T1, T2, T3, T4,T5,T6,T7)) := (v1 as System.IComparable).CompareTo(v2); +///-- +function operator<(Self: (T1, T2, T3, T4,T5,T6,T7); v: (T1, T2, T3, T4,T5,T6,T7)); extensionmethod := CompareToTup5(Self, v) < 0; +///-- +function operator<=(Self: (T1, T2, T3, T4,T5,T6,T7); v: (T1, T2, T3, T4,T5,T6,T7)); extensionmethod := CompareToTup5(Self, v) <= 0; +///-- +function operator>(Self: (T1, T2, T3, T4,T5,T6,T7); v: (T1, T2, T3, T4,T5,T6,T7)); extensionmethod := CompareToTup5(Self, v) > 0; +///-- +function operator>=(Self: (T1, T2, T3, T4,T5,T6,T7); v: (T1, T2, T3, T4,T5,T6,T7)); extensionmethod := CompareToTup5(Self, v) >= 0; // -------------------------------------------- // Методы расширения типа Tuple # Extension methods for Tuple // ------------------------------------------- // Дополнения февраль 2016 // Добавляет поле к кортежу -function Add (Self: (T1,T2); v: T3): (T1,T2,T3); extensionmethod; +function Add(Self: (T1, T2); v: T3): (T1, T2, T3); extensionmethod; begin - Result := (Self[0],Self[1],v); + Result := (Self[0], Self[1], v); end; // Добавляет поле к кортежу -function Add (Self: (T1,T2,T3); v: T4): (T1,T2,T3,T4); extensionmethod; +function Add(Self: (T1, T2, T3); v: T4): (T1, T2, T3, T4); extensionmethod; begin - Result := (Self[0],Self[1],Self[2],v); + Result := (Self[0], Self[1], Self[2], v); end; // Добавляет поле к кортежу -function Add (Self: (T1,T2,T3,T4); v: T5): (T1,T2,T3,T4,T5); extensionmethod; +function Add(Self: (T1, T2, T3, T4); v: T5): (T1, T2, T3, T4, T5); extensionmethod; begin - Result := (Self[0],Self[1],Self[2],Self[3],v); + Result := (Self[0], Self[1], Self[2], Self[3], v); end; // Добавляет поле к кортежу -function Add (Self: (T1,T2,T3,T4,T5); v: T6): (T1,T2,T3,T4,T5,T6); extensionmethod; +function Add(Self: (T1, T2, T3, T4, T5); v: T6): (T1, T2, T3, T4, T5, T6); extensionmethod; begin - Result := (Self[0],Self[1],Self[2],Self[3],Self[4],v); + Result := (Self[0], Self[1], Self[2], Self[3], Self[4], v); end; // Добавляет поле к кортежу -function Add (Self: (T1,T2,T3,T4,T5,T6); v: T7): (T1,T2,T3,T4,T5,T6,T7); extensionmethod; +function Add(Self: (T1, T2, T3, T4, T5, T6); v: T7): (T1, T2, T3, T4, T5, T6, T7); extensionmethod; begin - Result := (Self[0],Self[1],Self[2],Self[3],Self[4],Self[5],v); + Result := (Self[0], Self[1], Self[2], Self[3], Self[4], Self[5], v); end; {// Определяет, есть ли указанный элемент в массиве @@ -9974,18 +10662,18 @@ begin //begin case System.Type.GetTypeCode(t) of TypeCode.Boolean: Result := sizeof(Boolean); - TypeCode.Byte: Result := sizeof(Byte); - TypeCode.Char: Result := 1;//sizeof(Char); + TypeCode.Byte: Result := sizeof(Byte); + TypeCode.Char: Result := 1;//sizeof(Char); TypeCode.Decimal: Result := sizeof(Decimal); - TypeCode.Double: Result := sizeof(Double); - TypeCode.Int16: Result := sizeof(Int16); - TypeCode.Int32: Result := sizeof(Int32); - TypeCode.Int64: Result := sizeof(Int64); - TypeCode.UInt16: Result := sizeof(UInt16); - TypeCode.UInt32: Result := sizeof(UInt32); - TypeCode.UInt64: Result := sizeof(UInt64); - TypeCode.SByte: Result := sizeof(SByte); - TypeCode.Single: Result := sizeof(Single); + TypeCode.Double: Result := sizeof(Double); + TypeCode.Int16: Result := sizeof(Int16); + TypeCode.Int32: Result := sizeof(Int32); + TypeCode.Int64: Result := sizeof(Int64); + TypeCode.UInt16: Result := sizeof(UInt16); + TypeCode.UInt32: Result := sizeof(UInt32); + TypeCode.UInt64: Result := sizeof(UInt64); + TypeCode.SByte: Result := sizeof(SByte); + TypeCode.Single: Result := sizeof(Single); else if t.IsEnum then result := sizeof(integer); end//; //end @@ -10070,7 +10758,7 @@ end; function GetResourceStream(ResourceFileName: string): Stream; begin - result := System.Reflection.Assembly.GetEntryAssembly().GetManifestResourceStream(ResourceFileName); + Result := System.Reflection.Assembly.GetEntryAssembly().GetManifestResourceStream(ResourceFileName); end; function FormatValue(value: object; NumOfChars: integer): string; @@ -10109,9 +10797,6 @@ end; procedure StringDefaultPropertySet(var s: string; index: integer; c: char); begin - //s := string.Concat( s.Copy(0,index-1), c, s.Copy(index, s.Length - index)); - //s := string.Concat(s.Substring(0, index), c, s.Substring(index + 1)); - //ChangeChar(s[index + 1], c); var chars := s.ToCharArray; chars[index] := c; s := new String(chars); @@ -10123,8 +10808,6 @@ begin end; procedure CheckCanUsePointerOnType(T: System.Type); -var - fields: array of System.Reflection.FieldInfo; begin if T.IsPointer then begin @@ -10133,7 +10816,7 @@ begin end; if T.IsValueType then begin - fields := T.GetFields(); + var fields := T.GetFields(); foreach var fi in fields do if not fi.IsStatic then CheckCanUsePointerOnType(fi.FieldType); @@ -10216,7 +10899,7 @@ begin begin variable.GetType.InvokeMember('$Init$', System.Reflection.BindingFlags.InvokeMethod or - System.Reflection.BindingFlags.Instance or + System.Reflection.BindingFlags.&Instance or System.Reflection.BindingFlags.Public, nil, variable, nil); result := variable; end; @@ -10228,7 +10911,8 @@ begin end; function GetRuntimeSize: integer; -var val: T; +var + val: T; begin result := System.Runtime.InteropServices.Marshal.SizeOf(val); end; @@ -10288,10 +10972,8 @@ begin var src_ind := 0; var dest_ind := 0; internal_copy(source, dest, source_sizes, dest_sizes, 0, src_ind, dest_ind, 0); - Result := dest; - end - else - Result := dest; + end; + Result := dest; end; {function TypedSetComparer.Equals(x: System.Object; y: System.Object): boolean; @@ -10481,13 +11163,13 @@ begin nfi := new System.Globalization.NumberFormatInfo(); nfi.NumberGroupSeparator := '.'; // System.Threading.Thread.CurrentThread.CurrentCulture := new System.Globalization.CultureInfo('en-US'); - rnd := new System.Random; + //rnd := new System.Random; StartTime := DateTime.Now; output := new TextFile(); input := new TextFile(); //var tmp := __CONFIG__; if (Environment.OSVersion.Platform = PlatformID.Unix) or (Environment.OSVersion.Platform = PlatformID.MacOSX) then - foreach listener: System.Diagnostics.TraceListener in System.Diagnostics.Trace.Listeners do + foreach var listener in System.Diagnostics.Trace.Listeners do if listener is System.Diagnostics.DefaultTraceListener then (listener as System.Diagnostics.DefaultTraceListener).AssertUiEnabled := true; end; @@ -10515,6 +11197,15 @@ begin input.sr.Close; end; +// ----------------------------------------------------- +// DQNToNullable for dot_question_node: implementation +// ----------------------------------------------------- + +function DQNToNullable(v: integer): System.Nullable; +begin + Result := new System.Nullable(v); +end; + initialization __InitModule; finalization diff --git a/TestSuite/intellisense_tests/ispattern1.pas b/TestSuite/intellisense_tests/ispattern1.pas new file mode 100644 index 000000000..1d3423c78 --- /dev/null +++ b/TestSuite/intellisense_tests/ispattern1.pas @@ -0,0 +1,14 @@ +type + t1=class end; + +begin + var o:object; + + if o is t1(var o_t1) then + writeln(o_t1{@var o_t1: t1;@}); + if o is t1(var o_t1) then + begin + writeln(o_t1{@var o_t1: t1;@}); + end; + writeln(o_t1{@@}); +end. \ No newline at end of file diff --git a/TestSuite/intellisense_tests/match1.pas b/TestSuite/intellisense_tests/match1.pas new file mode 100644 index 000000000..d8fa26163 --- /dev/null +++ b/TestSuite/intellisense_tests/match1.pas @@ -0,0 +1,22 @@ +type + Line = class + end; + Rectangle = auto class + X,Y,Width,Height: real; + end; + Circle = auto class + X,Y,Radius: real; + end; + +begin + var l := new List; + l.Add(new Line); + l.Add(new Circle(10,10,5)); + l.Add(new Rectangle(10,10,20,10)); + foreach var x in l do + match x with + Line(var ll): Println('Line S =',0); + Circle(var c): Println('Circle S =',c{@var c: Circle;@}.Radius*c.Radius*Pi); + Rectangle(var r{@var r: Rectangle;@}): Println('Rectangle S =',r.Width*r.Height); + end; +end. \ No newline at end of file