pascalabcnet/bin/Lib/PABCSystem.pas
Mikhalkovich Stanislav 228c9f9aac fix #2204
Изменение реализации range на InternalRange и IntRange CharRange

Правки в AutoInsertCode.cs

IntRange и CharRange в PABCSystem.pas - аналогично Котлину
2020-02-14 19:47:41 +03:00

12594 lines
434 KiB
ObjectPascal
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
/// Стандартный модуль
/// !! System unit
unit PABCSystem;
{$define PascalABC}
{$gendoc true}
// Default Application type
{$apptype console}
{$reference '%GAC%\System.dll'}
{$reference '%GAC%\mscorlib.dll'}
{$reference '%GAC%\System.Core.dll'}
{$reference '%GAC%\System.Numerics.dll'}
interface
uses
System.Runtime.InteropServices,
System.IO,
System.Collections,
System.Collections.Generic,
System;
//{{{doc: Начало секции стандартных констант для документации }}}
const
// -----------------------------------------------------
//>> Стандартные константы # Standard constants
// -----------------------------------------------------
/// Максимальное значение типа shortint
MaxShortInt = shortint.MaxValue;
/// Максимальное значение типа byte
MaxByte = byte.MaxValue;
/// Максимальное значение типа smallint
MaxSmallInt = smallint.MaxValue;
/// Максимальное значение типа word
MaxWord = word.MaxValue;
/// Максимальное значение типа longword
MaxLongWord = longword.MaxValue;
/// Максимальное значение типа int64
MaxInt64 = int64.MaxValue;
/// Максимальное значение типа uint64
MaxUInt64 = uint64.MaxValue;
/// Максимальное значение типа double
MaxDouble = real.MaxValue;
/// Минимальное положительное значение типа double
MinDouble = real.Epsilon;
/// Максимальное значение типа real
MaxReal = real.MaxValue;
/// Минимальное положительное значение типа real
MinReal = real.Epsilon;
/// Максимальное значение типа single
MaxSingle = single.MaxValue;
/// Минимальное положительное значение типа single
MinSingle = single.Epsilon;
/// Максимальное значение типа integer
MaxInt = integer.MaxValue;
/// Константа Pi
/// !! Pi constant
Pi = 3.141592653589793;
/// Константа E
/// !! E constant
E = 2.718281828459045;
/// Константа перехода на новую строку
/// !! The newline string defined for this environment.
NewLine = System.Environment.NewLine;
//{{{--doc: Конец секции стандартных констант для документации }}}
//Маркер того, что это системный модуль
///--
const
END_OF_LINE_SYMBOL = #10;
__IS_SYSTEM_MODULE = true;
//{{{doc: Начало секции стандартных типов для документации }}}
type
// -----------------------------------------------------
//>> Стандартные типы # Standard types
// -----------------------------------------------------
/// Базовый тип объектов
Object = System.Object;
/// Базовый тип исключений
Exception = System.Exception;
/// double = real
double = System.Double;
/// longint = integer
longint = System.Int32;
/// cardinal = longword
cardinal = System.UInt32;
/// Представляет 128-битное вещественное число
/// !! Represents a decimal number
decimal = System.Decimal;
/// Представляет произвольно большое целое число
BigInteger = System.Numerics.BigInteger;
/// Представляет дату и время
DateTime = System.DateTime;
/// Представляет комплексное число
Complex = System.Numerics.Complex;
/// Представляет кортеж
Tuple = System.Tuple;
/// Представляет список на базе динамического массива
List<T> = System.Collections.Generic.List<T>;
/// Представляет базовый класс для реализации интерфейса IComparer
Comparer<T> = System.Collections.Generic.Comparer<T>;
/// Представляет базовый класс для реализации интерфейса IComparer
IComparable<T> = System.IComparable<T>;
/// Представляет множество значений, реализованное на базе хеш-таблицы
HashSet<T> = System.Collections.Generic.HashSet<T>;
/// Представляет множество значений, реализованное на базе бинарного дерева поиска
SortedSet<T> = System.Collections.Generic.SortedSet<T>;
/// Представляет ассоциативный массив (набор пар Ключ-Значение), реализованный на базе хеш-таблицы
Dictionary<Key, Value> = System.Collections.Generic.Dictionary<Key, Value>;
/// Представляет ассоциативный массив, реализованный на базе бинарного дерева поиска
SortedDictionary<Key, Value> = System.Collections.Generic.SortedDictionary<Key, Value>;
/// Представляет ассоциативный массив (набор пар ключ-значение), реализованный на базе динамического массива пар
SortedList<Key, Value> = System.Collections.Generic.SortedList<Key, Value>;
/// Представляет пару Ключ-Значение для ассоциативного массива
KeyValuePair<Key, Value> = System.Collections.Generic.KeyValuePair<Key, Value>;
/// Представляет двусвязный список
LinkedList<T> = System.Collections.Generic.LinkedList<T>;
/// Представляет узел двусвязного списка
LinkedListNode<T> = System.Collections.Generic.LinkedListNode<T>;
/// Представляет очередь - набор элементов, реализованных по принципу "первый вошел-первый вышел"
Queue<T> = System.Collections.Generic.Queue<T>;
/// Представляет стек - набор элементов, реализованных по принципу "последний вошел-первый вышел"
Stack<T> = System.Collections.Generic.Stack<T>;
/// Представляет интерфейс для коллекции
ICollection<T> = System.Collections.Generic.ICollection<T>;
/// Представляет интерфейс для сравнения двух элементов
IComparer<T> = System.Collections.Generic.IComparer<T>;
/// Представляет интерфейс для набора пар Ключ-Значение
IDictionary<Key, Value> = System.Collections.Generic.IDictionary<Key, Value>;
/// Представляет интерфейс, предоставляющий перечислитель для перебора элементов коллекции
IEnumerable<T> = System.Collections.Generic.IEnumerable<T>;
/// Представляет интерфейс для перебора элементов коллекции
IEnumerator<T> = System.Collections.Generic.IEnumerator<T>;
/// Представляет интерфейс для поддержки сравнения на равенство
IEqualityComparer<T> = System.Collections.Generic.IEqualityComparer<T>;
/// Представляет интерфейс для коллекции с доступом по индексу
IList<T> = System.Collections.Generic.IList<T>;
/// Представляет интерфейс для множества
ISet<T> = System.Collections.Generic.ISet<T>;
/// Представляет изменяемую строку символов
StringBuilder = System.Text.StringBuilder;
/// Тип кодировки символов
Encoding = System.Text.Encoding;
/// Класс, управляющий консольным окном и консольным вводом-выводом
Console = System.Console;
/// Класс, управляющий сборкой мусора
GC = System.GC;
/// Представляет действие без параметров
Action0 = System.Action;
/// Представляет действие с одним параметром
Action<T> = System.Action<T>;
/// Представляет действие с двумя параметрами
Action2<T1, T2> = System.Action<T1, T2>;
/// Представляет действие с тремя параметрами
Action3<T1, T2, T3> = System.Action<T1, T2, T3>;
/// Представляет функцию без параметров
Func0<Res> = System.Func<Res>;
/// Представляет функцию с одним параметром
Func<T, Res> = System.Func<T, Res>;
/// Представляет функцию с двумя параметрами
Func2<T1, T2, Res> = System.Func<T1, T2, Res>;
/// Представляет функцию с тремя параметрами
Func3<T1, T2, T3, Res> = System.Func<T1, T2, T3, Res>;
/// Представляет функцию с одним параметром целого типа, возвращающую целое
IntFunc = Func<integer, integer>;
/// Представляет функцию с одним параметром вещественного типа, возвращающую вещественное
RealFunc = Func<real, real>;
/// Представляет функцию с одним параметром строкового типа, возвращающую строку
StringFunc = Func<string, string>;
/// Представляет функцию с одним параметром, возвращающую boolean
Predicate<T> = System.Predicate<T>;
/// Представляет функцию с двумя параметрами, возвращающую boolean
Predicate2<T1, T2> = function(x1: T1; x2: T2): boolean;
/// Представляет функцию с тремя параметрами, возвращающую boolean
Predicate3<T1, T2, T3> = 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;
/// Представляет параметры регулярного выражения
RegexOptions = System.Text.RegularExpressions.RegexOptions;
/// Представляет результаты из одной группы при выполнении Regex.Match
RegexGroup = System.Text.RegularExpressions.Group;
/// Представляет результаты из набора групп при выполнении Regex.Match
RegexGroupCollection = System.Text.RegularExpressions.GroupCollection;
/// Представляет тип короткой строки фиксированной длины 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
//8
PSingle = ^single;//single
//16
PReal = ^real;//double
PDouble = ^double;//double //ошибка, не сохранится, надо исправить
//------------------------------------------------------------------------------
// -----------------------------------------------------
// IOSystem interface & IOStandardSystem implementation
// -----------------------------------------------------
type
/// Интерфейс подсистемы ввода/вывода
IOSystem = interface
function peek: integer;
function read_symbol: char;
procedure read(var x: integer);
procedure read(var x: real);
procedure read(var x: char);
procedure read(var x: string);
procedure read(var x: byte);
procedure read(var x: shortint);
procedure read(var x: smallint);
procedure read(var x: word);
procedure read(var x: longword);
procedure read(var x: int64);
procedure read(var x: uint64);
procedure read(var x: single);
procedure read(var x: boolean);
procedure read(var x: BigInteger);
procedure readln;
function ReadLine: string;
function ReadLexem: string;
procedure write(obj: object);
procedure write(p: pointer);
procedure writeln;
end;
/// Стандартная подсистема ввода-вывода
IOStandardSystem = class(IOSystem)
state := 0; // 0 - нет символа в буфере char, 1 - есть символ в буфере char
sym: integer; // буфер в 1 символ для моделирования Peek в консоли
buf: array of char;
pos := 0;
realbuflen := -1; // только вначале
tr: TextReader;
public
constructor Create;
procedure ReadNextBuf;
function peek: integer; virtual;// использует state и sym (стар) или буфер buf (нов)
function read_symbol: char; virtual;// использует state и sym (стар) или буфер buf (нов)
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: 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 read(var x: BigInteger); virtual;
procedure readln; virtual;
function ReadLine: string; virtual;
function ReadLexem: string; virtual;
procedure write(p: pointer); virtual;
procedure write(obj: object); virtual;
procedure writeln; virtual;
end;
// -----------------------------------------------------
// Classes for files & typed sets
// -----------------------------------------------------
type
/// Тип текстового файла
Text = class
private
fi: FileInfo;
sr: StreamReader;
sw: StreamWriter;
public
/// Возвращает значение типа integer, введенное из текстового файла
function ReadInteger: integer;
/// Возвращает значение типа real, введенное из текстового файла
function ReadReal: real;
/// Возвращает значение типа char, введенное из текстового файла
function ReadChar: char;
/// Возвращает значение типа string, введенное из текстового файла, без перехода на следующую строку
function ReadString: string;
/// Возвращает значение типа boolean, введенное из текстового файла
function ReadBoolean: boolean;
/// Возвращает слово, введенное из текстового файла
function ReadWord: string;
/// Возвращает значение типа integer, введенное из текстового файла, и переходит на следующую строку
function ReadlnInteger: integer;
/// Возвращает значение типа real, введенное из текстового файла, и переходит на следующую строку
function ReadlnReal: real;
/// Возвращает значение типа char, введенное из текстового файла, и переходит на следующую строку
function ReadlnChar: char;
/// Возвращает значение типа string, введенное из текстового файла, и переходит на следующую строку
function ReadlnString: string;
/// Возвращает значение типа boolean, введенное из текстового файла, и переходит на следующую строку
function ReadlnBoolean: boolean;
/// Переходит в файле на следующую строку
procedure Readln;
/// Записывает в текстовый файл значения
procedure Write(params o: array of Object);
/// Записывает в текстовый файл значения и переходит на следующую строку
procedure Writeln(params o: array of Object);
/// Записывает в текстовый файл значения, разделяя их пробелами
procedure Print(params o: array of Object);
/// Записывает в текстовый файл значения, разделяя их пробелами, и переходит на следующую строку
procedure Println(params o: array of Object);
/// Возвращает True, если достигнут конец файла, и False в противном случае
function Eof: boolean;
/// Возвращает True, если достигнут конец строки, и False в противном случае
function Eoln: boolean;
/// Закрывает файл
procedure Close;
/// Пропускает пробельные символы, после чего возвращает True, если достигнут конец файла
function SeekEof: boolean;
/// Пропускает пробельные символы, после чего возвращает True, если достигнут конец строки в файле
function SeekEoln: boolean;
/// Записывает содержимое буфера файла на диск
procedure Flush;
/// Удаляет файл
procedure Erase;
/// Переименовывает файл, давая ему имя newname
procedure Rename(newname: string);
/// Возвращает имя файла
function Name: string;
/// Возвращает полное имя файла
function FullName: string;
/// Возвращает в виде строки содержимое файла от текущего положения до конца
function ReadToEnd: string;
/// Открывает текстовый файл на чтение в кодировке Windows
procedure Reset;
/// Открывает текстовый файл на чтение в указанной кодировке
procedure Reset(en: Encoding);
/// Открывает текстовый файл на запись в кодировке Windows
procedure Rewrite;
/// Открывает текстовый файл на запись в указанной кодировке
procedure Rewrite(en: Encoding);
/// Открывает текстовый файл на дополнение в кодировке Windows
procedure Append;
/// Открывает текстовый файл на дополнение в указанной кодировке
procedure Append(en: Encoding);
/// Возвращает последовательность строк открытого текстового файла
function Lines: sequence of string;
end;
/// Тип текстового файла
TextFile = Text;
type
// Вспомогательный тип для диапазонного типа
///--
Diapason = record
low, high: integer;
clow, chigh: object;
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
// Вспомогательный тип для множества
///--
TypedSet = class (System.Collections.IEnumerable)
private
ht: Hashtable;
len: integer;
//copy_ht: Hashtable;
low_bound, upper_bound: object;
public
constructor Create;
constructor Create(len: integer);
constructor Create(low_bound, upper_bound: object);
constructor Create(vals: array of byte);
constructor Create(initValue: TypedSet);
constructor Create(low_bound, upper_bound: object; initValue: TypedSet);
procedure CreateIfNeed;
function UnionSet(s: TypedSet): TypedSet;
function SubtractSet(s: TypedSet): TypedSet;
function IntersectSet(s: TypedSet): TypedSet;
function CloneSet: TypedSet;
function GetBytes: array of byte;
function IsInDiapason(elem: object): boolean;
function Contains(elem: object): boolean;
procedure Clip;
procedure Clip(len: integer);
procedure IncludeElement(elem: object);
procedure ExcludeElement(elem: object);
procedure Init(params elems: array of object);
procedure AssignSetFrom(s: TypedSet);
function CompareEquals(s: TypedSet): boolean;
function CompareInEquals(s: TypedSet): boolean;
function CompareLess(s: TypedSet): boolean;
function CompareLessEqual(s: TypedSet): boolean;
function CompareGreater(s: TypedSet): boolean;
function CompareGreaterEqual(s: TypedSet): boolean;
function GetEnumerator: System.Collections.IEnumerator;
function ToString: string; override;
class function operator implicit<T>(s: TypedSet): HashSet<T>;
class function operator implicit<T>(s: HashSet<T>): TypedSet;
function Count: integer := ht.Count;
procedure Print(delim: string := ' ');
procedure Println(delim: string := ' ');
end;
type
// Base class for typed and binary files
///--
AbstractBinaryFile = class
private
fi: FileInfo;
fs: FileStream;
br: BinaryReader;
bw: BinaryWriter;
public
/// Закрывает файл
procedure Close;
/// Усекает двоичный файл, отбрасывая все элементы с позиции файлового указателя
procedure Truncate;
/// Возвращает True, если достигнут конец файла
function Eof: boolean;
/// Удаляет файл
procedure Erase;
/// Переименовывает файл, давая ему имя newname
procedure Rename(newname: string);
///- f.Write(a,b,...)
/// Выводит значения a,b,... в двоичный файл
procedure Write(params vals: array of object);
/// Открывает существующий двоичный файл на чтение и запись. Устанавливает файловый указатель на начало файла
procedure Reset;
/// Открывает двоичный файл на чтение и запись. Если файл не существовал, он создаётся, если существовал, он обнуляется
procedure Rewrite;
/// Возвращает имя файла
function Name: string;
/// Возвращает полное имя файла
function FullName: string;
end;
// Class for typed files
///--
TypedFile = sealed class(AbstractBinaryFile)
private
ElementSize: int64;
offset: integer;
offsets: array of integer;
function GetFilePos: int64;
public
ElementType: System.Type;
constructor Create(ElementType: System.Type);
constructor Create(ElementType: System.Type; offs: integer; params offsets: array of integer);
function ToString: string; override;
/// Возвращает количество элементов в типизированном файле
function Size: int64;
/// Устанавливает текущую позицию файлового указателя в типизированном файле на элемент с номером n
procedure Seek(n: int64);
/// Возвращает или устанавливает текущую позицию файлового указателя в типизированном файле
property Position: int64 read GetFilePos write Seek;
end;
// Class for binary files
///--
BinaryFile = sealed class(AbstractBinaryFile)
private
function GetFilePos: int64;
procedure InternalCheck;
public
function ToString: string; override;
/// Открывает существующий бестиповой файл на чтение и запись в указанной кодировке
procedure Reset(en: Encoding);
/// Открывает существующий бестиповой файл на чтение и запись в указанной кодировке. Если файл не существовал, он создаётся, если существовал, он обнуляется
procedure Rewrite(en: Encoding);
/// Возвращает количество байт в бестиповом файле
function Size: int64;
/// Устанавливает текущую позицию файлового указателя в бестиповом файле на байт с номером n
procedure Seek(n: int64);
/// Возвращает или устанавливает текущую позицию файлового указателя в бестиповом файле
property Position: int64 read GetFilePos write Seek;
/// Записывает данные из байтового массива в бестиповой файл
procedure WriteBytes(a: array of byte);
/// Считывает указанное количество байтов из бестипового файла в байтовый массив
function ReadBytes(count: integer): array of byte;
/// Считывает целое из бестипового файла
function ReadInteger: integer;
/// Считывает логическое из бестипового файла
function ReadBoolean: boolean;
/// Считывает байт из бестипового файла
function ReadByte: byte;
/// Считывает символ из бестипового файла
function ReadChar: char;
/// Считывает вещественное из бестипового файла
function ReadReal: real;
/// Считывает строку из бестипового файла
function ReadString: string;
end;
//{{{doc: Начало секции интерфейса для документации }}}
// -----------------------------------------------------
//>> Подпрограммы ввода # Read subroutines
// -----------------------------------------------------
///- procedure Read(a,b,...);
/// Вводит значения a,b,... с клавиатуры
procedure Read;
///--
procedure Read(var x: integer);
///--
procedure Read(var x: real);
///--
procedure Read(var x: char);
///--
procedure Read(var x: string);
///--
procedure Read(var x: byte);
///--
procedure Read(var x: shortint);
///--
procedure Read(var x: smallint);
///--
procedure Read(var x: word);
///--
procedure Read(var x: longword);
///--
procedure Read(var x: int64);
///--
procedure Read(var x: uint64);
///--
procedure Read(var x: single);
///--
procedure Read(var x: boolean);
///--
procedure Read(var x: BigInteger);
///- procedure Readln(a,b,...);
/// Вводит значения 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;
///--
function TryRead(var x: BigInteger): boolean;
/// Возвращает значение типа integer, введенное с клавиатуры
function ReadInteger: integer;
/// Возвращает значение типа int64, введенное с клавиатуры
function ReadInt64: int64;
/// Возвращает значение типа real, введенное с клавиатуры
function ReadReal: real;
/// Возвращает значение типа char, введенное с клавиатуры
function ReadChar: char;
/// Возвращает значение типа string, введенное с клавиатуры
function ReadString: string;
/// Возвращает значение типа boolean, введенное с клавиатуры
function ReadBoolean: boolean;
/// Возвращает значение типа BigInteger, введенное с клавиатуры
function ReadBigInteger: BigInteger;
/// Возвращает следующую лексему
function ReadLexem: string;
/// Возвращает значение типа integer, введенное с клавиатуры, и переходит на следующую строку ввода
function ReadlnInteger: integer;
/// Возвращает значение типа int64, введенное с клавиатуры, и переходит на следующую строку ввода
function ReadlnInt64: int64;
/// Возвращает значение типа real, введенное с клавиатуры, и переходит на следующую строку ввода
function ReadlnReal: real;
/// Возвращает значение типа char, введенное с клавиатуры, и переходит на следующую строку ввода
function ReadlnChar: char;
/// Возвращает значение типа string, введенное с клавиатуры, и переходит на следующую строку ввода
function ReadlnString: string;
/// Возвращает значение типа boolean, введенное с клавиатуры, и переходит на следующую строку ввода
function ReadlnBoolean: boolean;
/// Возвращает значение типа BigInteger, введенное с клавиатуры, и переходит на следующую строку ввода
function ReadlnBigInteger: BigInteger;
/// Возвращает кортеж из двух значений типа 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 ReadInteger4: (integer, integer, integer, integer);
/// Возвращает кортеж из четырёх значений типа real, введенных с клавиатуры
function ReadReal4: (real, real, real, real);
/// Возвращает кортеж из четырёх значений типа char, введенных с клавиатуры
function ReadChar4: (char, char, char, char);
/// Возвращает кортеж из четырёх значений типа string, введенных с клавиатуры
function ReadString4: (string, string, string, string);
/// Возвращает кортеж из четырёх значений типа integer, введенных с клавиатуры, и переходит на следующую строку ввода
function ReadlnInteger4: (integer, integer, integer, integer);
/// Возвращает кортеж из четырёх значений типа real, введенных с клавиатуры, и переходит на следующую строку ввода
function ReadlnReal4: (real, real, real, real);
/// Возвращает кортеж из четырёх значений типа char, введенных с клавиатуры, и переходит на следующую строку ввода
function ReadlnChar4: (char, char, char, char);
/// Возвращает кортеж из четырёх значений типа string, введенных с клавиатуры, и переходит на следующую строку ввода
function ReadlnString4: (string, 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 ReadInteger4(prompt: string): (integer, integer, integer, integer);
/// Возвращает кортеж из четырёх значений типа real, введенных с клавиатуры
function ReadReal4(prompt: string): (real, real, real, real);
/// Возвращает кортеж из четырёх значений типа char, введенных с клавиатуры
function ReadChar4(prompt: string): (char, char, char, char);
/// Возвращает кортеж из четырёх значений типа string, введенных с клавиатуры
function ReadString4(prompt: string): (string, string, string, string);
/// Возвращает кортеж из четырёх значений типа integer, введенных с клавиатуры, и переходит на следующую строку ввода
function ReadlnInteger4(prompt: string): (integer, integer, integer, integer);
/// Возвращает кортеж из четырёх значений типа real, введенных с клавиатуры, и переходит на следующую строку ввода
function ReadlnReal4(prompt: string): (real, real, real, real);
/// Возвращает кортеж из четырёх значений типа char, введенных с клавиатуры, и переходит на следующую строку ввода
function ReadlnChar4(prompt: string): (char, char, char, char);
/// Возвращает кортеж из четырёх значений типа string, введенных с клавиатуры, и переходит на следующую строку ввода
function ReadlnString4(prompt: string): (string, string, string, string);
/// Выводит приглашение к вводу и возвращает значение типа integer, введенное с клавиатуры
function ReadInteger(prompt: string): integer;
/// Выводит приглашение к вводу и возвращает значение типа int64, введенное с клавиатуры
function ReadInt64(prompt: string): int64;
/// Выводит приглашение к вводу и возвращает значение типа real, введенное с клавиатуры
function ReadReal(prompt: string): real;
/// Выводит приглашение к вводу и возвращает значение типа char, введенное с клавиатуры
function ReadChar(prompt: string): char;
/// Выводит приглашение к вводу и возвращает значение типа string, введенное с клавиатуры
function ReadString(prompt: string): string;
/// Выводит приглашение к вводу и возвращает значение типа boolean, введенное с клавиатуры
function ReadBoolean(prompt: string): boolean;
/// Выводит приглашение к вводу и возвращает значение типа integer, введенное с клавиатуры,
///и осуществляет переход на следующую строку ввода
function ReadlnInteger(prompt: string): integer;
/// Выводит приглашение к вводу и возвращает значение типа int64, введенное с клавиатуры,
///и осуществляет переход на следующую строку ввода
function ReadlnInt64(prompt: string): int64;
/// Выводит приглашение к вводу и возвращает значение типа real, введенное с клавиатуры,
///и осуществляет переход на следующую строку ввода
function ReadlnReal(prompt: string): real;
/// Выводит приглашение к вводу и возвращает значение типа char, введенное с клавиатуры,
///и осуществляет переход на следующую строку ввода
function ReadlnChar(prompt: string): char;
/// Выводит приглашение к вводу и возвращает значение типа string, введенное с клавиатуры,
///и осуществляет переход на следующую строку ввода
function ReadlnString(prompt: string): string;
/// Выводит приглашение к вводу и возвращает значение типа boolean, введенное с клавиатуры,
///и осуществляет переход на следующую строку ввода
function ReadlnBoolean(prompt: string): boolean;
///--
procedure ReadShortString(var s: string; n: integer);
///--
procedure ReadShortStringFromFile(f: Text; var s: string; n: integer);
///- procedure Read(f: файл; a,b,...);
/// Вводит значения a,b,... из файла f
procedure Read(f: Text);
///--
procedure Read(f: Text; var x: integer);
///--
procedure Read(f: Text; var x: real);
///--
procedure Read(f: Text; var x: char);
///--
procedure Read(f: Text; var x: string);
///--
procedure Read(f: Text; var x: byte);
///--
procedure Read(f: Text; var x: shortint);
///--
procedure Read(f: Text; var x: smallint);
///--
procedure Read(f: Text; var x: word);
///--
procedure Read(f: Text; var x: longword);
///--
procedure Read(f: Text; var x: int64);
///--
procedure Read(f: Text; var x: uint64);
///--
procedure Read(f: Text; var x: single);
///--
procedure Read(f: Text; var x: boolean);
///- procedure Readln(f: Text; a,b,...);
/// Вводит значения a,b,... из текстового файла f и осуществляет переход на следующую строку
procedure Readln(f: Text);
///--
procedure Readln(f: Text; var x: string);
/// Возвращает значение типа integer, введенное из текстового файла f
function ReadInteger(f: Text): integer;
/// Возвращает значение типа int64, введенное из текстового файла f
function ReadInt64(f: Text): int64;
/// Возвращает значение типа real, введенное из текстового файла f
function ReadReal(f: Text): real;
/// Возвращает значение типа char, введенное из текстового файла f
function ReadChar(f: Text): char;
/// Возвращает значение типа string, введенное из текстового файла f
function ReadString(f: Text): string;
/// Возвращает значение типа boolean, введенное из текстового файла f
function ReadBoolean(f: Text): boolean;
/// Возвращает следующую лексему из текстового файла f
function ReadLexem(f: Text): string;
/// Возвращает значение типа integer, введенное из текстового файла f,
///и осуществляет переход на следующую строку
function ReadlnInteger(f: Text): integer;
/// Возвращает значение типа int64, введенное из текстового файла f,
///и осуществляет переход на следующую строку
function ReadlnInt64(f: Text): int64;
/// Возвращает значение типа real, введенное из текстового файла f,
///и осуществляет переход на следующую строку
function ReadlnReal(f: Text): real;
/// Возвращает значение типа char, введенное из текстового файла f,
///и осуществляет переход на следующую строку
function ReadlnChar(f: Text): char;
/// Возвращает значение типа string, введенное из текстового файла f,
///и осуществляет переход на следующую строку
function ReadlnString(f: Text): string;
/// Возвращает значение типа boolean, введенное из текстового файла f,
///и осуществляет переход на следующую строку
function ReadlnBoolean(f: Text): boolean;
// -----------------------------------------------------
//>> Подпрограммы вывода # Write subroutines
// -----------------------------------------------------
///- procedure Write(a,b,...);
/// Выводит значения a,b,... на экран
procedure Write;
///--
procedure Write(obj: object);
///--
procedure Write(obj1, obj2: object);
///--
procedure Write(params args: array of object);
///- procedure Writeln(a,b,...);
/// Выводит значения a,b,... на экран и осуществляет переход на новую строку
///!!- Writeln(a,b,...)
/// Writes a,b,... to standart output stream and appends newline
procedure Writeln;
///--
procedure Writeln(obj: object);
///--
//procedure writeln(ptr: pointer);
///--
procedure Writeln(obj1, obj2: object);
///--
procedure Writeln(params args: array of object);
///- procedure Write(f: файл; a,b,...);
/// Выводит значения a,b,... в файл f
procedure Write(f: Text);
///--
procedure Write(f: Text; val: object);
///--
procedure Write(f: Text; params args: array of object);
///- procedure Writeln(f: Text; a,b,...);
/// Выводит значения a,b,... в текстовый файл f и осуществляет переход на новую строку
procedure Writeln(f: Text);
///--
procedure Writeln(f: Text; val: object);
///--
procedure Writeln(f: Text; params args: array of object);
/// Выводит значения args согласно форматной строке formatstr
procedure WriteFormat(formatstr: string; params args: array of object);
/// Выводит значения args согласно форматной строке formatstr и осуществляет переход на новую строку
procedure WritelnFormat(formatstr: string; params args: array of object);
/// Выводит значения args в текстовый файл f согласно форматной строке formatstr
procedure WriteFormat(f: Text; formatstr: string; params args: array of object);
/// Выводит значения args в текстовый файл f согласно форматной строке formatstr
///и осуществляет переход на новую строку
procedure WritelnFormat(f: Text; formatstr: string; params args: array of object);
///- procedure Print(a,b,...);
/// Выводит значения a,b,... на экран, после каждого значения выводит пробел
procedure Print(o: object);
///--
procedure Print(s: string);
///--
procedure Print(params args: array of object);
///- procedure Print(f: Text; a,b,...);
/// Выводит значения a,b,... в текстовый файл f, после каждого значения выводит пробел
procedure Print(f: Text; params args: array of object);
///- procedure Println(a,b,...);
/// Выводит значения a,b,... на экран, после каждого значения выводит пробел и переходит на новую строку
procedure Println(params args: array of object);
///- procedure Println(f: Text; a,b,...);
/// Выводит значения a,b,... в текстовый файл f, после каждого значения выводит пробел и переходит на новую строку
procedure Println(f: Text; params args: array of object);
// -----------------------------------------------------
//>> Общие подпрограммы для работы с файлами # Common subroutines for files
// -----------------------------------------------------
///- procedure Assign(f: файл; name: string);
/// Связывает файловую переменную с файлом на диске
procedure Assign(f: AbstractBinaryFile; name: string);
///- procedure AssignFile(f: файл; name: string);
/// Связывает файловую переменную с файлом на диске
procedure AssignFile(f: AbstractBinaryFile; name: string);
///- procedure Close(f: файл);
/// Закрывает файл
procedure Close(f: AbstractBinaryFile);
///- procedure CloseFile(f: файл);
/// Закрывает файл
procedure CloseFile(f: AbstractBinaryFile);
///- function Eof(f: файл): boolean;
/// Возвращает True, если достигнут конец файла
function Eof(f: AbstractBinaryFile): boolean;
///- procedure Erase(f: файл);
/// Удаляет файл, связанный с файловой переменной
procedure Erase(f: AbstractBinaryFile);
///- procedure Rename(f: файл; newname: string);
/// Переименовывает файл, связаный с файловой переменной, давая ему имя newname.
procedure Rename(f: AbstractBinaryFile; newname: string);
// -----------------------------------------------------
//>> Подпрограммы для работы с текстовыми файлами # Subroutines for text files
// -----------------------------------------------------
///--
procedure Assign(f: Text; name: string);
///--
procedure AssignFile(f: Text; name: string);
///--
procedure Close(f: Text);
///--
procedure CloseFile(f: Text);
/// Открывает текстовый файл на чтение в кодировке Windows
procedure Reset(f: Text);
/// Открывает текстовый файл на чтение в указанной кодировке
procedure Reset(f: Text; en: Encoding);
/// Связывает файловую переменную f с именем файла name и открывает текстовый файл на чтение в кодировке Windows
procedure Reset(f: Text; name: string);
/// Связывает файловую переменную f с именем файла name и открывает текстовый файл на чтение в указанной кодировке
procedure Reset(f: Text; name: string; en: Encoding);
/// Открывает текстовый файл на запись в кодировке Windows.
///Если файл существовал - он обнуляется, если нет - создается пустой
procedure Rewrite(f: Text);
/// Открывает текстовый файл на запись в указанной кодировке.
///Если файл существовал - он обнуляется, если нет - создается пустой
procedure Rewrite(f: Text; en: Encoding);
/// Связывает файловую переменную с именем файла name и открывает текстовый файл f на запись в кодировке Windows.
///Если файл существовал - он обнуляется, если нет - создается пустой
procedure Rewrite(f: Text; name: string);
/// Связывает файловую переменную f с именем файла name и открывает текстовый файл f на запись в указанной кодировке.
///Если файл существовал - он обнуляется, если нет - создается пустой
procedure Rewrite(f: Text; name: string; en: Encoding);
/// Открывает текстовый файл на дополнение в кодировке Windows
procedure Append(f: Text);
/// Открывает текстовый файл на дополнение в указанной кодировке
procedure Append(f: Text; en: Encoding);
/// Связывает файловую переменную f с именем файла name и открывает текстовый файл на дополнение в кодировке Windows
procedure Append(f: Text; name: string);
/// Связывает файловую переменную f с именем файла name и открывает текстовый файл на дополнение в указанной кодировке
procedure Append(f: Text; name: string; en: Encoding);
/// Возвращает текстовый файл с именем fname, открытый на чтение в кодировке Windows
function OpenRead(fname: string): Text;
/// Возвращает текстовый файл с именем fname, открытый на чтение в указанной кодировке
function OpenRead(fname: string; en: Encoding): Text;
/// Возвращает текстовый файл с именем fname, открытый на запись в кодировке Windows
function OpenWrite(fname: string): Text;
/// Возвращает текстовый файл с именем fname, открытый на запись в указанной кодировке
function OpenWrite(fname: string; en: Encoding): Text;
/// Возвращает текстовый файл с именем fname, открытый на дополнение в кодировке Windows
function OpenAppend(fname: string): Text;
/// Возвращает текстовый файл с именем fname, открытый на дополнение в указанной кодировке
function OpenAppend(fname: string; en: Encoding): Text;
///--
function Eof(f: Text): boolean;
/// Возвращает True, если в файле достигнут конец строки
function Eoln(f: Text): boolean;
/// Пропускает пробельные символы, после чего возвращает True, если достигнут конец файла
function SeekEof(f: Text): boolean;
/// Пропускает пробельные символы, после чего возвращает True, если в файле достигнут конец строки
function SeekEoln(f: Text): boolean;
/// Записывает содержимое буфера файла на диск
procedure Flush(f: Text);
///--
procedure Erase(f: Text);
///--
procedure Rename(f: Text; newname: string);
///--
procedure TextFileInit(var f: Text);
/// Открывает файл, считывает из него строки в кодировке Windows и закрывает файл. В каждый момент в памяти хранится только текущая строка
function ReadLines(path: string): sequence of string;
/// Открывает файл, считывает из него строки в указаной кодировке и закрывает файл. В каждый момент в памяти хранится только текущая строка
function ReadLines(path: string; en: Encoding): sequence of string;
/// Открывает файл, считывает из него строки в кодировке Windows в виде массива строк, после чего закрывает файл
function ReadAllLines(path: string): array of string;
/// Открывает файл, считывает из него строки в указаной кодировке в виде массива строк, после чего закрывает файл
function ReadAllLines(path: string; en: Encoding): array of string;
/// Открывает файл, считывает его содержимое в кодировке Windows в виде строки, после чего закрывает файл
function ReadAllText(path: string): string;
/// Открывает файл, считывает его содержимое в указаной кодировке в виде строки, после чего закрывает файл
function ReadAllText(path: string; en: Encoding): string;
/// Создает новый файл, записывает в него строки из последовательности в кодировке Windows, после чего закрывает файл
procedure WriteLines(path: string; ss: sequence of string);
/// Создает новый файл, записывает в него строки из последовательности в указанной кодировке, после чего закрывает файл
procedure WriteLines(path: string; ss: sequence of string; en: Encoding);
/// Создает новый файл, записывает в него строки из массива в кодировке Windows, после чего закрывает файл
procedure WriteAllLines(path: string; ss: array of string);
/// Создает новый файл, записывает в него строки из массива в указанной кодировке, после чего закрывает файл
procedure WriteAllLines(path: string; ss: array of string; en: Encoding);
/// Создает новый файл, записывает в него строку в кодировке Windows, после чего закрывает файл
procedure WriteAllText(path: string; s: string);
/// Создает новый файл, записывает в него строку в указанной кодировке, после чего закрывает файл
procedure WriteAllText(path: string; s: string; en: Encoding);
// -----------------------------------------------------
//>> Подпрограммы для работы с двоичными файлами # Subroutines for binary files
// -----------------------------------------------------
///- procedure Reset(f: двоичный файл);
/// Открывает двоичный файл на чтение и запись.
///Двоичный файл - это либо типизированный файл file of T, либо бестиповой файл file
procedure Reset(f: AbstractBinaryFile);
///- procedure Reset(f: двоичный файл; name: string);
/// Связывает файловую переменную f с файлом name на диске и открывает двоичный файл на чтение и запись.
///Двоичный файл - это либо типизированный файл file of T, либо бестиповой файл file
procedure Reset(f: AbstractBinaryFile; name: string);
///- procedure Rewrite(f: двоичный файл);
/// Открывает двоичный файл на чтение и запись, при этом обнуляя его содержимое. Если файл существовал, он обнуляется.
///Двоичный файл - это либо типизированный файл file of T, либо бестиповой файл file
procedure Rewrite(f: AbstractBinaryFile);
///- procedure Rewrite(f: двоичный файл; name: string);
/// Связывает файловую переменную f с файлом name на диске и открывает двоичный файл на чтение и запись, при этом обнуляя его содержимое.
///Двоичный файл - это либо типизированный файл file of T, либо бестиповой файл file
procedure Rewrite(f: AbstractBinaryFile; name: string);
///- procedure Reset(f: двоичный файл; en: Encoding);
/// Открывает двоичный файл на чтение и запись в заданной кодировке.
///Двоичный файл - это либо типизированный файл file of T, либо бестиповой файл file
procedure Reset(f: AbstractBinaryFile; en: Encoding);
///- procedure Reset(f: двоичный файл; name: string; en: Encoding);
/// Связывает файловую переменную f с файлом name на диске и открывает двоичный файл на чтение и запись в заданной кодировке.
///Двоичный файл - это либо типизированный файл file of T, либо бестиповой файл file
procedure Reset(f: AbstractBinaryFile; name: string; en: Encoding);
///- procedure Rewrite(f: двоичный файл; en: Encoding);
/// Открывает двоичный файл на чтение и запись в заданной кодировке, при этом обнуляя его содержимое. Если файл существовал, он обнуляется.
///Двоичный файл - это либо типизированный файл file of T, либо бестиповой файл file
procedure Rewrite(f: AbstractBinaryFile; en: Encoding);
///- procedure Rewrite(f: двоичный файл; name: string; en: Encoding);
/// Связывает файловую переменную f с файлом name на диске и открывает двоичный файл на чтение и запись в заданной кодировке, при этом обнуляя его содержимое.
///Двоичный файл - это либо типизированный файл file of T, либо бестиповой файл file
procedure Rewrite(f: AbstractBinaryFile; name: string; en: Encoding);
///- procedure Truncate(f: двоичный файл);
/// Усекает двоичный файл, отбрасывая все элементы с позиции файлового указателя.
///Двоичный файл - это либо типизированный файл file of T, либо бестиповой файл file
procedure Truncate(f: AbstractBinaryFile);
///--
procedure Write(f: AbstractBinaryFile; params vals: array of object);
///--
procedure Writeln(f: AbstractBinaryFile);
///--
procedure Writeln(f: AbstractBinaryFile; val: object);
///--
procedure Writeln(f: AbstractBinaryFile; params vals: array of object);
///- function FilePos(f: двоичный файл): int64;
/// Возвращает текущую позицию файлового указателя в двоичном файле
function FilePos(f: TypedFile): int64;
///- function FileSize(f: двоичный файл): int64;
/// Возвращает количество элементов в двоичном файле
function FileSize(f: TypedFile): int64;
///- procedure Seek(f: двоичный файл; n: int64);
/// Устанавливает текущую позицию файлового указателя в двоичном файле на элемент с данным номером
procedure Seek(f: TypedFile; n: int64);
///--
procedure TypedFileInit(var f: TypedFile; ElementType: System.Type);
///--
procedure TypedFileInit(var f: TypedFile; ElementType: System.Type; off: integer; params offs: array of integer);
///--
procedure TypedFileInitWithShortString(var f: TypedFile; ElementType: System.Type; off: integer; params offs: array of integer);
///--
function TypedFileRead(f: TypedFile): object;
///--
function FilePos(f: BinaryFile): int64;
///--
function FileSize(f: BinaryFile): int64;
///--
procedure Seek(f: BinaryFile; n: int64);
///--
procedure BinaryFileInit(var f: BinaryFile);
///--
function BinaryFileRead(var f: BinaryFile; ElementType: System.Type): object;
// -----------------------------------------------------
//>> Cистемные подпрограммы # System subroutines
// -----------------------------------------------------
/// Возвращает версию PascalABC.NET
function PascalABCVersion: string;
/// Возвращает количество параметров командной строки
function ParamCount: integer;
/// Возвращает i-тый параметр командной строки
function ParamStr(i: integer): string;
/// Возвращает текущий каталог
function GetDir: string;
/// Меняет текущий каталог
procedure ChDir(s: string);
/// Создает каталог
procedure MkDir(s: string);
/// Удаляет каталог
procedure RmDir(s: string);
/// Создает каталог. Возвращает True, если каталог успешно создан
function CreateDir(s: string): boolean;
/// Удаляет файл. Если файл не может быть удален, то возвращает False
function DeleteFile(s: string): boolean;
/// Возвращает текущий каталог
function GetCurrentDir: string;
/// Удаляет каталог. Возвращает True, если каталог успешно удален
function RemoveDir(s: string): boolean;
/// Переименовывает файл name, давая ему новое имя newname. Возвращает True, если файл успешно переименован
function RenameFile(name, newname: string): boolean;
/// Устанавливает текущий каталог. Возвращает True, если каталог успешно удален
function SetCurrentDir(s: string): boolean;
/// Изменяет расширение файла с именем name на newext
function ChangeFileNameExtension(name, newext: string): string;
/// Возвращает True, если файл с именем name существует
function FileExists(name: string): boolean;
///- procedure Assert(cond: boolean);
/// Выводит в специальном окне стек вызовов подпрограмм если условие не выполняется
procedure Assert(cond: boolean; sourceFile: string := ''; line: integer := 0);
///- procedure Assert(cond: boolean; message: string);
/// Выводит в специальном окне диагностическое сообщение и стек вызовов подпрограмм если условие не выполняется
procedure Assert(cond: boolean; message: string; sourceFile: string := ''; line: integer := 0);
/// Возвращает свободное место в байтах на диске с именем diskname
function DiskFree(diskname: string): int64;
/// Возвращает размер в байтах на диске с именем diskname
function DiskSize(diskname: string): int64;
/// Возвращает свободное место в байтах на диске disk. disk=0 - текущий диск, disk=1 - диск A: , disk=2 - диск B: и т.д.
function DiskFree(disk: integer): int64;
/// Возвращает размер в байтах на диске disk. disk=0 - текущий диск, disk=1 - диск A: , disk=2 - диск B: и т.д.
function DiskSize(disk: integer): int64;
/// Возвращает количество миллисекунд с момента начала работы программы
function Milliseconds: integer;
/// Возвращает количество миллисекунд с момента последнего вызова Milliseconds или MillisecondsDelta
function MillisecondsDelta: integer;
/// Завершает работу программы
procedure Halt;
/// Завершает работу программы, возвращая код ошибки exitCode
procedure Halt(exitCode: integer);
/// Делает паузу на ms миллисекунд
procedure Sleep(ms: integer);
/// Возващает имя запущенного .exe-файла
function GetEXEFileName: string;
/// Преобразует указатель к строковому представлению
function PointerToString(p: pointer): string;
/// Запускает программу или документ с именем filename
procedure Exec(filename: string);
/// Запускает программу или документ с именем filename и параметрами командной строки args
procedure Exec(filename: string; args: string);
/// Запускает программу или документ с именем filename
procedure Execute(filename: string);
/// Запускает программу или документ с именем filename и параметрами командной строки args
procedure Execute(filename: string; args: string);
/// Возвращает последовательность имен файлов по заданному пути, соответствующих шаблону поиска
function EnumerateFiles(path: string; searchPattern: string := '*.*'): sequence of string;
/// Возвращает последовательность имен файлов по заданному пути, соответствующих шаблону поиска, включая подкаталоги
function EnumerateAllFiles(path: string; searchPattern: string := '*.*'): sequence of string;
/// Возвращает последовательность имен каталогов по заданному пути
function EnumerateDirectories(path: string): sequence of string;
/// Возвращает последовательность имен каталогов по заданному пути, включая подкаталоги
function EnumerateAllDirectories(path: string): sequence of string;
///-procedure New<T>(var p: ^T);
/// Выделяет динамическую память размера sizeof(T) и возвращает в переменной p указатель на нее. Тип T должен быть размерным
//procedure New<T>(var p: ^T);
///-procedure Dispose<T>(var p: ^T);
/// Освобождает динамическую память, на которую указывает p
//procedure Dispose<T>(var p: ^T);
// -----------------------------------------------------
//>> Подпрограммы для работы с именами файлов # Functions for file names
// -----------------------------------------------------
/// Выделяет имя файла из полного имени файла fname
function ExtractFileName(fname: string): string;
/// Выделяет расширение из полного имени файла fname
function ExtractFileExt(fname: string): string;
/// Выделяет путь из полного имени файла fname
function ExtractFilePath(fname: string): string;
/// Выделяет имя диска и путь из полного имени файла fname
function ExtractFileDir(fname: string): string;
/// Выделяет путь из полного имени файла fname
function ExtractFileDrive(fname: string): string;
/// Возвращает полное имя файла fname
function ExpandFileName(fname: string): string;
// -----------------------------------------------------
//>> Математические подпрограммы # Math subroutines
// -----------------------------------------------------
///-function Sign(x: число): integer;
/// Возвращает -1, 0 или +1 в зависимости от знака числа x
function Sign(x: shortint): integer;
///--
function Sign(x: smallint): integer;
///--
function Sign(x: integer): integer;
///--
function Sign(x: int64): integer;
///--
function Sign(x: byte): integer;
///--
function Sign(x: word): integer;
///--
function Sign(x: longword): integer;
///--
function Sign(x: uint64): integer;
///--
function Sign(x: real): integer;
///--
function Sign(x: BigInteger): integer;
///-function Abs(x: число): число;
/// Возвращает модуль числа x
function Abs(x: shortint): shortint;
///--
function Abs(x: smallint): smallint;
///--
function Abs(x: integer): integer;
///--
function Abs(x: int64): int64;
///--
function Abs(x: byte): byte;
///--
function Abs(x: word): word;
///--
function Abs(x: longword): longword;
///--
function Abs(x: uint64): uint64;
///--
function Abs(x: BigInteger): BigInteger;
///--
function Abs(x: real): real;
///--
function Abs(x: single): single;
/// Возвращает синус угла x, измеряемого в радианах
function Sin(x: real): real;
/// Возвращает гиперболический синус угла x, измеряемого в радианах
function Sinh(x: real): real;
/// Возвращает косинус угла x, измеряемого в радианах
/// !! Returns the cosine of number x
function Cos(x: real): real;
/// Возвращает гиперболический косинус угла x, измеряемого в радианах
function Cosh(x: real): real;
/// Возвращает тангенс угла x, измеряемого в радианах
function Tan(x: real): real;
/// Возвращает гиперболический тангенс угла x, измеряемого в радианах
function Tanh(x: real): real;
/// Возвращает угол в радианах, синус которого равен x, -1<=x<=1
function ArcSin(x: real): real;
/// Возвращает угол в радианах, косинус которого равен x, -1<=x<=1
function ArcCos(x: real): real;
/// Возвращает угол в радианах, тангенс которого равен x
function ArcTan(x: real): real;
/// Возвращает экспоненту числа x
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
function Log10(x: real): real;
/// Возвращает логарифм числа x по основанию base
function LogN(base, x: real): real;
/// Возвращает квадратный корень числа x
function Sqrt(x: real): real;
///-function Sqr(x: число): число;
/// Возвращает квадрат числа x
function Sqr(x: shortint): integer;
///--
function Sqr(x: smallint): integer;
///--
function Sqr(x: integer): int64;
///--
function Sqr(x: int64): int64;
///--
function Sqr(x: byte): integer;
///--
function Sqr(x: word): uint64;
///--
function Sqr(x: longword): uint64;
///--
function Sqr(x: uint64): uint64;
///--
function Sqr(x: BigInteger): BigInteger;
///--
function Sqr(x: real): real;
/// Возвращает x в степени y
function Power(x, y: real): 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
function Trunc(x: real): integer;
/// Возвращает целую часть вещественного числа x как длинное целое
function TruncBigInteger(x: real): BigInteger;
/// Возвращает целую часть числа x
function Int(x: real): real;
/// Возвращает дробную часть числа x
function Frac(x: real): real;
/// Возвращает наибольшее целое <= x
function Floor(x: real): integer;
/// Возвращает наименьшее целое >= x
function Ceil(x: real): integer;
/// Переводит радианы в градусы
function RadToDeg(x: real): real;
/// Переводит градусы в радианы
function DegToRad(x: real): real;
/// Инициализирует датчик псевдослучайных чисел
procedure Randomize;
/// Инициализирует датчик псевдослучайных чисел, используя значение seed. При одном и том же seed генерируются одинаковые псевдослучайные последовательности
procedure Randomize(seed: integer);
/// Возвращает случайное целое в диапазоне от 0 до maxValue-1
function Random(maxValue: integer): integer;
/// Возвращает случайное вещественное в диапазоне [0,maxValue)
function Random(maxValue: real): real;
/// Возвращает случайное целое в диапазоне от a до b
function Random(a, b: integer): integer;
/// Возвращает случайное вещественное в диапазоне [a,b)
function Random(a, b: real): real;
/// Возвращает случайное вещественное в диапазоне [0..1)
function Random: real;
/// Возвращает кортеж из двух случайных целых в диапазоне от 0 до maxValue-1
function Random2(maxValue: integer): (integer, integer);
/// Возвращает кортеж из двух случайных вещественных в диапазоне [0,maxValue)
function Random2(maxValue: real): (real, real);
/// Возвращает кортеж из двух случайных целых в диапазоне от a до b
function Random2(a, b: integer): (integer, integer);
/// Возвращает кортеж из двух случайных вещественных в диапазоне [a,b)
function Random2(a, b: real): (real, real);
/// Возвращает кортеж из двух случайных вещественных в диапазоне [0..1)
function Random2: (real, real);
/// Возвращает кортеж из трех случайных целых в диапазоне от 0 до maxValue-1
function Random3(maxValue: integer): (integer, integer, integer);
/// Возвращает кортеж из трех случайных вещественных в диапазоне [0,maxValue)
function Random3(maxValue: real): (real, real, real);
/// Возвращает кортеж из трех случайных целых в диапазоне от a до b
function Random3(a, b: integer): (integer, integer, integer);
/// Возвращает кортеж из трех случайных вещественных в диапазоне [a,b)
function Random3(a, b: real): (real, real, real);
/// Возвращает кортеж из трех случайных вещественных в диапазоне [0..1)
function Random3: (real, real, real);
///-function Max(a: число, b: число): число;
/// Возвращает максимальное из чисел a,b
function Max(a, b: byte): byte;
///--
function Max(a, b: shortint): shortint;
///--
function Max(a, b: smallint): smallint;
///--
function Max(a, b: word): word;
///--
function Max(a, b: integer): integer;
///--
function Max(a, b: BigInteger): BigInteger;
///--
function Max(a, b: longword): longword;
///--
function Max(a, b: int64): int64;
///--
function Max(a, b: uint64): uint64;
///--
function Max(a, b: real): real;
///-function Min(a: число, b: число): число;
/// Возвращает минимальное из чисел a,b
function Min(a, b: byte): byte;
///--
function Min(a, b: shortint): shortint;
///--
function Min(a, b: word): word;
///--
function Min(a, b: smallint): smallint;
///--
function Min(a, b: integer): integer;
///--
function Min(a, b: BigInteger): BigInteger;
///--
function Min(a, b: longword): longword;
///--
function Min(a, b: int64): int64;
///--
function Min(a, b: uint64): uint64;
///--
function Min(a, b: real): real;
///-function Min(a,b,...: число): число;
/// Возвращает минимальное из чисел a,b,...
function Min(params a: array of integer): integer;
///--
function Min(params a: array of real): real;
///--
function Min(a, b, c: real): real;
///--
function Min(a, b, c, d: real): real;
///-function Max(a,b,...: число): число;
/// Возвращает ммксиимальное из чисел a,b,...
function Max(params a: array of integer): integer;
///--
function Max(params a: array of real): real;
///--
function Max(a, b, c: real): real;
///--
function Max(a, b, c, d: real): real;
///-function Odd(i: целое): boolean;
/// Возвращает True, если i нечетно, и False в противном случае
function Odd(i: byte): boolean;
///--
function Odd(i: shortint): boolean;
///--
function Odd(i: word): boolean;
///--
function Odd(i: smallint): boolean;
///--
function Odd(i: integer): boolean;
///--
function Odd(i: BigInteger): boolean;
///--
function Odd(i: longword): boolean;
///--
function Odd(i: int64): boolean;
///--
function Odd(i: uint64): boolean;
// -----------------------------------------------------
//>> Подпрограммы для работы с комплексными числами # Functions for Complex numbers
// -----------------------------------------------------
/// Конструирует комплексное число с вещественной частью re и мнимой частью im
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
// -----------------------------------------------------
///- procedure Include(var s: set of T; element: T);
///Добавляет элемент element во множество s
procedure Include(var s: TypedSet; el: object);
///- procedure Exclude(var s: set of T; element: T);
///Удаляет элемент element из множества s
procedure Exclude(var s: TypedSet; el: object);
// -----------------------------------------------------
//>> Подпрограммы для работы с символами # Subroutines for char
// -----------------------------------------------------
/// Увеличивает код символа c на 1
procedure Inc(var c: char);
/// Увеличивает код символа c на n
procedure Inc(var c: char; n: integer);
/// Уменьшает код символа c на 1
procedure Dec(var c: char);
/// Уменьшает код символа c на n
procedure Dec(var c: char; n: integer);
/// Возвращает предшествующий x символ
function Pred(x: char): char;
// Возвращает символ, отстоящий от x на n позиций назад
//function Pred(x: char; n: integer): char;
/// Возвращает следующий за x символ
function Succ(x: char): char;
// Возвращает символ, отстоящий от x на n позиций вперёд
//function Succ(x: char; n: integer): char;
/// Преобразует код в символ в кодировке Windows
function ChrAnsi(a: byte): char;
/// Преобразует символ в код в кодировке Windows
function OrdAnsi(a: char): byte;
/// Преобразует код в символ в кодировке Unicode
function Chr(a: word): char;
/// Преобразует символ в код в кодировке Unicode
function Ord(a: char): word;
/// Преобразует код в символ в кодировке Unicode
function ChrUnicode(a: word): char;
/// Преобразует символ в код в кодировке Unicode
function OrdUnicode(a: char): word;
/// Преобразует символ в верхний регистр
function UpperCase(ch: char): char;
/// Преобразует символ в нижний регистр
function LowerCase(ch: char): char;
/// Преобразует символ в верхний регистр
function UpCase(ch: char): char;
/// Преобразует символ в нижний регистр
function LowCase(ch: char): char;
// -----------------------------------------------------
//>> Подпрограммы для работы со строками # Subroutines for string
// -----------------------------------------------------
///-procedure Str(i: целое; var s: string);
/// Преобразует целое значение i к строковому представлению и записывает результат в s
procedure Str(i: integer; var s: string);
///--
procedure Str(i: longword; var s: string);
///--
procedure Str(i: int64; var s: string);
///--
procedure Str(i: uint64; var s: string);
/// Преобразует вещественное значение r к строковому представлению и записывает результат в s
procedure Str(r: real; var s: string);
/// Преобразует вещественное значение r к строковому представлению и записывает результат в s
procedure Str(r: single; var s: string);
///--
procedure Str(s1: string; var s: string);
/// Возвращает позицию подстроки subs в строке s. Если не найдена, возвращает 0
function Pos(subs, s: string; from: integer := 1): integer;
/// Возвращает позицию подстроки subs в строке s начиная с позиции from. Если не найдена, возвращает 0
function PosEx(subs, s: string; from: integer := 1): integer;
/// Возвращает позицию последнего вхождения подстроки subs в строке s. Если не найдена, возвращает 0
function LastPos(subs, s: string): integer;
/// Возвращает позицию последнего вхождения подстроки subs в строке s начиная с позиции from. Если не найдена, возвращает 0
function LastPos(subs, s: string; from: integer): integer;
/// Возвращает длину строки
function Length(s: string): integer;
/// Устанавливает длину строки s равной n
procedure SetLength(var s: string; n: integer);
///--
procedure SetLengthForShortString(var s: string; n, sz: integer);
/// Вставляет подстроку source в строку s с позиции index
procedure Insert(source: string; var s: string; index: integer);
///--
procedure InsertInShortString(source: string; var s: string; index, n: integer);
/// Удаляет из строки s count символов с позиции index
procedure Delete(var s: string; index, count: integer);
/// Возвращает подстроку строки s длины count с позиции index
function Copy(s: string; index, count: integer): string;
///-function Concat(s1,s2,...): string;
/// Возвращает строку, являющуюся результатом слияния строк s1,s2,...
function Concat(params strs: array of string): string;
/// Возвращает строку, являющуюся результатом слияния строк s1 и s2
function Concat(s1, s2: string): string;
/// Возвращает строку в нижнем регистре
function LowerCase(s: string): string;
/// Возвращает строку в верхнем регистре
function UpperCase(s: string): string;
/// Возвращает строку, состоящую из count символов ch
function StringOfChar(ch: char; count: integer): string;
/// Возвращает инвертированную строку
function ReverseString(s: string): string;
/// Возвращает инвертированную строку в диапазоне длины length начиная с индекса index
function ReverseString(s: string; index,length: integer): string;
/// Сравнивает строки. Возвращает значение < 0 если s1<s2, > 0 если s1>s2 и = 0 если s1=s2
function CompareStr(s1, s2: string): integer;
/// Возвращает первые count символов строки s
function LeftStr(s: string; count: integer): string;
/// Возвращает последние count символов строки s
function RightStr(s: string; count: integer): string;
/// Возвращает строку с удаленными начальными и конечными пробелами
function Trim(s: string): string;
/// Возвращает строку с удаленными начальными пробелами
function TrimLeft(s: string): string;
/// Возвращает строку с удаленными конечными пробелами
function TrimRight(s: string): string;
/// Преобразует строковое представление целого числа к числовому значению
function StrToInt(s: string): integer;
/// Преобразует строковое представление целого числа к числовому значению
function StrToInt64(s: string): int64;
/// Преобразует строковое представление вещественного числа к числовому значению
function StrToFloat(s: string): real;
/// Преобразует строковое представление вещественного числа к числовому значению
function StrToReal(s: string): real;
/// Преобразует строковое представление s целого числа к числовому значению и записывает его в value.
///При невозможности преобразования возвращается False
function TryStrToInt(s: string; var value: integer): boolean;
/// Преобразует строковое представление s целого числа к числовому значению и записывает его в value.
///При невозможности преобразования возвращается False
function TryStrToInt64(s: string; var value: int64): boolean;
/// Преобразует строковое представление s вещественного числа к числовому значению и записывает его в value.
///При невозможности преобразования возвращается False
function TryStrToFloat(s: string; var value: real): boolean;
/// Преобразует строковое представление s вещественного числа к числовому значению и записывает его в value.
///При невозможности преобразования возвращается False
function TryStrToFloat(s: string; var value: single): boolean;
/// Преобразует строковое представление s вещественного числа к числовому значению и записывает его в value.
///При невозможности преобразования возвращается False
function TryStrToReal(s: string; var value: real): boolean;
/// Преобразует строковое представление s вещественного числа к числовому значению и записывает его в value.
///При невозможности преобразования возвращается False
function TryStrToSingle(s: string; var value: single): boolean;
/// Считывает целое из строки начиная с позиции from и устанавливает from за считанным значением
function ReadIntegerFromString(s: string; var from: integer): integer;
/// Считывает вещественное из строки начиная с позиции from и устанавливает from за считанным значением
function ReadRealFromString(s: string; var from: integer): real;
/// Считывает из строки последовательность символов до пробельного символа начиная с позиции from и устанавливает from за считанным значением
function ReadWordFromString(s: string; var from: integer): string;
/// Возвращает True если достигнут конец строки или в строке остались только пробельные символы и False в противном случае
function StringIsEmpty(s: string; var from: integer): boolean;
/// Считывает целое из строки начиная с позиции from и устанавливает from за считанным значением.
///Возвращает True если считывание удачно и False в противном случае
function TryReadIntegerFromString(s: string; var from: integer; var res: integer): boolean;
/// Считывает вещественное из строки начиная с позиции from и устанавливает from за считанным значением.
///Возвращает True если считывание удачно и False в противном случае
function TryReadRealFromString(s: string; var from: integer; var res: real): boolean;
///-procedure Val(s: string; var value: число; var err: integer);
/// Преобразует строковое представление s целого числа к числовому значению и записывает его в переменную value.
///Если преобразование успешно, то err=0, иначе err>0
procedure Val(s: string; var value: integer; var err: integer);
///--
procedure Val(s: string; var value: shortint; var err: integer);
///--
procedure Val(s: string; var value: smallint; var err: integer);
///--
procedure Val(s: string; var value: int64; var err: integer);
///--
procedure Val(s: string; var value: byte; var err: integer);
///--
procedure Val(s: string; var value: word; var err: integer);
///--
procedure Val(s: string; var value: longword; var err: integer);
///--
procedure Val(s: string; var value: uint64; var err: integer);
///--
procedure Val(s: string; var value: real; var err: integer);
///--
procedure Val(s: string; var value: single; var err: integer);
/// Преобразует целое число к строковому представлению
function IntToStr(a: integer): string;
/// Преобразует целое число к строковому представлению
function IntToStr(a: int64): string;
/// Преобразует вещественное число к строковому представлению
function FloatToStr(a: real): string;
/// Возвращает отформатированную строку, построенную по форматной строке и списку форматируемых параметров
function Format(formatstring: string; params pars: array of object): string;
// -----------------------------------------------------
//>> Общие подпрограммы # Common subroutines
// -----------------------------------------------------
/// Увеличивает значение переменной i на 1
procedure Inc(var i: integer);
/// Увеличивает значение переменной i на n
procedure Inc(var i: integer; n: integer);
/// Уменьшает значение переменной i на 1
procedure Dec(var i: integer);
/// Уменьшает значение переменной i на n
procedure Dec(var i: integer; n: integer);
///-procedure Inc(var e: перечислимый тип);
/// Увеличивает значение перечислимого типа на 1
procedure Inc(var b: byte);
///-procedure Inc(var e: перечислимый тип; n: integer);
/// Увеличивает значение перечислимого типа на n
procedure Inc(var b: byte; n: integer);
///-procedure Dec(var e: перечислимый тип);
/// Уменьшает значение перечислимого типа на 1
procedure Dec(var b: byte);
///-procedure Dec(var e: перечислимый тип; n: integer);
/// Уменьшает значение перечислимого типа на n
procedure Dec(var b: byte; n: integer);
///--
procedure Inc(var f: boolean);
///--
procedure Dec(var f: boolean);
///-function Ord(a: целое): целое;
/// Возвращает порядковый номер значения a
function Ord(a: integer): integer;
///-function Ord(a: перечислимый тип): integer;
/// Возвращает порядковый номер значения a
function Ord(a: longword): longword;
///--
function Ord(a: int64): int64;
///--
function Ord(a: uint64): uint64;
///--
function Ord(a: boolean): integer;
///-function Succ(x: целое): целое;
/// Возвращает следующее за x значение
function Succ(x: integer): integer;
///-function Succ(x: перечислимый тип): перечислимый тип;
/// Возвращает следующее за x значение
function Succ(x: byte): byte;
///--
function Succ(x: shortint): shortint;
///--
function Succ(x: smallint): smallint;
///--
function Succ(x: word): word;
///--
function Succ(x: longword): longword;
///--
function Succ(x: int64): int64;
///--
function Succ(x: uint64): uint64;
///--
function Succ(x: boolean): boolean;
///-function Pred(x: целое): целое;
/// Возвращает предшествующее x значение
function Pred(x: integer): integer;
///-function Pred(x: перечислимый тип): перечислимый тип;
/// Возвращает предшествующее x значение
function Pred(x: byte): byte;
///--
function Pred(x: shortint): shortint;
///--
function Pred(x: smallint): smallint;
///--
function Pred(x: word): word;
///--
function Pred(x: longword): longword;
///--
function Pred(x: int64): int64;
///--
function Pred(x: uint64): uint64;
///--
function Pred(x: boolean): boolean;
/// Меняет местами значения двух переменных
procedure Swap<T>(var a, b: T);
/// Возвращает True, если достигнут конец строки
function Eoln: boolean;
/// Возвращает True, если достигнут конец потока ввода
function Eof: boolean;
// -----------------------------------------------------
//>> Подпрограммы для работы с динамическими массивами # Subroutines for array of T
// -----------------------------------------------------
///- function Low(a: array of T): integer;
/// Возвращает 0
function Low(i: System.Array): integer;
///- function High(a: array of T): integer;
/// Возвращает верхнюю границу динамического массива
function High(i: System.Array): integer;
///- function Length(a: array of T): integer;
/// Возвращает длину динамического массива
function Length(a: System.Array): integer;
///- function Length(a: array of T; dim: integer): integer;
/// Возвращает длину динамического массива по размерности dim
function Length(a: System.Array; dim: integer): integer;
///- procedure SetLength(var a: array of T; n: integer);
/// Устанавливает длину одномерного динамического массива. Старое содержимое сохраняется
//procedure SetLength<T>(var a: array of T; n: integer);
///- procedure SetLength(var a: array [,...,] of T; n1,n2,...: integer);
/// Устанавливает размеры n-мерного динамического массива. Старое содержимое сохраняется
//procedure SetLength<T>(var a: array[,...,] of T; n: integer);
///- function Copy(a: array of T): array of T;
/// Создаёт копию динамического массива
function Copy(a: System.Array): System.Array;
/// Сортирует динамический массив по возрастанию
procedure Sort<T>(a: array of T);
/// Сортирует динамический массив по критерию сортировки, задаваемому функцией сравнения cmp
procedure Sort<T>(a: array of T; cmp: (T,T)->integer);
/// Сортирует динамический массив по критерию сортировки, задаваемому функцией сравнения less
procedure Sort<T>(a: array of T; less: (T,T)->boolean);
/// Сортирует список по возрастанию
procedure Sort<T>(l: List<T>);
/// Сортирует список по критерию сортировки, задаваемому функцией сравнения cmp
procedure Sort<T>(l: List<T>; cmp: (T,T)->integer);
/// Сортирует список по критерию сортировки, задаваемому функцией сравнения less
procedure Sort<T>(l: List<T>; less: (T,T)->boolean);
/// Сортирует динамический массив по убыванию
procedure SortDescending<T>(a: array of T);
/// Сортирует список по убыванию
procedure SortDescending<T>(l: List<T>);
/// Изменяет порядок элементов в динамическом массиве на противоположный
procedure Reverse<T>(a: array of T);
/// Изменяет порядок элементов на противоположный в диапазоне динамического массива длины count, начиная с индекса index
procedure Reverse<T>(a: array of T; index, count: integer);
/// Изменяет порядок элементов в списке на противоположный
procedure Reverse<T>(a: List<T>);
/// Изменяет порядок элементов на противоположный в диапазоне списка длины count, начиная с индекса index
procedure Reverse<T>(a: List<T>; index, count: integer);
/// Изменяет порядок символов в строке на противоположный
procedure Reverse(var s: string);
/// Изменяет порядок символов в части строки длины count на противоположный, начиная с индекса index
procedure Reverse(var s: string; index, count: integer);
/// Перемешивает динамический массив случайным образом
procedure Shuffle<T>(a: array of T);
/// Перемешивает список случайным образом
procedure Shuffle<T>(l: List<T>);
// -----------------------------------------------------
//>> Подпрограммы для генерации последовательностей # Subroutines for sequence generation
// -----------------------------------------------------
/// Возвращает последовательность целых от a до b
function Range(a, b: integer): sequence of integer;
/// Возвращает последовательность символов от c1 до c2
function Range(c1, c2: char): sequence of char;
/// Возвращает последовательность вещественных в точках разбиения отрезка [a,b] на n равных частей
function PartitionPoints(a, b: real; n: integer): sequence of real;
/// Возвращает последовательность целых от a до b с шагом step
function Range(a, b, step: integer): sequence of integer;
/// Возвращает последовательность указанных элементов
function Seq<T>(params a: array of T): sequence of T;
/// Возвращает последовательность из n случайных целых элементов
function SeqRandom(n: integer := 10; a: integer := 0; b: integer := 100): sequence of integer;
/// Возвращает последовательность из n случайных целых элементов
function SeqRandomInteger(n: integer := 10; a: integer := 0; b: integer := 100): sequence of integer;
/// Возвращает последовательность из n случайных вещественных элементов
function SeqRandomReal(n: integer := 10; a: real := 0; b: real := 10): sequence of real;
/// Возвращает последовательность из count элементов, заполненных значениями f(i)
function SeqGen<T>(count: integer; f: integer->T): sequence of T;
/// Возвращает последовательность из count элементов, заполненных значениями f(i), начиная с i=from
function SeqGen<T>(count: integer; f: integer->T; from: integer): sequence of T;
/// Возвращает последовательность из count элементов, начинающуюся с first, с функцией next перехода от предыдущего к следующему
function SeqGen<T>(count: integer; first: T; next: T->T): sequence of T;
/// Возвращает последовательность из count элементов, начинающуюся с first и second,
///с функцией next перехода от двух предыдущих к следующему
function SeqGen<T>(count: integer; first, second: T; next: (T,T) ->T): sequence of T;
/// Возвращает последовательность элементов с начальным значением first,
///функцией next перехода от предыдущего к следующему и условием pred продолжения последовательности
function SeqWhile<T>(first: T; next: T->T; pred: T->boolean): sequence of T;
/// Возвращает последовательность элементов, начинающуюся с first и second,
///с функцией next перехода от двух предыдущих к следующему и условием pred продолжения последовательности
function SeqWhile<T>(first, second: T; next: (T,T) ->T; pred: T->boolean): sequence of T;
/// Возвращает последовательность из count элементов x
function SeqFill<T>(count: integer; x: T): sequence of T;
/// Возвращает последовательность из n целых, введенных с клавиатуры
function ReadSeqInteger(n: integer): sequence of integer;
/// Возвращает последовательность из n вещественных, введенных с клавиатуры
function ReadSeqReal(n: integer): sequence of real;
/// Возвращает последовательность из n строк, введенных с клавиатуры
function ReadSeqString(n: integer): sequence of string;
/// Выводит приглашение к вводу и возвращает последовательность из n целых, введенных с клавиатуры
function ReadSeqInteger(prompt: string; n: integer): sequence of integer;
/// Выводит приглашение к вводу и возвращает последовательность из n вещественных, введенных с клавиатуры
function ReadSeqReal(prompt: string; n: integer): sequence of real;
/// Выводит приглашение к вводу и возвращает последовательность из n строк, введенных с клавиатуры
function ReadSeqString(prompt: string; n: integer): sequence of string;
/// Возвращает последовательность целых, вводимых с клавиатуры пока выполняется определенное условие
function ReadSeqIntegerWhile(cond: integer->boolean): sequence of integer;
/// Возвращает последовательность вещественных, вводимых с клавиатуры пока выполняется определенное условие
function ReadSeqRealWhile(cond: real->boolean): sequence of real;
/// Возвращает последовательность строк, вводимых с клавиатуры пока выполняется определенное условие
function ReadSeqStringWhile(cond: string->boolean): sequence of string;
/// Выводит приглашение к вводу и возвращает последовательность целых, вводимых с клавиатуры пока выполняется определенное условие
function ReadSeqIntegerWhile(prompt: string; cond: integer->boolean): sequence of integer;
/// Выводит приглашение к вводу и возвращает последовательность вещественных, вводимых с клавиатуры пока выполняется определенное условие
function ReadSeqRealWhile(prompt: string; cond: real->boolean): sequence of real;
/// Выводит приглашение к вводу и возвращает последовательность строк, вводимых с клавиатуры пока выполняется определенное условие
function ReadSeqStringWhile(prompt: string; cond: string->boolean): sequence of string;
// -----------------------------------------------------
//>> Подпрограммы для создания динамических массивов # Subroutines for array of T generation
// -----------------------------------------------------
/// Возвращает массив, заполненный указанными значениями
function Arr<T>(params a: array of T): array of T;
/// Возвращает массив, заполненный значениями из последовательнсти
function Arr<T>(a: sequence of T): array of T;
/// Возвращает массив размера n, заполненный случайными целыми значениями
function ArrRandom(n: integer := 10; a: integer := 0; b: integer := 100): array of integer;
/// Возвращает массив размера n, заполненный случайными целыми значениями
function ArrRandomInteger(n: integer := 10; a: integer := 0; b: integer := 100): array of integer;
/// Возвращает массив размера n, заполненный случайными вещественными значениями
function ArrRandomReal(n: integer := 10; a: real := 0; b: real := 10): array of real;
/// Возвращает массив из count элементов, заполненных значениями gen(i)
function ArrGen<T>(count: integer; gen: integer->T): array of T;
/// Возвращает массив из count элементов, заполненных значениями gen(i), начиная с i=from
function ArrGen<T>(count: integer; gen: integer->T; from: integer): array of T;
/// Возвращает массив из count элементов, начинающихся с first, с функцией next перехода от предыдущего к следующему
function ArrGen<T>(count: integer; first: T; next: T->T): array of T;
/// Возвращает массив из count элементов, начинающихся с first и second, с функцией next перехода от двух предыдущих к следующему
function ArrGen<T>(count: integer; first, second: T; next: (T,T) ->T): array of T;
/// Возвращает массив из count элементов x
function ArrFill<T>(count: integer; x: T): array of T;
/// Возвращает массив из n целых, введенных с клавиатуры
function ReadArrInteger(n: integer): array of integer;
/// Возвращает массив из n целых int64, введенных с клавиатуры
function ReadArrInt64(n: integer): array of int64;
/// Возвращает массив из n вещественных, введенных с клавиатуры
function ReadArrReal(n: integer): array of real;
/// Возвращает массив из n строк, введенных с клавиатуры
function ReadArrString(n: integer): array of string;
///--
function ReadArrInteger: array of integer;
///--
function ReadArrReal: array of real;
///--
function ReadArrString: array of string;
/// Выводит приглашение к вводу и возвращает массив из n целых, введенных с клавиатуры
function ReadArrInteger(prompt: string; n: integer): array of integer;
/// Выводит приглашение к вводу и возвращает массив из n вещественных, введенных с клавиатуры
function ReadArrReal(prompt: string; n: integer): array of real;
/// Выводит приглашение к вводу и возвращает массив из n строк, введенных с клавиатуры
function ReadArrString(prompt: string; n: integer): array of string;
// -----------------------------------------------------
//>> Подпрограммы для создания двумерных динамических массивов # Subroutines for matrixes
// -----------------------------------------------------
/// Возвращает двумерный массив размера m x n, заполненный указанными значениями по строкам
function Matr<T>(m,n: integer; params data: array of T): array [,] of T;
/// Возвращает двумерный массив, заполненный значениями из одномерных массивов
function Matr<T>(params aa: array of array of T): array [,] of T;
/// Возвращает двумерный массив размера m x n, заполненный случайными целыми значениями
function MatrRandom(m: integer := 5; n: integer := 5; a: integer := 0; b: integer := 100): array [,] of integer;
/// Возвращает двумерный массив размера m x n, заполненный случайными целыми значениями
function MatrRandomInteger(m: integer := 5; n: integer := 5; a: integer := 0; b: integer := 100): array [,] of integer;
/// Возвращает двумерный массив размера 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<T>(m, n: integer; x: T): array [,] of T;
/// Возвращает двумерный массив размера m x n, заполненный элементами gen(i,j)
function MatrGen<T>(m, n: integer; gen: (integer,integer)->T): array [,] of T;
/// Транспонирует двумерный массив
function Transpose<T>(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<T1, T2>(x1: T1; x2: T2): System.Tuple<T1, T2>;
///--
function Rec<T1, T2, T3>(x1: T1; x2: T2; x3: T3): (T1, T2, T3);
///--
function Rec<T1, T2, T3, T4>(x1: T1; x2: T2; x3: T3; x4: T4): (T1, T2, T3, T4);
///--
function Rec<T1, T2, T3, T4, T5>(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5): (T1, T2, T3, T4, T5);
///--
function Rec<T1, T2, T3, T4, T5, T6>(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5; x6: T6): (T1, T2, T3, T4, T5, T6);
///--
function Rec<T1, T2, T3, T4, T5, T6, T7>(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
// -----------------------------------------------------
/// Возвращает список, заполненный указанными значениями
function Lst<T>(params a: array of T): List<T>;
/// Возвращает список, заполненный значениями из последовательности
function Lst<T>(a: sequence of T): List<T>;
/// Возвращает двусвязный список, заполненный указанными значениями
function LLst<T>(params a: array of T): LinkedList<T>;
/// Возвращает двусвязный список, заполненный значениями из последовательности
function LLst<T>(a: sequence of T): LinkedList<T>;
/// Возвращает множество на базе хеш таблицы, заполненное указанными значениями
function HSet<T>(params a: array of T): HashSet<T>;
/// Возвращает множество на базе хеш таблицы, заполненное значениями из последовательности
function HSet<T>(a: sequence of T): HashSet<T>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное значениями из последовательности
function SSet<T>(params a: array of T): SortedSet<T>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное значениями из последовательности
function SSet<T>(a: sequence of T): SortedSet<T>;
/// Возвращает словарь пар элементов (ключ, значение)
function Dict<TKey, TVal>(params pairs: array of KeyValuePair<TKey, TVal>): Dictionary<TKey, TVal>;
/// Возвращает словарь пар элементов (ключ, значение)
function Dict<TKey, TVal>(params pairs: array of (TKey, TVal)): Dictionary<TKey, TVal>;
/// Возвращает пару элементов (ключ, значение)
function KV<TKey, TVal>(key: TKey; value: TVal): KeyValuePair<TKey, TVal>;
//{{{--doc: Конец секции интерфейса для документации }}}
// -----------------------------------------------------
//>> Вспомогательные функции для pattern matching #
// -----------------------------------------------------
///--
function __TypeCheckAndAssignForIsMatch<T>(obj: object; var res: T): boolean;
///--
function __WildCardsTupleEqual<T1, T2, T3, T4>(
first: Tuple<T1, T2>;
second: Tuple<T3, T4>;
elemsToCompare: sequence of integer): boolean;
///--
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6>(
first: Tuple<T1, T2, T3>;
second: Tuple<T4, T5, T6>;
elemsToCompare: sequence of integer): boolean;
///--
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8>(
first: Tuple<T1, T2, T3, T4>;
second: Tuple<T5, T6, T7, T8>;
elemsToCompare: sequence of integer): boolean;
///--
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
first: Tuple<T1, T2, T3, T4, T5>;
second: Tuple<T6, T7, T8, T9, T10>;
elemsToCompare: sequence of integer): boolean;
///--
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(
first: Tuple<T1, T2, T3, T4, T5, T6>;
second: Tuple<T7, T8, T9, T10, T11, T12>;
elemsToCompare: sequence of integer): boolean;
///--
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(
first: Tuple<T1, T2, T3, T4, T5, T6, T7>;
second: Tuple<T8, T9, T10, T11, T12, T13, T14>;
elemsToCompare: sequence of integer): boolean;
// Вспомогательные функции для a..b
///--
function InRangeInternal(x: integer; a,b: integer): boolean;
///--
function InRangeInternal(x: char; a,b: char): boolean;
// -----------------------------------------------------
// Стандартные классы исключений
// -----------------------------------------------------
type
///Базовый класс для исключений, бросаемых при создании инстанции generic-типа
BadGenericInstanceParameterException = class(Exception)
protected
InstanceType: System.Type;
public
constructor Create(ActualParameterType: System.Type);
end;
///Бросается если тип непригоден для указателей
CanNotUseTypeForPointersException = class(BadGenericInstanceParameterException)
public
function ToString: string; override;
end;
///Бросается если тип непригоден для типизированных файлов
CanNotUseTypeForTypedFilesException = class(BadGenericInstanceParameterException)
public
function ToString: string; override;
end;
///Бросается если тип непригоден для бинарных файлов
CanNotUseTypeForFilesException = class(BadGenericInstanceParameterException)
public
function ToString: string; override;
end;
RangeException = class(SystemException) end;
CommandLineArgumentOutOfRangeException = class(SystemException) end;
// -----------------------------------------------------
// Общедоступные переменные
// -----------------------------------------------------
var
/// Содержит аргумены командой строки, с которыми была запущена программа
CommandLineArgs: array of string;
/// Стандартный текстовый файл для вывода. Связывается процедурой Assign с файлом на диске, после чего весь вывод на консоль перенаправляется в этот файл
output: TextFile;
/// Стандартный текстовый файл для ввода. Связывается процедурой Assign с файлом на диске, после чего весь ввод с консоли перенаправляется из этого файла
input: TextFile;
/// Определяет текущую систему ввода-вывода
CurrentIOSystem: IOSystem;
/// Принимает значение True, если приложение имеет консольное окно
IsConsoleApplication: boolean;
///--
RedirectIOInDebugMode := False;
///--
ExecuteBeforeProcessTerminateIn__Mode: procedure(e: Exception);
//GCHandlersForReferencePointers := new GCHandlersController;
///--
ExitCode := 0; // TODO Сделать возврат в Main
///--
DefaultEncoding: Encoding;
///--
PrintDelimDefault: string := ' ';
///--
PrintMatrixWithFormat: boolean := True;
var
///--
__CONFIG__: Dictionary<string, object> := new Dictionary<string, object>;
// Вспомогательные подпрограммы. Из раздела интерфейса не убирать!!!
// -----------------------------------------------------
// Internal System subprograms
// -----------------------------------------------------
///--
function CopyWithSize(source, dest: &Array): &Array;
///--
function check_in_range(val: int64; low, up: int64): int64;
///--
function check_in_range_char(val: char; low, up: char): char;
///--
function RunTimeSizeOf(t: System.Type): integer;
///--
function GetCharInShortString(s: string; ind, n: integer): char;
///--
function SetCharInShortString(s: string; ind, n: integer; c: char): string;
///--
function ClipShortString(s: string; len: integer): string;
///--
function GetResourceStream(ResourceFileName: string): Stream;
///--
function FormatValue(value: object; NumOfChars: integer): string;
///--
function FormatValue(value: integer; NumOfChars: integer): string;
///--
function FormatValue(value: int64; NumOfChars: integer): string;
///--
function FormatValue(value: real; NumOfChars: integer): string;
///--
function FormatValue(value: real; NumOfChars, NumOfSignesAfterDot: integer): string;
///--
procedure StringDefaultPropertySet(var s: string; index: integer; c: char);
//procedure InitShortString(var s: ShortString; Length: integer);
///Проверяет возможность использования указателей на тип T
procedure CheckCanUsePointerOnType(T: System.Type);
///Проверяет возможность записи типа T в файл
procedure CheckCanUseTypeForBinaryFiles(T: System.Type);
///Проверяет возможность создания file of T
procedure CheckCanUseTypeForTypedFiles(T: System.Type);
///Определяет специальные типы
function RuntimeDetermineType(T: System.Type): byte;
///Возвращает объект класса в зависимости от значения kind
function RuntimeInitialize(kind: byte; variable: object): object;
///Вычисление размера типа на этапе выполнения
function GetRuntimeSize<T>: integer;
///Возвращает строку для вывода в write
function _ObjectToString(o: object): string;
function IsUnix: boolean;
///--
function ExecuteAssemlyIsDll: boolean;
///--
function __StandardFilesDirectory: string;
///--
function __FindFile(filename: string): string;
// -----------------------------------------------------
// Internal for OpenMPSupport
// -----------------------------------------------------
///--
procedure omp_set_nested(nested: integer);
///--
function omp_get_nested: integer;
///--
var
OMP_NESTED: boolean := false;
// -----------------------------------------------------
// Internal typed sets operations
// -----------------------------------------------------
///--
function Union(s1, s2: TypedSet): TypedSet;
///--
function Subtract(s1, s2: TypedSet): TypedSet;
///--
function Intersect(s1, s2: TypedSet): TypedSet;
///--
function CreateSet(params elems: array of object): TypedSet;
///--
function CreateSet: TypedSet;
///--
function CreateBoundedSet(low, high: object): TypedSet;
///--
function InSet(obj: object; s: TypedSet): boolean;
///--
function CreateDiapason(low, high: integer): Diapason;
///--
function CreateObjDiapason(low, high: object): Diapason;
///--
function CompareSetEquals(s1, s2: TypedSet): boolean;
///--
function CompareSetInEquals(s1, s2: TypedSet): boolean;
///--
function CompareSetLess(s1, s2: TypedSet): boolean;
///--
function CompareSetGreaterEqual(s1, s2: TypedSet): boolean;
///--
function CompareSetLessEqual(s1, s2: TypedSet): boolean;
///--
function CompareSetGreater(s1, s2: TypedSet): boolean;
///--
procedure ClipSet(var s: TypedSet; low, high: object);
///--
procedure AssignSet(var left: TypedSet; right: TypedSet);
///--
function ClipSetFunc(s: TypedSet; low, high: object): TypedSet;
///--
function ClipShortStringInSet(s: TypedSet; len: integer): TypedSet;
///--
procedure ClipShortStringInSetProcedure(var s: TypedSet; len: integer);
///--
procedure AssignSetWithBounds(var left: TypedSet; right: TypedSet; low, high: object);
///--
procedure TypedSetInit(var st: TypedSet);
///--
procedure TypedSetInitWithBounds(var st: TypedSet; low, high: object);
///--
procedure TypedSetInitWithShortString(var st: TypedSet; len: integer);
// -----------------------------------------------------
// Internal classes
// -----------------------------------------------------
type
///--
GCHandlersController = class(System.Collections.IEnumerable)
private
Counters, Handlers: Hashtable;
public
constructor;
procedure Add(obj: Object);
procedure Remove(obj: Object);
function GetCounter(obj: Object): integer;
function GetEnumerator: System.Collections.IEnumerator;
end;
type
///--
PointerOutput = class
public
p: pointer;
function ToString: string; override;
constructor(ptr: pointer);
end;
type
///--
__ConceptSingleton<T> = 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;}
type
// Смысл полей Num, Width и Fmt соответствует
// атрибутам форматирования {Num,Width:Fmt}.
// Поле Comment может интерпретироваться как
// дополнительная строка, приписываемая слева к свойству.
// Если для первого атрибута дополнительная строка
// начинается со скобок или кавычек, то парные символы
// добавляются в конец итоговой строки.
/// Класс атрибута форматирования текста
PrintAttribute = class(System.Attribute)
public
Comment: string;
Num: integer;
Width: integer;
Fmt: string;
constructor (n: integer) := (Comment, Num, Width, Fmt) := ('', n, 0, '');
constructor (n, w: integer) := (Comment, Num, Width, Fmt) := ('', n, w, '');
constructor (n: integer; f: string) := (Comment, Num, Width, Fmt) := ('', n, 0, f);
constructor (n, w: integer; f: string) := (Comment, Num, Width, Fmt) := ('', n, w, f);
constructor (c: string; n: integer) := (Comment, Num, Width, Fmt) := (c, n, 0, '');
constructor (c: string; n, w: integer) := (Comment, Num, Width, Fmt) := (c, n, w, '');
constructor (c: string; n: integer; f: string) := (Comment, Num, Width, Fmt) := (c, n, 0, f);
constructor (c: string; n, w: integer; f: string) := (Comment, Num, Width, Fmt) := (c, n, w, f);
end;
type
/// Тип диапазона целых
IntRange = class(IEnumerable<integer>)
private
l,h: integer;
public
constructor(l,h: integer);
begin
Self.l := l;
Self.h := h;
end;
property Low: integer read l;
property High: integer read h;
static function operator in(x: integer; r: IntRange): boolean := (x >= r.l) and (x <= r.h);
static function operator=(r1,r2: IntRange): boolean := (r1.l = r2.l) and (r1.h = r2.h);
function IsEmpty: boolean := l<=h;
function GetEnumerator(): IEnumerator<integer> := Range(l,h).GetEnumerator;
function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := Range(l,h).GetEnumerator;
function ToString: string; override := $'({l},{h})';
function Equals(o: Object): boolean; override;
begin
var r2 := IntRange(o);
Result := (l = r2.l) and (h = r2.h);
end;
function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode;
end;
/// Тип диапазона символов
CharRange = class(IEnumerable<char>)
private
l,h: char;
public
constructor(l,h: char);
begin
Self.l := l;
Self.h := h;
end;
property Low: char read l;
property High: char read h;
static function operator in(x: char; r: CharRange): boolean := (x >= r.l) and (x <= r.h);
static function operator=(r1,r2: CharRange): boolean := (r1.l = r2.l) and (r1.h = r2.h);
function IsEmpty: boolean := l<=h;
function GetEnumerator(): IEnumerator<char> := Range(l,h).GetEnumerator;
function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := Range(l,h).GetEnumerator;
function ToString: string; override := $'({l},{h})';
function Equals(o: Object): boolean; override;
begin
var r2 := CharRange(o);
Result := (l = r2.l) and (h = r2.h);
end;
function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode;
end;
///--
function InternalRange(l,r: integer): IntRange;
///--
function InternalRange(l,r: char): CharRange;
// -----------------------------------------------------
// Internal procedures for PABCRTL.dll
// -----------------------------------------------------
///--
procedure __InitModule__;
///--
procedure __InitPABCSystem;
///--
procedure __FinalizeModule__;
// -----------------------------------------------------
// DQNToNullable for dot_question_node
// -----------------------------------------------------
function DQNToNullable<T>(v: T): Nullable<T>; where T: record;
implementation
var
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
const
WRITELN_IN_BINARYFILE_ERROR_MESSAGE = 'Операция Writeln не применима к бинарным файлам!!Writeln is not applicable to binary files';
InternalNullBasedArrayName = 'NullBasedArray';
FILE_NOT_ASSIGNED = 'Для файловой переменной не вызвана процедура Assign!!File is not assigned';
FILE_NOT_OPENED = 'Файл не открыт!!File is not opened';
FILE_NOT_OPENED_FOR_READING = 'Файл не открыт на чтение!!File is not opened for reading';
FILE_NOT_OPENED_FOR_WRITING = 'Файл не открыт на запись!!File is not opened for writing';
READ_LEXEM_AFTER_END_OF_TEXT_FILE = 'Попытка считывания за концом текстового файла!!Read after end of text file';
READ_LEXEM_AFTER_END_OF_INPUT_STREAM = 'Попытка считывания за концом потока ввода!!Read after end of input stream';
RANGE_ERROR_MESSAGE = 'Выход за границы диапазона!!Out of range';
EOF_FOR_TEXT_WRITEOPENED = 'Функция Eof не может быть вызвана для текстового файла, открытого на запись!!Eof function can''t be called for file, opened on writing';
EOLN_FOR_TEXT_WRITEOPENED = 'Функция Eoln не может быть вызвана для текстового файла, открытого на запись!!Eoln function can''t be called for file, opened on writing';
SEEKEOF_FOR_TEXT_WRITEOPENED = 'Функция SeekEof не может быть вызвана для текстового файла, открытого на запись!!SeekEof function can''t be called for file, opened on writing';
SEEKEOLN_FOR_TEXT_WRITEOPENED = 'Функция SeekEoln не может быть вызвана для текстового файла, открытого на запись!!SeekEoln function can''t be called for file, opened on writing';
BAD_TYPE_IN_RUNTIMESIZEOF = 'Для типизированных файлов нельзя указывать тип элементов, являющийся ссылочным или содержащий ссылочные поля!!Bad Type in RunTimeSizeOf';
PARAMETER_MUST_BE_GREATER_EQUAL_0 = 'Параметр должен быть >= 0!!Parameter must be >= 0';
PARAMETER_MUST_BE_GREATER_0 = 'Параметр должен быть > 0!!Parameter must be > 0';
PARAMETER_MUST_BE_GREATER_1 = 'Параметр должен быть > 1!!Parameter must be > 1';
PARAMETER_STEP_MUST_BE_NOT_EQUAL_0 = 'Параметр step не может быть равен 0!!The step parameter must be not equal to 0';
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';
INITELEM_COUNT_MUST_BE_EQUAL_TO_MATRIX_ELEMS_COUNT = 'Количество инициализирующих элементов не совпадает с количеством элементов матрицы!!The number of elements in init list must be equal to the number of elements in matrix';
TYPED_FILE_CANBE_OPENED_IN_SINGLEBYTE_ENCODING_ONLY = 'При открытии типизированного файла можно указывать только однобайтную кодировку!!Typed file can be opened in single byte encoding only';
BAD_ROW_INDEX = 'Один из элементов массива RowIndex выходит за пределы индексов строк двумерного массива!!One of the elements of RowIndex array is out of range of 2-dim array row indexes';
BAD_COL_INDEX = 'Один из элементов массива ColIndex выходит за пределы индексов столбцов двумерного массива!!One of the elements of ColIndex array is out of range of 2-dim array column indexes';
BAD_ROW_INDEX_FROM = 'FromRow выходит за пределы индексов строк двумерного массива!!FromRow is out of range of 2-dim array row indexes';
BAD_ROW_INDEX_TO = 'ToRow выходит за пределы индексов строк двумерного массива!!ToRow is out of range of 2-dim array row indexes';
BAD_COL_INDEX_FROM = 'FromCol выходит за пределы индексов строк двумерного массива!!FromCol is out of range of 2-dim array column indexes';
BAD_COL_INDEX_TO = 'ToCol выходит за пределы индексов строк двумерного массива!!ToCol is out of range of 2-dim array column indexes';
// -----------------------------------------------------
// WINAPI
// -----------------------------------------------------
function WINAPI_AllocConsole: longword; external 'kernel32.dll' name 'AllocConsole';
var
console_alloc: boolean := false;
// -----------------------------------------------------
// Internal functions
// -----------------------------------------------------
function GetCurrentLocale: string;
begin
var locale: object;
if __CONFIG__.TryGetValue('locale', locale) then
Result := locale as string
else
Result := 'ru';
end;
function GetTranslation(message: string): string;
begin
var cur_locale := GetCurrentLocale();
var arr := message.Split(new string[1]('!!'), StringSplitOptions.None);
if (cur_locale = 'en') and (arr.Length > 1) then
Result := arr[1]
else
Result := arr[0]
end;
function IsWDE: boolean;
begin
Result := AppDomain.CurrentDomain.GetData('_RedirectIO_SpecialArgs') <> nil;
end;
[System.Security.SecuritySafeCriticalAttribute]
procedure AllocConsole;
begin
if not IsConsoleApplication and (System.Environment.OSVersion.Platform <> PlatformID.Unix) and (AppDomain.CurrentDomain.GetData('_RedirectIO_SpecialArgs') = nil) then
WINAPI_AllocConsole;
console_alloc := true;
end;
function GetNullBasedArray(arr: object): System.Array;
var
fi: System.Reflection.FieldInfo;
begin
fi := arr.GetType.GetField(InternalNullBasedArrayName);
if fi <> nil then
Result := System.Array(fi.GetValue(arr))
else
Result := nil;
end;
function FormatFloatNumber(s: string): string;
begin
Result := s.Replace(',', '.');
end;
procedure ClipSet(var s: TypedSet; low, high: object);
begin
s.low_bound := low;
s.upper_bound := high;
s.Clip;
end;
function ClipSetFunc(s: TypedSet; low, high: object): TypedSet;
begin
s.low_bound := low;
s.upper_bound := high;
s.Clip();
Result := s;
end;
function ClipShortStringInSet(s: TypedSet; len: integer): TypedSet;
begin
s.len := len;
s.Clip;
Result := s;
end;
procedure ClipShortStringInSetProcedure(var s: TypedSet; len: integer);
begin
s.len := len;
s.Clip;
end;
procedure AssignSet(var left: TypedSet; right: TypedSet);
begin
left := right.CloneSet();
end;
procedure AssignSetWithBounds(var left: TypedSet; right: TypedSet; low, high: object);
begin
left := right.CloneSet();
left.low_bound := low;
right.upper_bound := high;
end;
procedure TypedSetInit(var st: TypedSet);
begin
if st = nil then
st := new TypedSet;
end;
procedure TypedSetInitWithBounds(var st: TypedSet; low, high: object);
begin
if st = nil then
st := new TypedSet(low, high);
end;
procedure TypedSetInitWithShortString(var st: TypedSet; len: integer);
begin
if st = nil then
st := new TypedSet(len);
end;
// -----------------------------------------------------
// Diapason
// -----------------------------------------------------
constructor Diapason.Create(_low, _high: integer);
begin
low := _low;high := _high;
end;
constructor Diapason.Create(_low, _high: object);
begin
clow := _low;chigh := _high;
end;
// -----------------------------------------------------
// TypedSet
// -----------------------------------------------------
///--
constructor TypedSet.Create;
begin
ht := new Hashtable({new TypedSetComparer()});
end;
///--
constructor TypedSet.Create(len: integer);
begin
ht := new Hashtable({new TypedSetComparer()});
Self.len := len;
end;
///--
constructor TypedSet.Create(low_bound, upper_bound: object);
begin
ht := new Hashtable({new TypedSetComparer()});
Self.low_bound := low_bound;
Self.upper_bound := upper_bound;
end;
///--
constructor TypedSet.Create(initValue: TypedSet);
begin
ht := new Hashtable({new TypedSetComparer()});
Self.AssignSetFrom(initValue);
Self.len := initValue.len;
end;
///--
constructor TypedSet.Create(low_bound, upper_bound: object; initValue: TypedSet);
begin
ht := new Hashtable({new TypedSetComparer()});
Self.low_bound := low_bound;
Self.upper_bound := upper_bound;
Self.AssignSetFrom(initValue);
end;
///--
constructor TypedSet.Create(vals: array of byte);
var
i: integer;
begin
ht := new Hashtable({new TypedSetComparer()});
i := 0;
while i < 256 div 8 do
begin
if vals[i] and 128 = 128 then ht.Add(i * 8, i * 8);
if vals[i] and 64 = 64 then ht.Add(i * 8 + 1, i * 8 + 1);
if vals[i] and 32 = 32 then ht.Add(i * 8 + 2, i * 8 + 2);
if vals[i] and 16 = 16 then ht.Add(i * 8 + 3, i * 8 + 3);
if vals[i] and 8 = 8 then ht.Add(i * 8 + 4, i * 8 + 4);
if vals[i] and 4 = 4 then ht.Add(i * 8 + 5, i * 8 + 5);
if vals[i] and 2 = 2 then ht.Add(i * 8 + 6, i * 8 + 6);
if vals[i] and 1 = 1 then ht.Add(i * 8 + 7, i * 8 + 7);
i := i + 1;
end;
end;
///--
procedure TypedSet.CreateIfNeed;
begin
if ht = nil then ht := new Hashtable({new TypedSetComparer()});
end;
[System.Diagnostics.DebuggerStepThrough]
function TypedSet.CloneSet: TypedSet;
begin
Result := new TypedSet();
Result.ht := ht.Clone() as Hashtable;
//Result.copy_ht := ht;
Result.low_bound := low_bound;
Result.upper_bound := upper_bound;
end;
///--
function TypedSet.GetBytes: array of byte;
var
ba: System.Collections.BitArray;
i: integer;
begin
ba := new BitArray(256);
Result := nil;
foreach o: object in ht.Keys do
begin
try
i := Convert.ToInt32(o);
if (i < 0) and (i >= -128) and (i <= 127) then
ba[i + 128] := true
else if (i >= 0) and (i <= 255) then
ba[i] := true;
except
on e: System.Exception do
begin
Result := nil;
//Exit;
end;
end;
end;
SetLength(Result, 256 div 8);
i := 0;
while i < 256 div 8 do
begin
Result[i] := Convert.ToByte(ba[i * 8 + 7]) or (Convert.ToByte(ba[i * 8 + 6]) shl 1) or (Convert.ToByte(ba[i * 8 + 5]) shl 2) or (Convert.ToByte(ba[i * 8 + 4]) shl 3)
or (Convert.ToByte(ba[i * 8 + 3]) shl 4) or (Convert.ToByte(ba[i * 8 + 2]) shl 5) or (Convert.ToByte(ba[i * 8 + 1]) shl 6) or (Convert.ToByte(ba[i * 8]) shl 7);
i := i + 1;
end;
end;
///--
function TypedSet.UnionSet(s: TypedSet): TypedSet;
begin
Result := Union(Self, s);
end;
///--
function TypedSet.SubtractSet(s: TypedSet): TypedSet;
begin
Result := Subtract(Self, s);
end;
///--
function TypedSet.IntersectSet(s: TypedSet): TypedSet;
begin
Result := Intersect(Self, s);
end;
///--
function TypedSet.IsInDiapason(elem: object): boolean;
begin
if (low_bound <> nil) and (upper_bound <> nil) and (elem is System.IComparable) then
begin
case System.Type.GetTypeCode(elem.GetType) of
TypeCode.Char:
begin
if ((elem as System.IComparable).CompareTo(Convert.ToChar(low_bound)) >= 0) and ((elem as System.IComparable).CompareTo(Convert.ToChar(upper_bound)) <= 0) then
Result := true
else Result := false
end;
TypeCode.Int32:
begin
if not (elem is integer) then elem := Convert.ToInt32(elem);
if ((elem as System.IComparable).CompareTo(Convert.ToInt32(low_bound)) >= 0) and ((elem as System.IComparable).CompareTo(Convert.ToInt32(upper_bound)) <= 0) then
Result := true
else Result := false
end;
TypeCode.Byte:
begin
if ((elem as System.IComparable).CompareTo(Convert.ToByte(low_bound)) >= 0) and ((elem as System.IComparable).CompareTo(Convert.ToByte(upper_bound)) <= 0) then
Result := true
else Result := false
end;
TypeCode.SByte:
begin
if ((elem as System.IComparable).CompareTo(Convert.ToSByte(low_bound)) >= 0) and ((elem as System.IComparable).CompareTo(Convert.ToSByte(upper_bound)) <= 0) then
Result := true
else Result := false
end;
TypeCode.Int16:
begin
if ((elem as System.IComparable).CompareTo(Convert.ToInt16(low_bound)) >= 0) and ((elem as System.IComparable).CompareTo(Convert.ToInt16(upper_bound)) <= 0) then
Result := true
else Result := false
end;
TypeCode.UInt16:
begin
if ((elem as System.IComparable).CompareTo(Convert.ToUint16(low_bound)) >= 0) and ((elem as System.IComparable).CompareTo(Convert.ToUInt16(upper_bound)) <= 0) then
Result := true
else Result := false
end;
TypeCode.UInt32:
begin
if ((elem as System.IComparable).CompareTo(Convert.ToUInt32(low_bound)) >= 0) and ((elem as System.IComparable).CompareTo(Convert.ToUInt32(upper_bound)) <= 0) then
Result := true
else Result := false
end;
TypeCode.Int64:
begin
if ((elem as System.IComparable).CompareTo(Convert.ToInt64(low_bound)) >= 0) and ((elem as System.IComparable).CompareTo(Convert.ToInt64(upper_bound)) <= 0) then
Result := true
else Result := false
end;
TypeCode.UInt64:
begin
if ((elem as System.IComparable).CompareTo(Convert.ToUInt64(low_bound)) >= 0) and ((elem as System.IComparable).CompareTo(Convert.ToUInt64(upper_bound)) <= 0) then
Result := true
else Result := false
end;
else
if elem.GetType().IsEnum then
begin
if ((Convert.ToInt32(elem)).CompareTo(Convert.ToInt32(low_bound)) >= 0) and ((Convert.ToInt32(elem)).CompareTo(Convert.ToInt32(upper_bound)) <= 0) then
Result := true
else Result := false
end
else Result := true;
end// case
end // then
else Result := true;
end;
function convert_elem(obj: object): object;// для TypedSet
begin
var t := obj.GetType;
if t.IsEnum then
begin
Result := obj;
exit;
end;
case System.Type.GetTypeCode(t) of
TypeCode.Byte, TypeCode.SByte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32:
Result := Convert.ToInt32(obj);
TypeCode.UInt32:
begin
var tmp: longword := longword(obj);
if tmp <= integer.MaxValue then
Result := integer(tmp)
else
Result := Convert.ToInt64(obj);
end;
TypeCode.Int64:
begin
var tmp: int64 := int64(obj);
if tmp <= integer.MaxValue then
Result := integer(tmp)
else
Result := obj;
end;
TypeCode.UInt64:
begin
var tmp: uint64 := uint64(obj);
if tmp <= integer.MaxValue then
Result := integer(tmp)
else
if tmp <= int64.MaxValue then
Result := int64(tmp)
else
Result := obj;
end
else
Result := obj;
end;
end;
///--
function TypedSet.Contains(elem: object): boolean;
begin
if elem.GetType().IsEnum then
begin
Result := ht[elem] <> nil
end
else
begin
elem := convert_elem(elem);
Result := ht.ContainsKey(elem);// <> nil;
if not Result and (elem is char) then
Result := ht.ContainsKey(Convert.ToString(elem));
end;
end;
///--
procedure TypedSet.Clip;
begin
if Self.len > 0 then
begin
Clip(Self.len);
exit;
end;
var tmp_ht := new Hashtable();
foreach el: object in ht.Keys do
begin
if IsInDiapason(el) then
begin
if (Self.low_bound <> nil) then
begin
var tmp := convert_elem(el);
tmp_ht.Add(tmp, tmp)
end
else
tmp_ht.Add(el, el);
end;
end;
ht := tmp_ht;
end;
///--
procedure TypedSet.Clip(len: integer);
begin
var tmp_ht := new Hashtable();
foreach el: object in ht.Keys do
begin
var str_el := Convert.ToString(el);
if str_el.Length > len then
begin
var s := str_el.Substring(0, len);
tmp_ht.Add(s, s);
end
else
tmp_ht.Add(str_el, str_el);
end;
ht := tmp_ht;
end;
procedure TypedSet.IncludeElement(elem: object);
var
diap: Diapason;
begin
if elem = nil then exit;
elem := convert_elem(elem);
if not IsInDiapason(elem) then Exit;
if elem.GetType().IsEnum then
begin
ht[elem] := elem;
//if copy_ht <> nil then
// copy_ht[elem] := elem;
end
else
if not (elem is Diapason) then
begin
ht[elem] := elem;
//if copy_ht <> nil then
// copy_ht[elem] := elem;
end
else
begin
diap := Diapason(elem);
if diap.clow = nil then
begin
for var i := diap.low to diap.high do
begin
ht[i] := i;
//if copy_ht <> nil then
// copy_ht[i] := i;
end
end
else
begin
if diap.clow is char then
begin
for var c := char(diap.clow) to char(diap.chigh) do
begin
ht[c] := c;
//if copy_ht <> nil then
// copy_ht[c] := c;
end
end
else if diap.clow is boolean then
begin
for var b := boolean(diap.clow) to boolean(diap.chigh) do
ht[b] := b;
end
else if diap.clow.GetType().IsEnum then
begin
for var i := integer(diap.clow) to integer(diap.chigh) do
begin
var obj := Enum.ToObject(diap.clow.GetType(), i);
ht[obj] := obj;
//if copy_ht <> nil then
// copy_ht[obj] := obj;
end;
end;
end;
end;
end;
procedure TypedSet.ExcludeElement(elem: object);
begin
if elem.GetType().IsEnum then
begin
ht.Remove(elem);
end
else
begin
elem := convert_elem(elem);
ht.Remove(elem);
end
end;
///--
procedure TypedSet.Init(params elems: array of object);
begin
for var i := 0 to elems.Length - 1 do
ht[elems[i]] := elems[i];
end;
[System.Diagnostics.DebuggerStepThrough]
procedure TypedSet.AssignSetFrom(s: TypedSet);
begin
ht := s.ht.Clone() as Hashtable;
Clip;
end;
///--
function TypedSet.GetEnumerator: System.Collections.IEnumerator;
begin
Result := ht.Keys.GetEnumerator;
end;
function FormatStr(obj: object): string;
begin
if (obj.GetType = typeof(char)) or (obj.GetType = typeof(string)) then
Result := '''' + string.Format(System.Globalization.NumberFormatInfo.InvariantInfo, '{0}', new object[](obj)) + ''''
else
Result := string.Format(System.Globalization.NumberFormatInfo.InvariantInfo, '{0}', new object[](obj))
end;
///--
class function TypedSet.operator implicit<T>(s: TypedSet): HashSet<T>;
begin
var hs := new HashSet<T>();
foreach var key in s.ht.Keys do
begin
hs.Add(T(key));
end;
Result := hs;
end;
///--
class function TypedSet.operator implicit<T>(s: HashSet<T>): TypedSet;
begin
var ts := new TypedSet();
foreach key: T in s.ToArray() do
begin
ts.ht[key] := key;
end;
Result := ts;
end;
///--
function TypedSet.ToString: string;
var
i: System.Collections.IEnumerator;
lst: ArrayList;
begin
i := GetEnumerator;
lst := new ArrayList();
var t: &Type;
var added := false;
if i.MoveNext then
if not (i.Current is System.IComparable) then
begin
result := '' + FormatStr(i.Current) + '';
added := true;
end
else
begin
lst.Add(i.Current);
t := i.Current.GetType;
end;
while i.MoveNext do
if not (i.Current is System.IComparable) then
begin
result := (added ? result + ',' : '') + FormatStr(i.Current);
added := true;
end
else
begin
if (t <> nil) and (t <> i.Current.GetType) then
begin
result := (added ? result + ',' : '') + FormatStr(i.Current);
added := true;
end
else
begin
t := i.Current.GetType;
lst.Add(i.Current);
end;
end;
if lst.Count > 0 then
begin
lst.Sort;
var ind := 1;
if not added then
result := '' + FormatStr(lst[0]) + ''
else
ind := 0;
for j: integer := ind to lst.Count - 1 do
begin
result := result + ',' + FormatStr(lst[j]);
end;
end;
result := '[' + result + ']';
end;
{class function TypedSet.operator implicit<T>(hset: HashSet<T>): TypedSet;
begin
Result := new TypedSet();
foreach var x in hset do
Result.ht[x] := x;
end;}
///--
function TypedSet.CompareEquals(s: TypedSet): boolean;
begin
Result := CompareSetEquals(Self, s);
end;
///--
function TypedSet.CompareInEquals(s: TypedSet): boolean;
begin
Result := CompareSetInEquals(Self, s);
end;
///--
function TypedSet.CompareLess(s: TypedSet): boolean;
begin
Result := CompareSetLess(Self, s);
end;
///--
function TypedSet.CompareLessEqual(s: TypedSet): boolean;
begin
Result := CompareSetLessEqual(Self, s);
end;
///--
function TypedSet.CompareGreater(s: TypedSet): boolean;
begin
Result := CompareSetGreater(Self, s);
end;
///--
function TypedSet.CompareGreaterEqual(s: TypedSet): boolean;
begin
Result := CompareSetGreaterEqual(Self, s);
end;
procedure TypedSet.Print(delim: string);
begin
foreach var x in ht.Keys do
Write(x,delim)
end;
procedure TypedSet.Println(delim: string);
begin
var fst := True;
foreach var x in ht.Keys do
begin
if fst then
begin
fst := False;
Write(x);
end
else Write(delim,x);
end;
Writeln;
end;
// -----------------------------------------------------
// Typed Set functions
// -----------------------------------------------------
[System.Diagnostics.DebuggerStepThrough]
function CreateSet: TypedSet;
begin
Result := new TypedSet();
end;
[System.Diagnostics.DebuggerStepThrough]
function CreateBoundedSet(low, high: object): TypedSet;
begin
Result := new TypedSet(low, high);
end;
[System.Diagnostics.DebuggerStepThrough]
function CreateDiapason(low, high: integer): Diapason;
begin
Result.low := low;
Result.high := high;
end;
//[System.Diagnostics.DebuggerStepThrough]
function CreateObjDiapason(low, high: object): Diapason;
begin
Result.clow := low;
Result.chigh := high;
end;
[System.Diagnostics.DebuggerStepThrough]
function CreateSet(params elems: array of object): TypedSet;
begin
var chars := false;
var strings := false;
var others := false;
foreach var x in elems do
begin
if (x is char) or (x is Diapason) and (Diapason(x).clow is char) then
chars := true
else if x is string then
strings := true
else
begin
others := true;
break
end;
end;
Result := new TypedSet();
if chars and strings and not others then
foreach var x in elems do
if x is char then
Result.IncludeElement(x.ToString)
else if (x is Diapason) and (Diapason(x).clow is char) then
begin
var c1 := char(Diapason(x).clow);
var c2 := char(Diapason(x).chigh);
for var cc := c1 to c2 do
Result.IncludeElement(cc.ToString)
end
else Result.IncludeElement(x)
else
foreach var x in elems do
Result.IncludeElement(x);
end;
[System.Diagnostics.DebuggerStepThrough]
function Subtract(s1, s2: TypedSet): TypedSet;
begin
Result := s1.CloneSet;
var en := s2.ht.GetEnumerator();
while en.MoveNext do
begin
if s1.Contains(en.Key) then
Result.ht.Remove(en.Key);
end;
end;
[System.Diagnostics.DebuggerStepThrough]
procedure Include(var s: TypedSet; el: object);
begin
s.IncludeElement(el);
end;
[System.Diagnostics.DebuggerStepThrough]
procedure Exclude(var s: TypedSet; el: object);
begin
s.ExcludeElement(el);
end;
[System.Diagnostics.DebuggerStepThrough]
function Union(s1, s2: TypedSet): TypedSet;
begin
Result := s1.CloneSet;
var en := s2.ht.GetEnumerator();
while en.MoveNext do
Result.ht[en.Key] := en.Key;
end;
[System.Diagnostics.DebuggerStepThrough]
function Intersect(s1, s2: TypedSet): TypedSet;
var
en: System.Collections.IEnumerator;
begin
Result := new TypedSet();
en := s1.ht.GetEnumerator();
while en.MoveNext do
if s2.Contains((en as IDictionaryEnumerator).Key) then
Result.ht[(en as IDictionaryEnumerator).Key] := (en as IDictionaryEnumerator).Key;
end;
[System.Diagnostics.DebuggerStepThrough]
function InSet(obj: object; s: TypedSet): boolean;
begin
{if obj.GetType().IsEnum then
Result := s.ht[obj] <> nil
else}
Result := (obj <> nil) and s.Contains(obj);
{Result := (obj <> nil) and (s.ht[obj] <> nil);
if not Result and (obj is TypedSet) then
Result := s.Contains(obj as TypedSet);}
//if Result = true then
// Result := s.IsInDiapason(obj);
end;
[System.Diagnostics.DebuggerStepThrough]
function CompareSetEquals(s1, s2: TypedSet): boolean;
var
en: System.Collections.IEnumerator;
equals: boolean := true;
begin
if s1.ht.Count <> s2.ht.Count then
begin
Result := false;
Exit;
end;
en := s1.ht.GetEnumerator();
while en.MoveNext do
begin
var is_in_s1 := s1.Contains((en as IDictionaryEnumerator).Key);
var is_in_s2 := s2.Contains((en as IDictionaryEnumerator).Key);
if is_in_s1 and not is_in_s2 then
begin
equals := false;
break;
end
else if not is_in_s1 and is_in_s2 then
begin
equals := false;
break;
end
end;
if equals <> false then
begin
en := s2.ht.GetEnumerator();
en.Reset();
while en.MoveNext do
begin
var is_in_s1 := s1.Contains((en as IDictionaryEnumerator).Key);
var is_in_s2 := s2.Contains((en as IDictionaryEnumerator).Key);
if is_in_s2 and not is_in_s1 then
begin
equals := false;
break;
end
else if not is_in_s2 and is_in_s1 then
begin
equals := false;
break;
end
end;
end;
Result := equals;
end;
[System.Diagnostics.DebuggerStepThrough]
function CompareSetInEquals(s1, s2: TypedSet): boolean;
begin
Result := not CompareSetEquals(s1, s2);
end;
[System.Diagnostics.DebuggerStepThrough]
function CompareSetLess(s1, s2: TypedSet): boolean;
var
en: System.Collections.IEnumerator;
less: boolean := true;
begin
en := s1.ht.GetEnumerator();
en.Reset();
while en.MoveNext do
begin
if not s2.Contains((en as IDictionaryEnumerator).Key) then
begin
less := false;
break;
end;
end;
if less <> false then
begin
en := s2.ht.GetEnumerator();
en.Reset();
var b: boolean := false;
while en.MoveNext do
begin
if not s1.Contains((en as IDictionaryEnumerator).Key) then
begin
b := true;
break;
end;
end;
less := b;
end;
Result := less;
end;
[System.Diagnostics.DebuggerStepThrough]
function CompareSetGreaterEqual(s1, s2: TypedSet): boolean;
var
en: System.Collections.IEnumerator;
greater: boolean := true;
begin
en := s2.ht.GetEnumerator();
en.Reset();
while en.MoveNext do
begin
if not s1.Contains((en as IDictionaryEnumerator).Key) then
begin
greater := false;
break;
end;
end;
Result := greater;
end;
[System.Diagnostics.DebuggerStepThrough]
function CompareSetLessEqual(s1, s2: TypedSet): boolean;
var
en: System.Collections.IEnumerator;
less: boolean := true;
begin
en := s1.ht.GetEnumerator();
en.Reset();
while en.MoveNext do
begin
if not s2.Contains((en as IDictionaryEnumerator).Key) then
begin
less := false;
break;
end;
end;
Result := less;
end;
[System.Diagnostics.DebuggerStepThrough]
function CompareSetGreater(s1, s2: TypedSet): boolean;
var
greater: boolean := true;
en: System.Collections.IEnumerator;
begin
en := s2.ht.GetEnumerator();
en.Reset();
while en.MoveNext do
begin
if not s1.Contains((en as IDictionaryEnumerator).Key) then
begin
greater := false;
break;
end;
end;
if greater <> false then
begin
en := s1.ht.GetEnumerator();
en.Reset();
var b: boolean := false;
while en.MoveNext do
begin
if not s2.Contains((en as IDictionaryEnumerator).Key) then
begin
b := true;
break;
end;
end;
greater := b;
end;
Result := greater;
end;
// -----------------------------------------------------
// TypedFile
// -----------------------------------------------------
constructor TypedFile.Create(ElementType: System.Type);
begin
Self.ElementType := ElementType;
ElementSize := RuntimeSizeOf(ElementType);
end;
constructor TypedFile.Create(ElementType: System.Type; offs: integer; params offsets: array of integer);
begin
Self.ElementType := ElementType;
ElementSize := RuntimeSizeOf(ElementType);
Self.offsets := offsets;
if offs <> 0 then
begin
ElementSize := ElementSize + offs{*2};
offset := offs{*2};
end;
end;
function TypedFile.ToString := Format('file of {0}', ElementType);
// -----------------------------------------------------
// BinaryFile
// -----------------------------------------------------
function BinaryFile.ToString: string := 'file';
// -----------------------------------------------------
// GCHandlersController
// -----------------------------------------------------
constructor GCHandlersController.Create;
begin
Counters := new Hashtable;
Handlers := new Hashtable;
end;
procedure GCHandlersController.Add(obj: Object);
begin
if obj <> nil then begin
if Counters.Contains(obj) then
Counters[obj] := integer(Counters[obj]) + 1
else begin
Counters.Add(obj, 1);
Handlers.Add(obj, GCHandle.Alloc(obj, GCHandleType.Pinned));
//var ptr := Marshal.AllocHGlobal(Marshal.SizeOf(obj));
//Marshal.StructureToPtr(obj, ptr, false);
//Handlers.Add(obj, ptr);
//GC.KeepAlive(obj);
//var ptr:=IntPtr(pointer(@obj));
//Handlers.Add(obj,new IntPtr(integer(ptr) or 1));
end;
end;
end;
procedure GCHandlersController.Remove(obj: Object);
begin
if obj <> nil then begin
if Counters.Contains(obj) then begin
var Count := integer(Counters[obj]);
if Count > 1 then
Counters[obj] := Count - 1
else begin
Counters.Remove(obj);
GCHandle(Handlers[obj]).Free;
Handlers.Remove(obj);
end;
end else
raise new SystemException('PABCSystem.GCHandleForPointersController not contains object ' + obj.ToString);
end;
end;
function GCHandlersController.GetCounter(obj: Object): integer;
begin
result := 0;
if Counters.Contains(obj) then
result := integer(Counters[obj]);
end;
function GCHandlersController.GetEnumerator: System.Collections.IEnumerator;
begin
result := Counters.Keys.GetEnumerator;
end;
//------------------------------------------------------------------------------
// StructuredObjectToString
//------------------------------------------------------------------------------
// Возвращает переопределенный в последнем потомке ToString или nil если ToString определен в Object
function RedefinedToString(o: object): System.Reflection.MethodInfo;
begin
var t := o.GetType;
var meth: System.Reflection.MethodInfo := nil;
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
break;
t := t.BaseType;
end;
if (t = typeof(Object)) or (t = typeof(System.ValueType)) then
Result := nil
else Result := meth;
end;
function ArrNToString(a: System.Array; indexes: array of integer; i: integer): string; forward;
function StructuredObjectToString(o: Object; n: integer := 0): string;
const
nmax = 100;
nmax1 = 30;
begin
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) + ')';
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);
end
else if o is System.Collections.IEnumerable then
begin
var sb := new StringBuilder();
var g := (o as System.Collections.IEnumerable).GetEnumerator();
var otype := o.GetType;
//var isdictorset := otype.Name.Equals('Dictionary`2') or otype.Name.Equals('SortedDictionary`2') or otype.Name.Equals('HashSet`1') or otype.Name.Equals('SortedSet`1');
var isdictorset := o.GetType.IsGenericType and
((otype.GetGenericTypeDefinition = typeof(Dictionary<,>))
or (otype.GetGenericTypeDefinition = typeof(SortedDictionary<,>))
or (otype.GetGenericTypeDefinition = typeof(HashSet<>))
or (otype.GetGenericTypeDefinition = typeof(SortedSet<>)));
isdictorset := isdictorset or (otype = typeof(TypedSet));
if isdictorset then
sb.Append('{')
else sb.Append('[');
if g.MoveNext() then
begin
sb.Append(StructuredObjectToString(g.Current, n + 1));
var cnt := 1;
while g.MoveNext() and (cnt < nmax) do
begin
sb.Append(',');
sb.Append(StructuredObjectToString(g.Current, n + 1));
cnt += 1;
end;
if cnt >= nmax then
sb.Append(',...');
end;
if isdictorset then
sb.Append('}')
else sb.Append(']');
Result := sb.ToString;
end
else if o.GetType.GetField('NullBasedArray') <> nil then
begin
var f := o.GetType.GetField('NullBasedArray');
Result := StructuredObjectToString(f.GetValue(o));
end
else
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
Result := o.ToString
else
begin
var t := o.GetType;
var sb := new System.Text.StringBuilder();
sb.Append('(');
if n > nmax1 then
sb.Append('....')
else
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
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;
sb.Append(')');
Result := sb.ToString;
end;
end;
end;
function ArrNToString(a: System.Array; indexes: array of integer; i: integer): string;
const
nmax = 100;
begin
var sb := new StringBuilder;
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
begin
indexes[i] := k;
sb.Append(ArrNToString(a, indexes, i + 1));
if (k >= nmax - 1) and (k < a.GetLength(i) - 1) then
begin
sb.Append(',...');
break
end
else if k < a.GetLength(i) - 1 then
sb.Append(',');
end;
sb.Append(']');
end;
Result := sb.ToString;
end;
//------------------------------------------------------------------------------
// Операции для string и char
//------------------------------------------------------------------------------
procedure string.operator+=(var left: string; right: string);
begin
left := left + right;
end;
function string.operator<(left, right: string) := string.CompareOrdinal(left, right) < 0;
function string.operator<=(left, right: string) := string.CompareOrdinal(left, right) <= 0;
function string.operator>(left, right: string) := string.CompareOrdinal(left, right) > 0;
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;
loop n do
sb.Append(str);
Result := sb.ToString;
end;
/// Повторяет строку str n раз
function string.operator*(n: integer; str: string): string;
begin
var sb := new StringBuilder;
loop n do
sb.Append(str);
Result := sb.ToString;
end;
/// Повторяет символ c n раз
function char.operator*(c: char; n: integer): string;
begin
if n <= 0 then
begin
Result := '';
exit;
end;
var sb := new StringBuilder(n, n);
loop n do
sb.Append(c);
Result := sb.ToString;
end;
/// Повторяет символ c n раз
function char.operator*(n: integer; c: char): string;
begin
if n <= 0 then
begin
Result := '';
exit;
end;
var sb := new StringBuilder(n, n);
loop n do
sb.Append(c);
Result := sb.ToString;
end;
/// Добавляет к строке str строковое представление числа n
function string.operator+(str: string; n: integer) := str + n.ToString;
/// Добавляет к строке str строковое представление числа n
function string.operator+(n: integer; str: string) := n.ToString + str;
/// Добавляет к строке str строковое представление числа r
function string.operator+(str: string; r: real) := str + r.ToString(nfi);
/// Добавляет к строке str строковое представление числа r
function string.operator+(r: real; str: string) := r.ToString(nfi) + str;
procedure string.operator+=(var left: string; right: integer);
begin
left := left + right.ToString;
end;
procedure string.operator+=(var left: string; right: real);
begin
left := left + right.ToString(nfi);
end;
procedure string.operator*=(var left: string; n: integer);
begin
var sb := new StringBuilder;
loop n do
sb.Append(left);
left := sb.ToString;
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
//------------------------------------------------------------------------------
/// Объединяет два массива
function operator+<T>(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);
end;
///--
function operator in<T>(x: T; a: array of T): boolean; extensionmethod := a.Contains(x);
function operator*<T>(a: array of T; n: integer): array of T; extensionmethod;
begin
Result := new T[a.Length * n];
for var i := 0 to n - 1 do
a.CopyTo(Result, a.Length * i);
end;
function operator*<T>(n: integer; a: array of T): array of T; extensionmethod := a * n;
//------------------------------------------------------------------------------
// Операции для List<T>
//------------------------------------------------------------------------------
///--
function operator+=<T>(a, b: List<T>): List<T>; extensionmethod;
begin
a.AddRange(b);
Result := a;
end;
///--
function operator+<T>(a, b: List<T>): List<T>; extensionmethod;
begin
Result := new List<T>(a);
Result.AddRange(b);
end;
///--
function operator+=<T>(a: List<T>; x: T): List<T>; extensionmethod;
begin
a.Add(x);
Result := a;
end;
///--
function List<T>.operator in(x: T; Self: List<T>): boolean;
begin
Result := Self.Contains(x);
end;
///--
function operator*<T>(a: List<T>; n: integer): List<T>; extensionmethod;
begin
Result := new List<T>();
for var i := 1 to n do
Result.AddRange(a);
end;
///--
function operator*<T>(n: integer; a: List<T>): List<T>; extensionmethod := a * n;
//------------------------------------------------------------------------------
// Операции для Stack<T>
//------------------------------------------------------------------------------
///--
function operator+=<T>(s: Stack<T>; x: T): Stack<T>; extensionmethod;
begin
s.Push(x);
Result := s;
end;
//------------------------------------------------------------------------------
// Операции для Queue<T>
//------------------------------------------------------------------------------
///--
function operator+=<T>(q: Queue<T>; x: T): Queue<T>; extensionmethod;
begin
q.Enqueue(x);
Result := q;
end;
//------------------------------------------------------------------------------
// Операции для HashSet<T>
//------------------------------------------------------------------------------
///--
function operator in<T>(x: T; Self: HashSet<T>): boolean; extensionmethod := Self.Contains(x);
function operator+=<T>(var Self: HashSet<T>; x: T): HashSet<T>; extensionmethod;
begin
Self.Add(x);
Result := Self;
end;
function operator+=<T>(var Self: HashSet<T>; x: sequence of T): HashSet<T>; extensionmethod;
begin
Self.UnionWith(x);
Result := Self;
end;
function operator-=<T>(var Self: HashSet<T>; x: T): HashSet<T>; extensionmethod;
begin
Self.Remove(x);
Result := Self;
end;
function operator-=<T>(var Self: HashSet<T>; x: sequence of T): HashSet<T>; extensionmethod;
begin
Self.ExceptWith(x);
Result := Self;
end;
function InternalEqual<T>(x,y: HashSet<T>): 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.SetEquals(y);
end;
function operator=<T>(x,y: HashSet<T>): boolean; extensionmethod := InternalEqual(x,y);
function operator<><T>(x,y: HashSet<T>); extensionmethod := not InternalEqual(x,y);
function operator-<T>(x, y: HashSet<T>): HashSet<T>; extensionmethod;
begin
var v := new HashSet<T>(x);
v.ExceptWith(y);
Result := v;
end;
function operator+<T>(x, y: HashSet<T>): HashSet<T>; extensionmethod;
begin
var v := new HashSet<T>(x);
v.UnionWith(y);
Result := v;
end;
function operator+<T>(x: HashSet<T>; y: T): HashSet<T>; extensionmethod;
begin
var v := new HashSet<T>(x);
v.Add(y);
Result := v;
end;
function operator-<T>(x: HashSet<T>; y: T): HashSet<T>; extensionmethod;
begin
var v := new HashSet<T>(x);
v.Remove(y);
Result := v;
end;
function operator*<T>(x,y: HashSet<T>): HashSet<T>; extensionmethod;
begin
var v := new HashSet<T>(x);
v.IntersectWith(y);
Result := v;
end;
function operator< <T>(x, y: HashSet<T>); extensionmethod := x.IsProperSubsetOf(y);
function operator<= <T>(x, y: HashSet<T>); extensionmethod := x.IsSubsetOf(y);
function operator> <T>(x, y: HashSet<T>); extensionmethod := x.IsProperSupersetOf(y);
function operator>= <T>(x, y: HashSet<T>); extensionmethod := x.IsSupersetOf(y);
//------------------------------------------------------------------------------
// Операции для SortedSet<T>
//------------------------------------------------------------------------------
function operator in<T>(x: T; Self: SortedSet<T>): boolean; extensionmethod := Self.Contains(x);
function operator+=<T>(var Self: SortedSet<T>; x: T): SortedSet<T>; extensionmethod;
begin
Self.Add(x);
Result := Self;
end;
function operator+=<T>(var Self: SortedSet<T>; x: sequence of T): SortedSet<T>; extensionmethod;
begin
Self.UnionWith(x);
Result := Self;
end;
function operator-=<T>(var Self: SortedSet<T>; x: T): SortedSet<T>; extensionmethod;
begin
Self.Remove(x);
Result := Self;
end;
function operator-=<T>(var Self: SortedSet<T>; x: sequence of T): SortedSet<T>; extensionmethod;
begin
Self.ExceptWith(x);
Result := Self;
end;
function InternalEqual<T>(x,y: SortedSet<T>): 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.SetEquals(y);
end;
function operator=<T>(x,y: SortedSet<T>): boolean; extensionmethod := InternalEqual(x,y);
function operator<><T>(x, y: SortedSet<T>); extensionmethod := not InternalEqual(x,y);
function operator-<T>(x, y: SortedSet<T>): SortedSet<T>; extensionmethod;
begin
var v := new SortedSet<T>(x);
v.ExceptWith(y);
Result := v;
end;
function operator+<T>(x, y: SortedSet<T>): SortedSet<T>; extensionmethod;
begin
var v := new SortedSet<T>(x);
v.UnionWith(y);
Result := v;
end;
function operator+<T>(x: SortedSet<T>; y: T): SortedSet<T>; extensionmethod;
begin
var v := new SortedSet<T>(x);
v.Add(y);
Result := v;
end;
function operator-<T>(x: SortedSet<T>; y: T): SortedSet<T>; extensionmethod;
begin
var v := new SortedSet<T>(x);
v.Remove(y);
Result := v;
end;
function operator*<T>(x,y: SortedSet<T>): SortedSet<T>; extensionmethod;
begin
var v := new SortedSet<T>(x);
v.IntersectWith(y);
Result := v;
end;
function operator< <T>(x, y: SortedSet<T>); extensionmethod := x.IsProperSubsetOf(y);
function operator<= <T>(x, y: SortedSet<T>); extensionmethod := x.IsSubsetOf(y);
function operator> <T>(x, y: SortedSet<T>); extensionmethod := x.IsProperSupersetOf(y);
function operator>= <T>(x, y: SortedSet<T>): boolean; extensionmethod := x.IsSupersetOf(y);
//------------------------------------------------------------------------------
// Операции для Dictionary<K,V>, SortedDictionary<K,V>, SortedList<K,V>
//------------------------------------------------------------------------------
function Dictionary<K, V>.operator in(key: K; d: Dictionary<K, V>): boolean;
begin
Result := d.ContainsKey(key);
end;
function SortedDictionary<K, V>.operator in(key: K; d: SortedDictionary<K, V>): boolean;
begin
Result := d.ContainsKey(key);
end;
function SortedList<K, V>.operator in(key: K; d: SortedList<K, V>): boolean;
begin
Result := d.ContainsKey(key);
end;
//------------------------------------------------------------------------------
// **
//------------------------------------------------------------------------------
function operator**(x: real; n: integer): real; extensionmethod := Power(x, n);
function operator**(x: single; 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(p)/q;
function BigInteger.operator/(q: real; p: BigInteger) := q/real(p);
function BigInteger.operator>(p: BigInteger; q: integer) := p > BigInteger.Create(q);
function BigInteger.operator>(p: integer; q: BigInteger) := BigInteger.Create(p) > q;
function BigInteger.operator<(p: BigInteger; q: integer) := p < BigInteger.Create(q);
function BigInteger.operator<(p: integer; q: BigInteger) := BigInteger.Create(p) < q;
function BigInteger.operator>=(p: BigInteger; q: integer) := p >= BigInteger.Create(q);
function BigInteger.operator>=(p: integer; q: BigInteger) := BigInteger.Create(p) >= q;
function BigInteger.operator<=(p: BigInteger; q: integer) := p <= BigInteger.Create(q);
function BigInteger.operator<=(p: integer; q: BigInteger) := BigInteger.Create(p) <= q;
function BigInteger.operator=(p: BigInteger; q: integer) := p = BigInteger.Create(q);
function BigInteger.operator=(p: integer; q: BigInteger) := BigInteger.Create(p) = q;
function BigInteger.operator<>(p: BigInteger; q: integer) := p <> BigInteger.Create(q);
function BigInteger.operator<>(p: integer; q: BigInteger) := BigInteger.Create(p) <> q;
procedure BigInteger.operator+=(var p: BigInteger; q: BigInteger) := p := p + q;
procedure BigInteger.operator*=(var p: BigInteger; q: BigInteger) := p := p * q;
procedure BigInteger.operator-=(var p: BigInteger; q: BigInteger) := p := p - q;
function BigInteger.operator div(p: BigInteger; q: integer) := BigInteger.Divide(p,q);
function BigInteger.operator mod(p: BigInteger; q: integer) := BigInteger.Remainder(p,q);
//function BigInteger.operator div(p,q: BigInteger) := BigInteger.Divide(p,q);
//function BigInteger.operator mod(p,q: BigInteger) := BigInteger.Remainder(p,q);
function BigInteger.operator-(p: BigInteger) := BigInteger.Negate(p);
//------------------------------------------------------------------------------
// Операции для Complex
//------------------------------------------------------------------------------
function operator-(Self: Complex): Complex; extensionmethod := Complex.Negate(Self);
function operator implicit(c: (real,real)): Complex; extensionmethod := Cplx(c[0],c[1]);
function operator implicit(c: (real,integer)): Complex; extensionmethod := Cplx(c[0],c[1]);
function operator implicit(c: (integer,real)): Complex; extensionmethod := Cplx(c[0],c[1]);
function operator implicit(c: (integer,integer)): Complex; extensionmethod := Cplx(c[0],c[1]);
procedure operator+=(var c: Complex; x: Complex); extensionmethod := c := c + x;
procedure operator*=(var c: Complex; x: Complex); extensionmethod := c := c * x;
procedure operator-=(var c: Complex; x: Complex); extensionmethod := c := c - x;
procedure operator/=(var c: Complex; x: Complex); extensionmethod := c := c / x;
//------------------------------------------------------------------------------
// Операции для sequence of T
//------------------------------------------------------------------------------
///--
function operator+<T>(a, b: sequence of T): sequence of T; extensionmethod;
begin
Result := a.Concat(b);
end;
///--
function operator+<T>(a: sequence of T; b: T): sequence of T; extensionmethod;
begin
Result := a.Concat(new T[1](b));
end;
///--
function operator+<T>(b: T; a: sequence of T): sequence of T; extensionmethod;
begin
Result := new T[1](b);
Result := Result.Concat(a);
end;
{function operator*<T>(a: sequence of T; n: integer): sequence of T; extensionmethod;
begin
Result := System.Linq.Enumerable.Empty&<T>();
loop n do
Result := Result.Concat(a);
end;
function operator*<T>(n: integer; a: sequence of T): sequence of T; extensionmethod;
begin
Result := a * n;
end;}
///--
function operator in<T>(x: T; Self: sequence of T): boolean; extensionmethod;
begin
Result := Self.Contains(x);
end;
// -----------------------------------------------------------------------------
// Функции для последовательностей и динамических массивов
// -----------------------------------------------------------------------------
function Range(a, b: integer): sequence of integer;
begin
if b < a then
Result := System.Linq.Enumerable.Empty&<integer>
else Result := System.Linq.Enumerable.Range(a, b - a + 1);
end;
function Range(c1, c2: char): sequence of char;
begin
Result := Range(integer(c1), integer(c2)).Select(x -> Chr(x));
end;
function Range(a, b: real; n: integer): sequence of real;
begin
if n = 0 then
raise new System.ArgumentException('n=0');
if n < 0 then
raise new System.ArgumentException('n<0');
var r := a;
var h := (b - a) / n;
for var i := 0 to n do
begin
yield r;
r += h
end;
end;
function PartitionPoints(a, b: real; n: integer): sequence of real;
begin
Result := Range(a, b, n)
end;
type
ArithmSeq = auto class
a, step: integer;
function f(x: integer): integer;
begin
Result := x * step + a;
end;
end;
function Range(a, b, step: integer): sequence of integer;
begin
if step = 0 then
raise new System.ArgumentException('step=0');
if (step > 0) and (b < a) or (step < 0) and (b > a) then
begin
Result := System.Linq.Enumerable.Empty&<integer>;
exit;
end;
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);
Result := System.Linq.Enumerable.Range(0, n).Select(ar.f);
end;
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);
end;
function ArrRandomInteger(n: integer; a: integer; b: integer): array of integer;
begin
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;
end;
function SeqRandom(n: integer; a: integer; b: integer): sequence of integer;
begin
loop n do
yield Random(a, b)
end;
function SeqRandomInteger(n: integer; a: integer; b: integer): sequence of integer;
begin
loop n do
yield Random(a, b)
end;
function SeqRandomReal(n: integer; a: real; b: real): sequence of real;
begin
loop n do
yield Random() * (b - a) + a
end;
function Arr<T>(params a: array of T): array of T;
begin
Result := new T[a.Length];
System.Array.Copy(a, Result, a.Length);
end;
function Arr<T>(a: sequence of T): array of T;
begin
Result := a.ToArray;
end;
function Seq<T>(params a: array of T): sequence of T;
begin
var res := new T[a.Length];
System.Array.Copy(a, res, a.Length);
Result := res;
end;
/// Возвращает бесконечную рекуррентную последовательность элементов, задаваемую начальным элементом first и функцией next
function Iterate<T>(first: T; next: T->T): sequence of T;
begin
yield first;
while True do
begin
first := next(first);
yield first;
end;
end;
/// Возвращает бесконечную рекуррентную последовательность элементов, задаваемую начальными элементами first, second и функцией next
function Iterate<T>(first, second: T; next: (T,T)->T): sequence of T;
begin
yield first;
yield second;
while True do
begin
var nxt := next(first, second);
yield nxt;
first := second;
second := nxt;
end;
end;
function SeqGen<T>(count: integer; first: T; next: T->T): sequence of T;
begin
if count < 1 then
raise new System.ArgumentOutOfRangeException('count', count, GetTranslation(PARAMETER_MUST_BE_GREATER_0));
Result := Iterate(first, next).Take(count);
end;
function SeqGen<T>(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_MUST_BE_GREATER_0));
Result := Iterate(first, second, next).Take(count);
end;
function SeqWhile<T>(first: T; next: T->T; pred: T->boolean): sequence of T;
begin
Result := Iterate(first, next).TakeWhile(pred);
end;
function SeqWhile<T>(first, second: T; next: (T,T) ->T; pred: T->boolean): sequence of T;
begin
Result := Iterate(first, second, next).TakeWhile(pred);
end;
function ArrGen<T>(count: integer; first: T; next: T->T): array of T;
begin
if count < 1 then
raise new System.ArgumentOutOfRangeException('count', count, GetTranslation(PARAMETER_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]);
Result := a;
end;
function ArrGen<T>(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_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]);
Result := a;
end;
{function ListWhile<T>(first: T; next: Func<T,T>; pred: Predicate<T>): List<T>;
begin
var a := new List<T>;
var x := first;
while pred(x) do
begin
a.Add(x);
x := next(x);
end;
Result := a;
end;
function ListWhile<T>(first,second: T; next: Func2<T,T,T>; pred: Predicate<T>): List<T>;
begin
var a := new List<T>;
var x := first;
var y := second;
while pred(x) do
begin
a.Add(x);
var z := next(x,y);
x := y;
y := z;
end;
Result := a;
end;}
function ArrFill<T>(count: integer; x: T): array of T;
begin
Result := new T[count];
for var i := 0 to Result.Length - 1 do
Result[i] := x;
end;
function ArrGen<T>(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);
end;
function ArrGen<T>(count: integer; gen: integer->T): array of T;
begin
Result := new T[count];
for var i := 0 to Result.Length - 1 do
Result[i] := gen(i);
end;
function SeqFill<T>(count: integer; x: T): sequence of T;
begin
Result := System.Linq.Enumerable.Repeat(x, count);
end;
function SeqGen<T>(count: integer; f: integer->T; from: integer): sequence of T;
begin
Result := Range(from, count + from - 1).Select(f)
end;
function SeqGen<T>(count: integer; f: integer->T): sequence of T;
begin
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
Result[i] := ReadInteger;
end;
function ReadArrInt64(n: integer): array of int64;
begin
Result := new int64[n];
for var i := 0 to Result.Length - 1 do
Result[i] := ReadInt64;
end;
function ReadArrInteger(prompt: string; n: integer): array of integer;
begin
Print(prompt);
Result := ReadArrInteger(n);
end;
function ReadArrReal(n: integer): array of real;
begin
Result := new real[n];
for var i := 0 to Result.Length - 1 do
Result[i] := ReadReal;
end;
function ReadArrReal(prompt: string; n: integer): array of real;
begin
Print(prompt);
Result := ReadArrReal(n);
end;
function ReadArrString(n: integer): array of string;
begin
Result := new string[n];
for var i := 0 to Result.Length - 1 do
Result[i] := ReadString;
end;
function ReadArrString(prompt: string; n: integer): array of string;
begin
Print(prompt);
Result := ReadArrString(n);
end;
///--
function ReadArrInteger: array of integer;
begin
Result := nil;
raise new System.ArgumentException('Функцию ReadArrInteger запрещено вызывать без параметров')
end;
///--
function ReadArrReal: array of real;
begin
Result := nil;
raise new System.ArgumentException('Функцию ReadArrReal запрещено вызывать без параметров')
end;
///--
function ReadArrString: array of string;
begin
Result := nil;
raise new System.ArgumentException('Функцию ReadArrString запрещено вызывать без параметров')
end;
function ReadSeqInteger(n: integer): sequence of integer;
begin
Result := Range(1, n).Select(i -> ReadInteger());
end;
function ReadSeqInteger(prompt: string; n: integer): sequence of integer;
begin
Print(prompt);
Result := ReadSeqInteger(n);
end;
function ReadSeqReal(n: integer): sequence of real;
begin
Result := Range(1, n).Select(i -> ReadReal());
end;
function ReadSeqReal(prompt: string; n: integer): sequence of real;
begin
Print(prompt);
Result := ReadSeqReal(n);
end;
function ReadSeqString(n: integer): sequence of string;
begin
Result := Range(1, n).Select(i -> ReadString());
end;
function ReadSeqString(prompt: string; n: integer): sequence of string;
begin
Print(prompt);
Result := ReadSeqString(n);
end;
function ReadSeqIntegerWhile(cond: integer->boolean): sequence of integer;
begin
while True do
begin
var x := ReadInteger();
if not cond(x) then
break;
yield x;
end;
end;
function ReadSeqRealWhile(cond: real->boolean): sequence of real;
begin
while True do
begin
var x := ReadReal();
if not cond(x) then
break;
yield x;
end;
end;
function ReadSeqStringWhile(cond: string->boolean): sequence of string;
begin
while True do
begin
var x := ReadString();
if not cond(x) then
break;
yield x;
end;
end;
function ReadSeqIntegerWhile(prompt: string; cond: integer->boolean): sequence of integer;
begin
Print(prompt);
Result := ReadSeqIntegerWhile(cond);
end;
function ReadSeqRealWhile(prompt: string; cond: real->boolean): sequence of real;
begin
Print(prompt);
Result := ReadSeqRealWhile(cond);
end;
function ReadSeqStringWhile(prompt: string; cond: string->boolean): sequence of string;
begin
Print(prompt);
Result := ReadSeqStringWhile(cond);
end;
// -----------------------------------------------------------------------------
// Функции Rec для создания кортежей
// -----------------------------------------------------------------------------
function Rec<T1, T2>(x1: T1; x2: T2) := Tuple.Create(x1, x2);
function Rec<T1, T2, T3>(x1: T1; x2: T2; x3: T3) := Tuple.Create(x1, x2, x3);
function Rec<T1, T2, T3, T4>(x1: T1; x2: T2; x3: T3; x4: T4) := Tuple.Create(x1, x2, x3, x4);
function Rec<T1, T2, T3, T4, T5>(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5) := Tuple.Create(x1, x2, x3, x4, x5);
function Rec<T1, T2, T3, T4, T5, T6>(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5; x6: T6) := Tuple.Create(x1, x2, x3, x4, x5, x6);
function Rec<T1, T2, T3, T4, T5, T6, T7>(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
// -----------------------------------------------------------------------------
function Lst<T>(params a: array of T): List<T>;
begin
Result := new List<T>(a);
end;
function Lst<T>(a: sequence of T): List<T>;
begin
Result := new List<T>(a);
end;
function LLst<T>(params a: array of T): LinkedList<T>;
begin
Result := new LinkedList<T>(a);
end;
function LLst<T>(a: sequence of T): LinkedList<T>;
begin
Result := new LinkedList<T>(a);
end;
function HSet<T>(params a: array of T): HashSet<T>;
begin
Result := new HashSet<T>(a);
end;
function SSet<T>(params a: array of T): SortedSet<T>;
begin
Result := new SortedSet<T>(a);
end;
function HSet<T>(a: sequence of T): HashSet<T>;
begin
Result := new HashSet<T>(a);
end;
function SSet<T>(a: sequence of T): SortedSet<T>;
begin
Result := new SortedSet<T>(a);
end;
function Dict<TKey, TVal>(params pairs: array of KeyValuePair<TKey, TVal>): Dictionary<TKey, TVal>;
begin
Result := new Dictionary<TKey, TVal>();
for var i := 0 to pairs.Length - 1 do
Result.Add(pairs[i].Key, pairs[i].Value);
end;
function Dict<TKey, TVal>(params pairs: array of (TKey, TVal)): Dictionary<TKey, TVal>;
begin
Result := new Dictionary<TKey, TVal>();
for var i := 0 to pairs.Length - 1 do
Result.Add(pairs[i][0], pairs[i][1]);
end;
function KV<TKey, TVal>(key: TKey; value: TVal): KeyValuePair<TKey, TVal>;
begin
Result := new KeyValuePair<TKey, TVal>(key, value);
end;
function __TypeCheckAndAssignForIsMatch<T>(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;
function __WildCardsTupleEqual<T1, T2, T3, T4>(
first: Tuple<T1, T2>;
second: Tuple<T3, T4>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
end;
end;
end;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6>(
first: Tuple<T1, T2, T3>;
second: Tuple<T4, T5, T6>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
2: Result := Result and first.Item3.Equals(second.Item3);
end;
end;
end;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8>(
first: Tuple<T1, T2, T3, T4>;
second: Tuple<T5, T6, T7, T8>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
2: Result := Result and first.Item3.Equals(second.Item3);
3: Result := Result and first.Item4.Equals(second.Item4);
end;
end;
end;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
first: Tuple<T1, T2, T3, T4, T5>;
second: Tuple<T6, T7, T8, T9, T10>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
2: Result := Result and first.Item3.Equals(second.Item3);
3: Result := Result and first.Item4.Equals(second.Item4);
4: Result := Result and first.Item5.Equals(second.Item5);
end;
end;
end;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(
first: Tuple<T1, T2, T3, T4, T5, T6>;
second: Tuple<T7, T8, T9, T10, T11, T12>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
2: Result := Result and first.Item3.Equals(second.Item3);
3: Result := Result and first.Item4.Equals(second.Item4);
4: Result := Result and first.Item5.Equals(second.Item5);
5: Result := Result and first.Item6.Equals(second.Item6);
end;
end;
end;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(
first: Tuple<T1, T2, T3, T4, T5, T6, T7>;
second: Tuple<T8, T9, T10, T11, T12, T13, T14>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
2: Result := Result and first.Item3.Equals(second.Item3);
3: Result := Result and first.Item4.Equals(second.Item4);
4: Result := Result and first.Item5.Equals(second.Item5);
5: Result := Result and first.Item6.Equals(second.Item6);
6: Result := Result and first.Item7.Equals(second.Item7);
end;
end;
end;
///--
procedure Deconstruct<T>(self: T; var res: T); extensionmethod;
begin
res := self;
end;
// -----------------------------------------------------------------------------
// ReadLexem
// -----------------------------------------------------------------------------
{function ReadLexem: string;
begin
var c: char;
repeat
c := CurrentIOSystem.read_symbol;
until not char.IsWhiteSpace(c);
var sb := new System.Text.StringBuilder;
repeat
sb.Append(c);
c := char(CurrentIOSystem.peek);
if char.IsWhiteSpace(c) or (c = char(-1)) then // char(-1) - Ctrl-Z во входном потоке
break;
c := CurrentIOSystem.read_symbol;
until False; // accumulate nonspaces
Result := sb.ToString;
end;}
function ReadLexem(f: Text): string;
begin
if f.fi = nil then
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));
var i: integer;
repeat
i := f.sr.Read();
until not char.IsWhiteSpace(char(i)); // pass spaces
if i=-1 then
raise new System.IO.IOException(GetTranslation(READ_LEXEM_AFTER_END_OF_TEXT_FILE));
var c := char(i);
var sb := System.Text.StringBuilder.Create;
repeat
sb.Append(c);
i := f.sr.Peek();
if i = -1 then
break;
c := char(i);
if char.IsWhiteSpace(c) then
break;
f.sr.Read();
until False; // accumulate nonspaces
Result := sb.ToString;
end;
// -----------------------------------------------------
// IOStandardSystem: implementation
// -----------------------------------------------------
// размер буфера. Определен эмпирически
const
buflen = 256;
constructor IOStandardSystem.Create;
begin
tr := Console.In;
buf := new char[buflen];
end;
procedure IOStandardSystem.ReadNextBuf;
begin
realbuflen := tr.ReadBlock(buf, 0, buflen);
if realbuflen < buflen then
buf[realbuflen] := char(-1);
pos := 0;
end;
const
m = char(-1);
var
_IsPipedRedirectedQuery := False;
_IsPipedRedirected := False;
function IsInputPipedOrRedirectedFromFile: boolean;
begin
if _IsPipedRedirectedQuery then
Result := _IsPipedRedirected
else
begin
_IsPipedRedirectedQuery := True;
var pi := typeof(Console).GetProperty('IsInputRedirected');
if pi = nil then
begin
_IsPipedRedirected := False; // просто работаем без буфера на старых системах
Result := _IsPipedRedirected;
end
else
begin
var IsInputRedirected := boolean(pi?.GetValue(nil,nil));
_IsPipedRedirected := IsInputRedirected {Console.IsInputRedirected} and (CurrentIOSystem.GetType = typeof(IOStandardSystem));
Result := _IsPipedRedirected;
end;
end;
end;
function IOStandardSystem.peek: integer;// +
begin
if IsInputPipedOrRedirectedFromFile then
begin// новый код
if pos >= realbuflen then
ReadNextBuf;
Result := integer(buf[pos]);
end
else // старый код
begin
if not console_alloc then
AllocConsole;
// SSM 29.11.14
if state = 1 then // в sym - символ, считанный предыдущим Peek
Result := sym
else // в sym ничего нет
begin
state := 1;
sym := Console.Read(); // считываение в буфер из одного символа
Result := sym;
end;
end;
end;
function IOStandardSystem.read_symbol: char;// +
begin
if IsInputPipedOrRedirectedFromFile then
begin// новый код
if pos >= realbuflen then
ReadNextBuf;
Result := buf[pos];
if Result <> m then
pos += 1;
end
else // старый код
begin
if not console_alloc then
AllocConsole;
// SSM 29.11.14
if state = 1 then // в sym - символ, считанный предыдущим Peek
begin
state := 0;
Result := char(sym);
sym := -1;
end
else // в sym ничего нет
Result := char(Console.Read());
exit;
end;
end;
function IOStandardSystem.ReadLine: string;// +
begin
{ReadNextBuf;
while realbuflen>0 do
begin
sb.Append(buf,0,realbuflen);
ReadNextBuf;
end;}
if IsInputPipedOrRedirectedFromFile then
begin// новый код
{var sb := new StringBuilder(10); // старый новый код
var c: char;
repeat
if pos >= realbuflen then
ReadNextBuf;
c := buf[pos];
if c = char(-1) then
break;
pos += 1;
if c = #13 then
break;
if c = #10 then
break;
sb.Append(c);
until False;
if c = #13 then
begin
if peek = 10 then
read_symbol;
end;
Result := sb.ToString;}
var sb := new StringBuilder(10); // новый новый код
var c: char;
repeat
if pos >= realbuflen then
break;
c := buf[pos];
if c = char(-1) then
break;
pos += 1;
if c = #13 then
break;
if c = #10 then
break;
sb.Append(c);
until False;
if pos >= realbuflen then // Если дочитали до конца буфера, то вернуть sb.ToString + tr.ReadLine
begin
Result := sb.ToString + tr.ReadLine;
ReadNextBuf;
end
else // Если мы не дочитали до конца буфера, то просто вернуть sb.ToString
begin
Result := sb.ToString;
if c = #13 then
begin
if peek = 10 then
read_symbol;
end;
end;
end
else // старый код
begin
if not console_alloc then
AllocConsole;
if state = 1 then
begin
state := 0;
Result := char(sym) + Console.ReadLine;
sym := -1;
end
else
Result := Console.ReadLine;
end;
end;
function ReadLexem: string;
begin
if input.sr <> nil then
Result := ReadLexem(input)
else Result := CurrentIOSystem.ReadLexem;
end;
function IOStandardSystem.ReadLexem: string;// +
begin
if IsInputPipedOrRedirectedFromFile then
begin// новый код
var c: char;
repeat
c := read_symbol;
until (c <> ' ') and (c <> #10) and (c <> #13);
if c = char(-1) then
raise new System.IO.IOException(GetTranslation(READ_LEXEM_AFTER_END_OF_INPUT_STREAM));
var sb := new StringBuilder;
repeat
sb.Append(c);
if pos >= realbuflen then
ReadNextBuf;
c := buf[pos]; //c := read_symbol;
if c = ' ' then
break;
if c = #10 then
break;
if c = #13 then
break;
if c = char(-1) then
break;
pos += 1;
until False;
Result := sb.ToString;
end
else // старый код
begin
var c: char;
repeat
c := read_symbol;
until not char.IsWhiteSpace(c);
var sb := new System.Text.StringBuilder;
repeat
sb.Append(c);
c := char(peek);
if char.IsWhiteSpace(c) or (c = char(-1)) then // char(-1) - Ctrl-Z во входном потоке
break;
c := read_symbol;
until False; // accumulate nonspaces
Result := sb.ToString;
end;
end;
function ErrorStringFromResource(s: string): string;
begin
var _rm := new System.Resources.ResourceManager('mscorlib', typeof(object).Assembly);
Result := _rm.GetString(s);
end;
procedure IOStandardSystem.read(var x: integer);// +
begin
if IsInputPipedOrRedirectedFromFile then
begin// новый код
var c: char;
repeat
c := read_symbol;
until (c <> ' ') and (c <> #10) and (c <> #13);
if c = char(-1) then
raise new System.IO.IOException(GetTranslation(READ_LEXEM_AFTER_END_OF_INPUT_STREAM));
var sign := 0;
if c = '-' then
begin
sign := -1;
c := read_symbol;
end
else if c = '+' then
begin
sign := 1;
c := read_symbol;
end;
if c = char(-1) then
raise new System.IO.IOException(GetTranslation(READ_LEXEM_AFTER_END_OF_INPUT_STREAM));
if (c < #48) or (c > #57) then
raise new System.FormatException(ErrorStringFromResource('Format_InvalidString') + ' ' + Ord(c));
x := integer(c) - 48;
repeat
if pos >= realbuflen then
ReadNextBuf;
c := buf[pos]; //c := read_symbol;
if c = ' ' then
break;
if c = #10 then
break;
if c = #13 then
break;
if c = char(-1) then
break;
if c > #57 then
raise new System.FormatException(ErrorStringFromResource('Format_InvalidString') + ' ' + Ord(c));
if c < #48 then
raise new System.FormatException(ErrorStringFromResource('Format_InvalidString') + ' ' + Ord(c));
if x > 214748364 then
raise new System.OverflowException(ErrorStringFromResource('Overflow_Int32'));
x := x * 10 + (integer(c) - 48);
pos += 1;
until False;
if x < 0 then
if (x = -2147483648) and (sign = -1) then
exit
else raise new System.OverflowException(ErrorStringFromResource('Overflow_Int32'));
if sign = -1 then
x := -x;
end
else // старый код
begin
x := StrToInt(ReadLexem);
end;
end;
procedure IOStandardSystem.read(var x: real);
begin
x := Convert.ToDouble(ReadLexem, nfi);
end;
procedure IOStandardSystem.read(var x: char);
begin
x := read_symbol;
end;
{procedure IOStandardSystem.read(var x: string);
begin
var sb := new System.Text.StringBuilder;
var c := read_symbol;
while c <> #13 do
begin
sb.Append(c);
c := read_symbol;
end;
x := sb.ToString;
end;}
procedure IOStandardSystem.read(var x: string);
begin
var sb := new StringBuilder;
// SSM 8.04.10
var c := char(peek()); // первый раз может быть char(-1) - это значит, что в потоке ввода ничего нет, тогда мы читаем символ
while (c <> #13) and (c <> #10) do
begin
c := read_symbol;
if (c <> #13) and (c <> #10) then // SSM 13.12.13
sb.Append(c);
c := char(peek);
end;
x := sb.ToString;
end;
procedure IOStandardSystem.read(var x: byte);
begin
x := Convert.ToByte(ReadLexem);
end;
procedure IOStandardSystem.read(var x: shortint);
begin
x := Convert.ToSByte(ReadLexem);
end;
procedure IOStandardSystem.read(var x: smallint);
begin
x := Convert.ToInt16(ReadLexem);
end;
procedure IOStandardSystem.read(var x: word);
begin
x := Convert.ToUInt16(ReadLexem);
end;
procedure IOStandardSystem.read(var x: longword);
begin
x := Convert.ToUInt32(ReadLexem);
end;
procedure IOStandardSystem.read(var x: int64);
begin
x := Convert.ToInt64(ReadLexem);
end;
procedure IOStandardSystem.read(var x: uint64);
begin
x := Convert.ToUInt64(ReadLexem);
end;
procedure IOStandardSystem.read(var x: single);
begin
x := Convert.ToSingle(ReadLexem, nfi);
end;
procedure IOStandardSystem.read(var x: boolean);
begin
var s := ReadLexem.ToLower;
if s = 'true' then
x := True
else if s = 'false' then
x := False
else raise new System.FormatException('Входная строка имела неверный формат');
end;
procedure IOStandardSystem.read(var x: BigInteger);
begin
x := Biginteger.Parse(ReadLexem)
end;
procedure IOStandardSystem.readln;
begin
// 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;
{function IOStandardSystem.ReadLine: string;
begin
// Надо учесть sym
if not console_alloc then
AllocConsole;
if state = 1 then
begin
state := 0;
Result := char(sym) + Console.ReadLine;
sym := -1;
end
else
Result := Console.ReadLine;
end;}
procedure IOStandardSystem.write(obj: object);
begin
if not console_alloc then
AllocConsole;
Console.Write(StructuredObjectToString(obj));
end;
procedure IOStandardSystem.write(p: pointer);
begin
Write(PointerToString(p));
end;
procedure IOStandardSystem.writeln;
begin
if not console_alloc then
AllocConsole;
Console.WriteLine;
System.Diagnostics.Debug.WriteLine('');
end;
function _ObjectToString(o: object): string;
begin
Result := StructuredObjectToString(o);
end;
// -----------------------------------------------------
// Read - Readln
// -----------------------------------------------------
procedure Read;
begin
end;
procedure Readln;
begin
CurrentIOSystem.readln
end;
procedure Read(var x: integer);
begin
CurrentIOSystem.read(x)
end;
procedure Read(var x: real);
begin
CurrentIOSystem.read(x)
end;
procedure Read(var x: char);
begin
CurrentIOSystem.read(x)
end;
procedure Read(var x: string);
begin
CurrentIOSystem.read(x)
end;
procedure Read(var x: byte);
begin
CurrentIOSystem.read(x)
end;
procedure Read(var x: shortint);
begin
CurrentIOSystem.read(x)
end;
procedure Read(var x: smallint);
begin
CurrentIOSystem.read(x)
end;
procedure Read(var x: word);
begin
CurrentIOSystem.read(x)
end;
procedure Read(var x: longword);
begin
CurrentIOSystem.read(x)
end;
procedure Read(var x: int64);
begin
CurrentIOSystem.read(x)
end;
procedure Read(var x: uint64);
begin
CurrentIOSystem.read(x)
end;
procedure Read(var x: single);
begin
CurrentIOSystem.read(x)
end;
procedure Read(var x: boolean);
begin
CurrentIOSystem.read(x)
end;
procedure Read(var x: BigInteger);
begin
CurrentIOSystem.read(x)
end;
function TryRead(var x: integer): boolean;
begin
Result := True;
try
Read(x)
except
Result := False;
end
end;
function TryRead(var x: BigInteger): 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
Read(Result);
end;
function ReadInt64: int64;
begin
Read(Result);
end;
function ReadReal: real;
begin
Read(Result);
end;
function ReadChar: char;
begin
Read(Result);
end;
function ReadString: string;
begin
Result := CurrentIOSystem.ReadLine;
end;
function ReadBoolean: boolean;
begin
Read(Result);
end;
function ReadBigInteger: BigInteger;
begin
Read(Result);
end;
function ReadlnInteger: integer;
begin
Result := ReadInteger;
Readln();
end;
function ReadlnInt64: int64;
begin
Result := ReadInt64;
Readln();
end;
function ReadlnReal: real;
begin
Result := ReadReal;
Readln();
end;
function ReadlnChar: char;
begin
Result := ReadChar;
Readln();
end;
function ReadlnString: string;
begin
Result := CurrentIOSystem.ReadLine;
end;
function ReadlnBoolean: boolean;
begin
Result := ReadBoolean;
Readln();
end;
function ReadlnBigInteger: BigInteger;
begin
Result := ReadBigInteger;
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 ReadInteger4 := (ReadInteger, ReadInteger, ReadInteger, ReadInteger);
function ReadReal4 := (ReadReal, ReadReal, ReadReal, ReadReal);
function ReadChar4 := (ReadChar, ReadChar, ReadChar, ReadChar);
function ReadString4 := (ReadString, ReadString, ReadString, ReadString);
function ReadlnInteger4 := (ReadInteger, ReadInteger, ReadInteger, ReadlnInteger);
function ReadlnReal4 := (ReadReal, ReadReal, ReadReal, ReadlnReal);
function ReadlnChar4 := (ReadChar, ReadChar, ReadChar, ReadlnChar);
function ReadlnString4 := (ReadString, 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);
function ReadInteger4(prompt: string) := (ReadInteger(prompt), ReadInteger, ReadInteger, ReadInteger);
function ReadReal4(prompt: string) := (ReadReal(prompt), ReadReal, ReadReal, ReadReal);
function ReadChar4(prompt: string) := (ReadChar(prompt), ReadChar, ReadChar, ReadChar);
function ReadString4(prompt: string) := (ReadString(prompt), ReadString, ReadString, ReadString);
function ReadlnInteger4(prompt: string) := (ReadInteger(prompt), ReadInteger, ReadInteger, ReadlnInteger);
function ReadlnReal4(prompt: string) := (ReadReal(prompt), ReadReal, ReadReal, ReadlnReal);
function ReadlnChar4(prompt: string) := (ReadChar(prompt), ReadChar, ReadChar, ReadlnChar);
function ReadlnString4(prompt: string) := (ReadString(prompt), ReadString, ReadString, ReadlnString);
// Read with prompt
function ReadInteger(prompt: string): integer;
begin
Print(prompt);
Result := ReadInteger;
end;
function ReadInt64(prompt: string): int64;
begin
Print(prompt);
Result := ReadInt64;
end;
function ReadReal(prompt: string): real;
begin
Print(prompt);
Result := ReadReal;
end;
function ReadChar(prompt: string): char;
begin
Print(prompt);
Result := ReadChar;
end;
function ReadString(prompt: string): string;
begin
Print(prompt);
Result := ReadString;
end;
function ReadBoolean(prompt: string): boolean;
begin
Print(prompt);
Result := ReadBoolean;
end;
function ReadlnInteger(prompt: string): integer;
begin
Print(prompt);
Result := ReadlnInteger;
end;
function ReadlnInt64(prompt: string): int64;
begin
Print(prompt);
Result := ReadlnInt64;
end;
function ReadlnReal(prompt: string): real;
begin
Print(prompt);
Result := ReadlnReal;
end;
function ReadlnChar(prompt: string): char;
begin
Print(prompt);
Result := ReadlnChar;
end;
function ReadlnString(prompt: string): string;
begin
Print(prompt);
Result := ReadlnString;
end;
function ReadlnBoolean(prompt: string): boolean;
begin
Print(prompt);
Result := ReadlnBoolean;
end;
procedure ReadShortStringFromFile(f: Text; var s: string; n: integer);
begin
//x := f.sr.ReadLine;//если конец файла то вернет nil
//Нельзя эти пользоваться т.к. считывает и конец строки
var i := 1;
var sb := new System.Text.StringBuilder;
repeat
if f.sr.EndOfStream then
break;
if f.sr.Peek = 13 then
break;
if f.sr.Peek = 10 then
break;
if i > n then break;
sb.Append(Convert.ToChar(f.sr.Read));
i := i + 1;
until False;
s := sb.ToString; {}
if s = nil then
s := string.Empty;
if s.Length > n then s := s.Substring(0, n);
end;
procedure ReadShortString(var s: string; n: integer);// Снова сделал peek. В прошлый раз была ошибка
begin
// SSM 30/01/20 - закомментировал это, поскольку мы перешли на буфер, и read_symbol и peek сами переключают потоки при Assign(input,...) и считывают из буфера
{if (input.fi <> nil) and (input.sr <> nil) then
begin
ReadShortStringFromFile(input, s, n);
exit;
end;}
{ var sb := new System.Text.StringBuilder;
var c := CurrentIOSystem.read_symbol;
while c <> #13 do
begin
sb.Append(c);
c := CurrentIOSystem.read_symbol;
end;
s := sb.ToString;
if s.Length > n then s := s.Substring(0, n);
}
// SSM 8.04.10
var sb := new System.Text.StringBuilder;
var c := char(CurrentIOSystem.peek());
var i := 0;
while (c <> #13) and (c <> #10) and (i < n) do
begin
c := CurrentIOSystem.read_symbol;
i += 1;
sb.Append(c);
c := char(CurrentIOSystem.peek());
end;
s := sb.ToString;
end;
//--------------------------------
procedure read(f: Text);
begin
end;
procedure readln(f: Text);
begin
if f.fi = nil then
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));
f.sr.ReadLine;
end;
procedure read(f: Text; var x: integer);
begin
try
x := Convert.ToInt32(ReadLexem(f));
except
on e: Exception do
raise e;
end;
end;
procedure read(f: Text; var x: real);
begin
try
x := Convert.ToDouble(ReadLexem(f), nfi);
except
on e: Exception do
raise e;
end;
end;
procedure readln(f: Text; var x: string);
begin
if f.fi = nil then
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 := '';
end;
procedure read(f: Text; var x: string);
begin
//x := f.sr.ReadLine;//если конец файла то вернет nil
//Нельзя этим пользоваться т.к. считывает и конец строки
if f.fi = nil then
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));
var s := new System.Text.StringBuilder;
repeat
if f.sr.EndOfStream then
break;
if f.sr.Peek = 13 then
break;
if f.sr.Peek = 10 then
break;
s.Append(Convert.ToChar(f.sr.Read));
until False;
x := s.ToString; {}
if x = nil then
x := string.Empty;
end;
procedure read(f: Text; var x: char);
begin
if f.fi = nil then
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));
try
x := Convert.ToChar(f.sr.Read());
except
on e: Exception do
raise e;
end;
end;
procedure read(f: Text; var x: byte);
begin
try
x := Convert.ToByte(ReadLexem(f));
except
on e: Exception do
raise e;
end;
end;
procedure read(f: Text; var x: shortint);
begin
try
x := Convert.ToSByte(ReadLexem(f));
except
on e: Exception do
raise e;
end;
end;
procedure read(f: Text; var x: smallint);
begin
try
x := Convert.ToInt16(ReadLexem(f));
except
on e: Exception do
raise e;
end;
end;
procedure read(f: Text; var x: word);
begin
try
x := Convert.ToUInt16(ReadLexem(f));
except
on e: Exception do
raise e;
end;
end;
procedure read(f: Text; var x: longword);
begin
try
x := Convert.ToUInt32(ReadLexem(f));
except
on e: Exception do
raise e;
end;
end;
procedure read(f: Text; var x: int64);
begin
try
x := Convert.ToInt64(ReadLexem(f));
except
on e: Exception do
raise e;
end;
end;
procedure read(f: Text; var x: uint64);
begin
try
x := Convert.ToUInt64(ReadLexem(f));
except
on e: Exception do
raise e;
end;
end;
procedure read(f: Text; var x: single);
begin
try
x := Convert.ToSingle(ReadLexem(f));
except
on e: Exception do
raise e;
end;
end;
procedure read(f: Text; var x: boolean);
begin
var s := ReadLexem(f).ToLower;
if s = 'true' then
x := True
else if s = 'false' then
x := False
else raise new System.FormatException('Входная строка имела неверный формат');
end;
function ReadInteger(f: Text): integer;
begin
Read(f, Result);
end;
function ReadInt64(f: Text): int64;
begin
Read(f, Result);
end;
function ReadReal(f: Text): real;
begin
Read(f, Result);
end;
function ReadChar(f: Text): char;
begin
Read(f, Result);
end;
function ReadString(f: Text): string;
begin
Read(f, Result);
Readln(f);
end;
function ReadBoolean(f: Text): boolean;
begin
Read(f, Result);
end;
function ReadlnInteger(f: Text): integer;
begin
Result := ReadInteger(f);
Readln(f);
end;
function ReadlnInt64(f: Text): int64;
begin
Result := ReadInt64(f);
Readln(f);
end;
function ReadlnReal(f: Text): real;
begin
Result := ReadReal(f);
Readln(f);
end;
function ReadlnChar(f: Text): char;
begin
Result := ReadChar(f);
Readln(f);
end;
function ReadlnString(f: Text): string;
begin
Result := ReadString(f);
end;
function ReadlnBoolean(f: Text): boolean;
begin
Result := ReadBoolean(f);
Readln(f);
end;
// -----------------------------------------------------
// TextFile methods
// -----------------------------------------------------
function Text.ReadInteger := PABCSystem.ReadInteger(Self);
function Text.ReadReal := PABCSystem.ReadReal(Self);
function Text.ReadChar := PABCSystem.ReadChar(Self);
function Text.ReadString := PABCSystem.ReadString(Self);
function Text.ReadWord := ReadLexem(Self);
function Text.ReadBoolean := PABCSystem.ReadBoolean(Self);
function Text.ReadlnInteger := PABCSystem.ReadlnInteger(Self);
function Text.ReadlnReal := PABCSystem.ReadlnReal(Self);
function Text.ReadlnChar := PABCSystem.ReadlnChar(Self);
function Text.ReadlnString := PABCSystem.ReadlnString(Self);
function Text.ReadlnBoolean := PABCSystem.ReadlnBoolean(Self);
procedure Text.Readln := PABCSystem.Readln(Self);
procedure Text.Write(params o: array of Object) := PABCSystem.Write(Self, o);
procedure Text.Writeln(params o: array of Object) := PABCSystem.Writeln(Self, o);
procedure Text.Print(params o: array of Object);
begin
if PrintDelimDefault<>'' then
foreach var s in o do
PABCSystem.Write(Self, s, PrintDelimDefault)
else
foreach var s in o do
PABCSystem.Write(Self, s)
end;
procedure Text.Println(params o: array of Object);
begin
if o.Length <> 0 then
begin
if PrintDelimDefault<>'' then
for var i:=0 to o.Length-2 do
PABCSystem.Write(Self, o[i], PrintDelimDefault)
else
for var i:=0 to o.Length-2 do
PABCSystem.Write(Self, o[i]);
PABCSystem.Write(Self, o.Last);
end;
PABCSystem.Writeln(Self);
end;
function Text.Eof := PABCSystem.Eof(Self);
function Text.Eoln := PABCSystem.Eoln(Self);
procedure Text.Close := PABCSystem.Close(Self);
function Text.SeekEof := PABCSystem.SeekEof(Self);
function Text.SeekEoln := PABCSystem.SeekEoln(Self);
procedure Text.Flush := PABCSystem.Flush(Self);
procedure Text.Erase := PABCSystem.Erase(Self);
procedure Text.Rename(newname: string) := PABCSystem.Rename(Self, newname);
function Text.Name := fi.Name;
function Text.FullName := fi.FullName;
function Text.ReadToEnd := sr.ReadToEnd;
procedure Text.Reset := PABCSystem.Reset(Self);
procedure Text.Reset(en: Encoding) := PABCSystem.Reset(Self,en);
procedure Text.Rewrite := PABCSystem.Rewrite(Self);
procedure Text.Rewrite(en: Encoding) := PABCSystem.Rewrite(Self,en);
procedure Text.Append := PABCSystem.Append(Self);
procedure Text.Append(en: Encoding) := PABCSystem.Append(Self,en);
function Text.Lines: sequence of string;
begin
Self.sr.BaseStream.Position := 0;
while not Eof do
yield ReadlnString;
end;
// -----------------------------------------------------
// AbstractBinaryFile methods
// -----------------------------------------------------
procedure AbstractBinaryFile.Close := PABCSystem.Close(Self);
procedure AbstractBinaryFile.Truncate := PABCSystem.Truncate(Self);
function AbstractBinaryFile.Eof := PABCSystem.Eof(Self);
procedure AbstractBinaryFile.Erase := PABCSystem.Erase(Self);
procedure AbstractBinaryFile.Rename(newname: string) := PABCSystem.Rename(Self, newname);
procedure AbstractBinaryFile.Write(params vals: array of object) := PABCSystem.Write(Self, vals);
procedure AbstractBinaryFile.Reset := PABCSystem.Reset(Self);
procedure AbstractBinaryFile.Rewrite := PABCSystem.Rewrite(Self);
function AbstractBinaryFile.Name := fi.Name;
function AbstractBinaryFile.FullName := fi.FullName;
// -----------------------------------------------------
// TypedFile & BinaryFile methods
// -----------------------------------------------------
function TypedFile.Size: int64 := PABCSystem.FileSize(Self);
function TypedFile.GetFilePos: int64 := PABCSystem.FilePos(Self);
procedure TypedFile.Seek(n: int64) := PABCSystem.Seek(Self, n);
procedure BinaryFile.Reset(en: Encoding) := PABCSystem.Reset(Self,en);
procedure BinaryFile.Rewrite(en: Encoding) := PABCSystem.Rewrite(Self,en);
function BinaryFile.GetFilePos: int64 := PABCSystem.FilePos(Self);
function BinaryFile.Size: int64 := PABCSystem.FileSize(Self);
procedure BinaryFile.Seek(n: int64) := PABCSystem.Seek(Self, n);
procedure BinaryFile.InternalCheck;
begin
if Self.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
if Self.fs = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED));
end;
procedure BinaryFile.WriteBytes(a: array of byte);
begin
InternalCheck;
Self.bw.Write(a);
end;
function BinaryFile.ReadBytes(count: integer): array of byte;
begin
InternalCheck;
Result := Self.br.ReadBytes(count)
end;
function BinaryFile.ReadInteger: integer;
begin
InternalCheck;
Result := Self.br.ReadInt32;
end;
function BinaryFile.ReadBoolean: boolean;
begin
InternalCheck;
Result := Self.br.ReadBoolean;
end;
function BinaryFile.ReadByte: byte;
begin
InternalCheck;
Result := Self.br.ReadByte;
end;
function BinaryFile.ReadChar: char;
begin
InternalCheck;
Result := Self.br.ReadChar;
end;
function BinaryFile.ReadReal: real;
begin
InternalCheck;
Result := Self.br.ReadDouble;
end;
function BinaryFile.ReadString: string;
begin
InternalCheck;
Result := Self.br.ReadString;
end;
// -----------------------------------------------------
// Eoln - Eof
// -----------------------------------------------------
function Eoln: boolean;
begin
if not console_alloc then
AllocConsole;
Result := CurrentIOSystem.peek = 13
end;
function Eof: boolean;
begin
if not console_alloc then
AllocConsole;
Result := CurrentIOSystem.peek = -1
end;
// -----------------------------------------------------
// Write - Writeln # Write subroutines
// -----------------------------------------------------
function PointerOutput.ToString: string;
begin
result := PointerToString(p);
end;
constructor PointerOutput.Create(ptr: pointer);
begin
p := ptr;
end;
procedure Write;
begin
end;
procedure write_in_output(obj: object);
begin
write(output, obj);
end;
procedure writeln_in_output;
begin
writeln(output);
end;
procedure Write(obj: object);
begin
if output.sw <> nil then
write_in_output(obj)
else CurrentIOSystem.Write(obj);
end;
//procedure write(ptr: pointer);
//begin
// CurrentIOSystem.Write(ptr);
//end;
procedure Write(obj1, obj2: object);
begin
if output.sw <> nil then
begin
write_in_output(obj1);
write_in_output(obj2);
end
else
begin
CurrentIOSystem.Write(obj1);
CurrentIOSystem.Write(obj2);
end;
end;
procedure Write(params args: array of object);
begin
for var i := 0 to args.length - 1 do
if output.sw <> nil then
write_in_output(args[i])
else
CurrentIOSystem.Write(args[i]);
end;
procedure Writeln(obj: object);
begin
if output.sw <> nil then
begin
write_in_output(obj);
writeln_in_output;
end
else
begin
CurrentIOSystem.Write(obj);
CurrentIOSystem.Writeln;
end
end;
//procedure writeln(ptr: pointer);
//begin
// CurrentIOSystem.Write(PointerToString(ptr));
// CurrentIOSystem.Writeln;
//end;
procedure Writeln(obj1, obj2: object);
begin
if output.sw <> nil then
begin
write_in_output(obj1);
write_in_output(obj2);
writeln_in_output;
end
else
begin
CurrentIOSystem.Write(obj1);
CurrentIOSystem.Write(obj2);
CurrentIOSystem.Writeln;
end
end;
procedure Writeln;
begin
if output.sw <> nil then
writeln_in_output
else CurrentIOSystem.Writeln;
end;
procedure Writeln(params args: array of object);
begin
if output.sw <> nil then
begin
for var i := 0 to args.length - 1 do
write_in_output(args[i]);
writeln_in_output;
end
else
begin
for var i := 0 to args.length - 1 do
CurrentIOSystem.Write(args[i]);
CurrentIOSystem.Writeln;
end;
end;
procedure Write(f: Text);
begin
end;
procedure Write(f: Text; val: object);
begin
if f.fi = nil then
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;
end;
case System.Type.GetTypeCode(val.GetType) of
TypeCode.Double,
TypeCode.Single,
TypeCode.Decimal:
f.sw.Write(FormatFloatNumber(val.ToString));
else
f.sw.Write(val)
end;}
end;
procedure Write(f: Text; params args: array of object);
begin
for var i := 0 to args.length - 1 do
write(f, args[i]);
end;
procedure Writeln(f: Text);
begin
if f.fi = nil then
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;
procedure Writeln(f: Text; val: object);
begin
write(f, val);
writeln(f);
end;
procedure Writeln(f: Text; params args: array of object);
begin
for var i := 0 to args.length - 1 do
write(f, args[i]);
writeln(f);
end;
procedure WriteFormat(formatstr: string; params args: array of object);
begin
var s := Format(formatstr, args);
write(s);
end;
procedure WritelnFormat(formatstr: string; params args: array of object);
begin
var s := Format(formatstr, args);
writeln(s);
end;
procedure WriteFormat(f: Text; formatstr: string; params args: array of object);
begin
var s := Format(formatstr, args);
write(f, s);
end;
procedure WritelnFormat(f: Text; formatstr: string; params args: array of object);
begin
var s := Format(formatstr, args);
Writeln(f, s);
end;
// -----------------------------------------------------
// Print - Println
// -----------------------------------------------------
procedure Print(s: string);
begin
if PrintDelimDefault<>'' then
Write(s, PrintDelimDefault)
else Write(s)
end;
procedure Print(o: object);
begin
if PrintDelimDefault<>'' then
Write(o, PrintDelimDefault)
else
Write(o)
end;
procedure Print(params args: array of object);
begin
if args.Length = 0 then
exit;
if PrintDelimDefault<>'' then
for var i := 0 to args.length - 1 do
Write(args[i], PrintDelimDefault)
else
for var i := 0 to args.length - 1 do
Write(args[i])
end;
procedure Println(params args: array of object);
begin
Print(args);
Writeln;
end;
procedure Print(f: Text; params args: array of object);
begin
if args.Length = 0 then
exit;
if PrintDelimDefault<>'' then
for var i := 0 to args.length - 1 do
Write(f, args[i], PrintDelimDefault)
else
for var i := 0 to args.length - 1 do
Write(f, args[i])
end;
procedure Println(f: Text; params args: array of object);
begin
Print(f, args);
Writeln(f);
end;
// -----------------------------------------------------
// Text files
// -----------------------------------------------------
procedure Assign(f: Text; name: string);
begin
try
f.fi := System.IO.FileInfo.Create(name);
except
on e: Exception do
raise e;
end;
if f = output then
f.sw := new StreamWriter(f.fi.FullName);
if f = input then
begin
f.sr := new StreamReader(f.fi.FullName, DefaultEncoding);
(CurrentIOSystem as IOStandardSystem).tr := f.sr;
_IsPipedRedirected := True;
_IsPipedRedirectedQuery := True;
end;
end;
procedure AssignFile(f: Text; name: string) := Assign(f, name);
procedure Close(f: Text);
begin
if f.fi = nil then
raise new IOException(GetTranslation(FILE_NOT_ASSIGNED));
if f.sr <> nil then
begin
f.sr.Close;
f.sr := nil;
f.sw := nil;
// f.fi := nil;
end
else if f.sw <> nil then
begin
f.sw.Close;
f.sr := nil;
f.sw := nil;
// f.fi := nil;
end
else raise new IOException(GetTranslation(FILE_NOT_OPENED));
end;
procedure CloseFile(f: Text) := Close(f);
procedure Reset(f: Text) := Reset(f, DefaultEncoding);
procedure Reset(f: Text; en: Encoding);
begin
if f.fi = nil then
raise new IOException(GetTranslation(FILE_NOT_ASSIGNED));
if f.sr = nil then
begin
f.sr := new StreamReader(f.fi.FullName, en);
if f.sw <> nil then
begin
f.sw.Close;
f.sw := nil;
end;
end
else
begin
f.sr.BaseStream.Position := 0;
f.sr.DiscardBufferedData;
end;
end;
procedure Reset(f: Text; name: string) := Reset(f, name, DefaultEncoding);
procedure Reset(f: Text; name: string; en: Encoding);
begin
Assign(f, name);
Reset(f, en);
end;
procedure Rewrite(f: Text);
begin
Rewrite(f, DefaultEncoding)
end;
procedure Rewrite(f: Text; en: Encoding);
begin
if f.fi = nil then
raise new IOException(GetTranslation(FILE_NOT_ASSIGNED));
if f.sw = nil then
begin
f.sw := new StreamWriter(f.fi.FullName, False, en);
if f.sr <> nil then
begin
f.sr.Close;
f.sr := nil;
end;
end
else
begin
f.sw.BaseStream.Position := 0;
end;
end;
procedure Rewrite(f: Text; name: string);
begin
Rewrite(f, name, DefaultEncoding)
end;
procedure Rewrite(f: Text; name: string; en: Encoding);
begin
Assign(f, name);
Rewrite(f, en);
end;
procedure Append(f: Text) := Append(f, DefaultEncoding);
procedure Append(f: Text; en: Encoding);
begin
if f.fi = nil then
raise new IOException(GetTranslation(FILE_NOT_ASSIGNED));
f.sw := new StreamWriter(f.fi.FullName, True, en);
end;
procedure Append(f: Text; name: string) := Append(f, name, DefaultEncoding);
procedure Append(f: Text; name: string; en: Encoding);
begin
Assign(f, name);
Append(f, en);
end;
function OpenRead(fname: string): Text := OpenRead(fname, DefaultEncoding);
function OpenRead(fname: string; en: Encoding): Text;
begin
var f: Text := new Text;
Reset(f, fname, en);
Result := f;
end;
function OpenWrite(fname: string): Text := OpenWrite(fname, DefaultEncoding);
function OpenWrite(fname: string; en: Encoding): Text;
begin
var f: Text := new Text;
Rewrite(f, fname, en);
Result := f;
end;
function OpenAppend(fname: string): Text := OpenAppend(fname, DefaultEncoding);
function OpenAppend(fname: string; en: Encoding): Text;
begin
var f: Text := new Text;
Append(f, fname, en);
Result := f;
end;
function Eof(f: Text): boolean;
begin
if f.sr <> nil then
Result := f.sr.EndOfStream
else if f.sw <> nil then
raise new IOException(GetTranslation(EOF_FOR_TEXT_WRITEOPENED))
else raise new IOException(GetTranslation(FILE_NOT_OPENED));
end;
function Eoln(f: Text): boolean;
begin
if f.sr <> nil then
Result := f.sr.EndOfStream or (f.sr.Peek = 13) or (f.sr.Peek = 10)
else if f.sw <> nil then
raise new IOException(GetTranslation(EOLN_FOR_TEXT_WRITEOPENED))
else raise new IOException(GetTranslation(FILE_NOT_OPENED));
end;
function SeekEof(f: Text): boolean;
begin
if f.sw <> nil then
raise new IOException(GetTranslation(SEEKEOF_FOR_TEXT_WRITEOPENED));
if f.sr = nil then
raise new IOException(GetTranslation(FILE_NOT_OPENED));
repeat
if f.sr.EndOfStream then
break;
var i := f.sr.Peek;
if not char.IsWhiteSpace(char(i)) then
break;
f.sr.Read;
until False;
Result := f.sr.EndOfStream;
end;
function SeekEoln(f: Text): boolean;
begin
if f.sw <> nil then
raise new IOException(GetTranslation(SEEKEOLN_FOR_TEXT_WRITEOPENED));
if f.sr = nil then
raise new IOException(GetTranslation(FILE_NOT_OPENED));
repeat
if f.sr.EndOfStream then
break;
var i := f.sr.Peek;
// if not char.IsWhiteSpace(char(i)) then
if (i <> 32) and (i <> 9) then // Если это не пробел и не табуляция
break;
f.sr.Read;
until False;
Result := f.sr.EndOfStream or (f.sr.Peek = 13) or (f.sr.Peek = 10); // Концом строки
end;
procedure Flush(f: Text);
begin
if f.sw <> nil then
f.sw.Flush
end;
procedure Erase(f: Text);
begin
if f.fi = nil then
raise new IOException(GetTranslation(FILE_NOT_ASSIGNED));
f.fi.Delete;
end;
procedure Rename(f: Text; newname: string);
begin
if f.fi = nil then
raise new IOException(GetTranslation(FILE_NOT_ASSIGNED));
System.IO.File.Move(f.fi.FullName, newname);
end;
procedure TextFileInit(var f: Text);
begin
f := new Text;
end;
// -----------------------------------------------------
// ReadLines, ReadAllText, WriteLines, WriteAllText
// -----------------------------------------------------
function ReadLines(path: string): sequence of string;
begin
Result := ReadLines(path, DefaultEncoding);
end;
function ReadLines(path: string; en: Encoding): sequence of string;
begin
Result := System.IO.File.ReadLines(path, en);
end;
function ReadAllLines(path: string): array of string;
begin
Result := ReadAllLines(path, DefaultEncoding);
end;
function ReadAllLines(path: string; en: Encoding): array of string;
begin
Result := System.IO.File.ReadAllLines(path, en);
end;
function ReadAllText(path: string): string;
begin
Result := ReadAllText(path, DefaultEncoding);
end;
function ReadAllText(path: string; en: Encoding): string;
begin
Result := System.IO.File.ReadAllText(path, en);
end;
procedure WriteLines(path: string; ss: sequence of string);
begin
WriteLines(path, ss, DefaultEncoding);
end;
procedure WriteLines(path: string; ss: sequence of string; en: Encoding);
begin
System.IO.File.WriteAllLines(path, ss, en);
end;
procedure WriteAllLines(path: string; ss: array of string);
begin
WriteAllLines(path, ss, DefaultEncoding);
end;
procedure WriteAllLines(path: string; ss: array of string; en: Encoding);
begin
System.IO.File.WriteAllLines(path, ss, en);
end;
procedure WriteAllText(path: string; s: string);
begin
System.IO.File.WriteAllText(path, s, DefaultEncoding);
end;
procedure WriteAllText(path: string; s: string; en: Encoding);
begin
System.IO.File.WriteAllText(path, s, en);
end;
// -----------------------------------------------------
// Abstract binary files
// -----------------------------------------------------
procedure Assign(f: AbstractBinaryFile; name: string);
begin
f.fi := System.IO.FileInfo.Create(name);
end;
procedure AssignFile(f: AbstractBinaryFile; name: string) := Assign(f, name);
procedure Close(f: AbstractBinaryFile);
begin
if f.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
if f.fs = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED));
if f.fs <> nil then
begin
f.br.Close;
f.bw.Close;
f.fs := nil;
f.br := nil;
f.bw := nil;
end;
end;
procedure CloseFile(f: AbstractBinaryFile) := Close(f);
procedure Reset(f: AbstractBinaryFile; en: Encoding);
begin
if f.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
if (f is TypedFile) and not en.IsSingleByte then
raise new System.IO.IOException(GetTranslation(TYPED_FILE_CANBE_OPENED_IN_SINGLEBYTE_ENCODING_ONLY));
if f.fs = nil then
begin
f.fs := new FileStream(f.fi.FullName, FileMode.Open);
f.br := new BinaryReader(f.fs, en);
f.bw := new BinaryWriter(f.fs, en);
end
else
f.fs.Position := 0;
end;
procedure Reset(f: AbstractBinaryFile) := Reset(f,DefaultEncoding);
procedure Reset(f: AbstractBinaryFile; name: string);
begin
Assign(f, name);
Reset(f);
end;
procedure Reset(f: AbstractBinaryFile; name: string; en: Encoding);
begin
Assign(f, name);
Reset(f,en);
end;
procedure Rewrite(f: AbstractBinaryFile; en: Encoding);
begin
if f.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
if (f is TypedFile) and not en.IsSingleByte then
raise new System.IO.IOException(GetTranslation(TYPED_FILE_CANBE_OPENED_IN_SINGLEBYTE_ENCODING_ONLY));
if f.fs = nil then
begin
f.fs := new FileStream(f.fi.FullName, FileMode.Create);
f.bw := new BinaryWriter(f.fs, en);
f.br := new BinaryReader(f.fs, en);
end
else
begin
f.fs.Position := 0;
Truncate(f);
end;
end;
procedure Rewrite(f: AbstractBinaryFile) := Rewrite(f,DefaultEncoding);
procedure Rewrite(f: AbstractBinaryFile; name: string; en: Encoding);
begin
Assign(f, name);
Rewrite(f,en);
end;
procedure Rewrite(f: AbstractBinaryFile; name: string);
begin
Assign(f, name);
Rewrite(f);
end;
procedure Truncate(f: AbstractBinaryFile);
begin
if f.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
if f.fs = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED));
f.fs.SetLength(f.fs.Position);
end;
function Eof(f: AbstractBinaryFile): boolean;
begin
if f.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
if f.fs = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED));
if f.fs <> nil then
Result := f.fs.Position = f.fs.Length;
end;
procedure Erase(f: AbstractBinaryFile);
begin
if f.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
f.fi.Delete;
end;
procedure Rename(f: AbstractBinaryFile; newname: string);
begin
if f.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
System.IO.File.Move(f.fi.FullName, newname);
end;
function AbstractBinaryFileReadT(f: AbstractBinaryFile; t: System.Type; var ind: integer; in_arr: boolean): object;
var
t1: System.Type;
elem: object;
fa: array of System.Reflection.FieldInfo;
NullBasedArray: System.Array;
begin
if t.IsPrimitive then
begin
with f.br do
case System.Type.GetTypeCode(t) of
TypeCode.Boolean: Result := ReadBoolean;
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;
end;
end
else if t.IsEnum then Result := f.br.ReadInt32
else if t.IsValueType then
begin
elem := Activator.CreateInstance(t,true);
fa := t.GetFields(System.Reflection.BindingFlags.GetField or System.Reflection.BindingFlags.Instance or System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.NonPublic);
for var i := 0 to fa.Length - 1 do
if {not fa[i].IsStatic and} not fa[i].IsLiteral then
fa[i].SetValue(elem, AbstractBinaryFileReadT(f, fa[i].FieldType, ind, in_arr));
Result := elem;
end
else
if t = typeof(string) then
begin
if f is TypedFile then
begin
var len := f.br.ReadByte();
var chh := f.br.ReadChars(len);
Result := new string(chh);
end
else Result := f.br.ReadString();
if (f is TypedFile) and ((f as TypedFile).offsets <> nil) and ((f as TypedFile).offsets.Length > 0) then
begin
f.br.BaseStream.Seek((f as TypedFile).offsets[ind] - (Result as string).Length, SeekOrigin.Current);
end;
if not in_arr then
Inc(ind);
//if f is TypedFile then
//f.br.BaseStream.Seek(255-(Result as string).Length,SeekOrigin.Current);
end
else if t = typeof(TypedSet) then
begin
Result := f.br.ReadBytes(256 div 8);
elem := Activator.CreateInstance(t, Result);
Result := elem;
end
else
begin
elem := Activator.CreateInstance(t);
NullBasedArray := GetNullBasedArray(elem);
if NullBasedArray <> nil then
begin
t1 := NullBasedArray.GetType.GetElementType;
var tmp := ind;
var tmp2 := 0;
for var i := 0 to NullBasedArray.Length - 1 do
begin
NullBasedArray.SetValue(AbstractBinaryFileReadT(f, t1, ind, i = 0 ? false : true), i);
if i = 0 then
tmp2 := ind;
ind := tmp;
end;
ind := tmp2;
end;
result := elem;
end;
end;
procedure Write(f: AbstractBinaryFile; val: object; arr: boolean; var ind: integer; in_arr: boolean);
var
t: System.Type;
fa: array of System.Reflection.FieldInfo;
NullBasedArray: System.Array;
begin
t := val.GetType;
if f is TypedFile and not arr then
begin
t := (f as TypedFile).ElementType;
end;
if t.IsPrimitive or t.IsEnum then
begin
if t = typeof(integer) then
f.bw.Write(Convert.ToInt32(val))
else if t = typeof(real) then
f.bw.Write(Convert.ToDouble(val))
else if t = typeof(char) then
f.bw.Write(Convert.ToChar(val))
else if t = typeof(boolean) then
f.bw.Write(Convert.ToBoolean(val))
else if t = typeof(byte) then
f.bw.Write(Convert.ToByte(val))
else if t = typeof(shortint) then
f.bw.Write(Convert.ToSByte(val))
else if t = typeof(smallint) then
f.bw.Write(Convert.ToInt16(val))
else if t = typeof(word) then
f.bw.Write(Convert.ToUInt16(val))
else if t = typeof(longword) then
f.bw.Write(Convert.ToUInt32(val))
else if t = typeof(int64) then
f.bw.Write(Convert.ToInt64(val))
else if t = typeof(uint64) then
f.bw.Write(Convert.ToUInt64(val))
else if t = typeof(single) then
f.bw.Write(Convert.ToSingle(val))
else if t.IsEnum then
f.bw.Write(Convert.ToInt32(val));
end
else if t.IsValueType then
begin
fa := t.GetFields(System.Reflection.BindingFlags.GetField or System.Reflection.BindingFlags.Instance or System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.NonPublic);
for var i := 0 to fa.Length - 1 do
begin
if {not fa[i].IsStatic and} not fa[i].IsLiteral then
Write(f, fa[i].GetValue(val), true, ind, in_arr);
end;
end
else if t = typeof(string) then
begin
//var tmp := f.bw.BaseStream.Position;
if f is TypedFile then
begin
f.bw.Write(byte(string(val).Length));
f.bw.Write(string(val).ToArray);
end
else f.bw.Write(string(val));
if (f is TypedFile) and ((f as TypedFile).offsets <> nil) and ((f as TypedFile).offsets.Length > 0) then
begin
f.bw.Write(new byte[(f as TypedFile).offsets[ind] - (val as string).Length]);
end;
if not in_arr then
Inc(ind);
end
else if t = typeof(TypedSet) then
begin
f.bw.Write((val as TypedSet).GetBytes());
end
else
begin
NullBasedArray := GetNullBasedArray(val);
if NullBasedArray <> nil then
begin
var tmp := ind;
var tmp2 := 0;
for var i := 0 to NullBasedArray.Length - 1 do
begin
Write(f, NullBasedArray.GetValue(i), true, ind, i = 0 ? false : true);
if i = 0 then
tmp2 := ind;
ind := tmp;
end;
ind := tmp2;
end;
end;
end;
procedure Write(f: AbstractBinaryFile; params vals: array of object);
begin
if f.fi = nil then raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
if f.fs = nil then raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED));
for var i := 0 to vals.Length - 1 do
begin
var NullBasedArray := GetNullBasedArray(vals[i]);
var ind := 0;
Write(f, vals[i], NullBasedArray <> nil, ind, false);
end;
end;
procedure Writeln(f: AbstractBinaryFile);
begin
raise new System.IO.IOException(GetTranslation(WRITELN_IN_BINARYFILE_ERROR_MESSAGE));
end;
procedure Writeln(f: AbstractBinaryFile; val: object);
begin
raise new System.IO.IOException(GetTranslation(WRITELN_IN_BINARYFILE_ERROR_MESSAGE));
end;
procedure Writeln(f: AbstractBinaryFile; params vals: array of object);
begin
raise new System.IO.IOException(GetTranslation(WRITELN_IN_BINARYFILE_ERROR_MESSAGE));
end;
// -----------------------------------------------------
// Typed files
// -----------------------------------------------------
function FilePos(f: TypedFile): int64;
begin
if f.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
if f.fs = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED));
Result := f.fs.Position div f.ElementSize;
end;
function FileSize(f: TypedFile): int64;
begin
if f.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
if f.fs = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED));
if f.fs.Length mod f.ElementSize <> 0 then
raise new System.IO.IOException('Bad typed file size');
Result := f.fs.Length div f.ElementSize;
end;
procedure Seek(f: TypedFile; n: int64);
begin
if f.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
if f.fs = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED));
f.fs.Position := n * f.ElementSize
end;
procedure TypedFileInit(var f: TypedFile; ElementType: System.Type);
begin
f := new TypedFile(ElementType, 0, new integer[0]);
end;
procedure TypedFileInit(var f: TypedFile; ElementType: System.Type; off: integer; params offs: array of integer);
begin
f := new TypedFile(ElementType, off, offs);
end;
procedure TypedFileInitWithShortString(var f: TypedFile; ElementType: System.Type; off: integer; params offs: array of integer);
begin
f := new TypedFile(ElementType, off, offs);
end;
function TypedFileRead(f: TypedFile): object;
begin
var ind := 0;
if f.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
if f.fs = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED));
Result := AbstractBinaryFileReadT(f, f.ElementType, ind, false);
//if f.offset > 0 then
//f.fs.Seek(tmp+(f as TypedFile).ElementSize-f.fs.Position,SeekOrigin.Current);
end;
// -----------------------------------------------------
// Binary files
// -----------------------------------------------------
function FilePos(f: BinaryFile): int64;
begin
if f.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
if f.fs = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED));
Result := f.fs.Position;
end;
function FileSize(f: BinaryFile): int64;
begin
if f.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
if f.fs = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED));
Result := f.fs.Length;
end;
procedure Seek(f: BinaryFile; n: int64);
begin
if f.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
if f.fs = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED));
f.fs.Position := n;
end;
procedure BinaryFileInit(var f: BinaryFile);
begin
f := new BinaryFile();
end;
function BinaryFileRead(var f: BinaryFile; ElementType: System.Type): object;
begin
if f.fi = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_ASSIGNED));
if f.fs = nil then
raise new System.IO.IOException(GetTranslation(FILE_NOT_OPENED));
var ind := 0;
Result := AbstractBinaryFileReadT(f, ElementType, ind, false);
end;
// -----------------------------------------------------
// Operating System subroutines: implementation
// -----------------------------------------------------
function PascalABCVersion: string;
begin
Result := '3.2.0.1364'{PABC_VERSION};
end;
function ParamCount: integer;
begin
if (Environment.GetCommandLineArgs.Length > 1) and ((Environment.GetCommandLineArgs[1] = '[REDIRECTIOMODE]') or (Environment.GetCommandLineArgs[1] = '[RUNMODE]')) then
Result := Environment.GetCommandLineArgs.Length - 2
else
Result := Environment.GetCommandLineArgs.Length - 1;
end;
function ParamStr(i: integer): string;
begin
if (Environment.GetCommandLineArgs.Length > 1) and ((Environment.GetCommandLineArgs[1] = '[REDIRECTIOMODE]') or (Environment.GetCommandLineArgs[1] = '[RUNMODE]')) then
Result := Environment.GetCommandLineArgs[i + 1]
else
Result := Environment.GetCommandLineArgs[i];
end;
function GetDir: string;
begin
Result := Environment.CurrentDirectory;
end;
procedure ChDir(s: string);
begin
Environment.CurrentDirectory := s;
end;
procedure MkDir(s: string);
begin
Directory.CreateDirectory(s);
end;
procedure RmDir(s: string);
begin
Directory.Delete(s);
end;
function CreateDir(s: string): boolean;
begin
try
Result := True;
Directory.CreateDirectory(s);
except
Result := False;
end;
end;
function DeleteFile(s: string): boolean;
begin
try
Result := True;
&File.Delete(s);
except
Result := False;
end;
end;
function GetCurrentDir: string;
begin
Result := Environment.CurrentDirectory;
end;
function RemoveDir(s: string): boolean;
begin
try
Result := True;
Directory.Delete(s);
except
Result := False;
end;
end;
function RenameFile(name, newname: string): boolean;
begin
try
Result := True;
&File.Move(name, newname);
except
Result := False;
end;
end;
function SetCurrentDir(s: string): boolean;
begin
try
Result := True;
Environment.CurrentDirectory := s;
except
Result := False;
end;
end;
function ChangeFileNameExtension(name, newext: string): string;
begin
Result := System.IO.Path.ChangeExtension(name, newext);
end;
function FileExists(name: string): boolean;
begin
Result := System.IO.File.Exists(name);
end;
procedure Assert(cond: boolean; sourceFile: string; line: integer);
begin
if (Environment.OSVersion.Platform = PlatformID.Unix) or (Environment.OSVersion.Platform = PlatformID.MacOSX) or IsWDE then
begin
//var stackTrace := new System.Diagnostics.StackTrace(true);
//var ind := 1;
//if stackTrace.GetFrame(0).GetMethod().Name <> 'Assert' then
//ind := 0;
//var currentLine := stackTrace.GetFrame(ind).GetFileLineNumber();
//var currentFile := stackTrace.GetFrame(ind).GetFileName();
if not IsWDE then
System.Diagnostics.Debug.Assert(cond, 'Файл ' + sourceFile + ', строка ' + line.ToString())
else if not cond then
begin
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.Contracts.Contract.Assert(cond,'Файл '+sourceFile+', строка '+line.ToString())
end;
procedure Assert(cond: boolean; message: string; sourceFile: string; line: integer);
begin
if (Environment.OSVersion.Platform = PlatformID.Unix) or (Environment.OSVersion.Platform = PlatformID.MacOSX) or IsWDE then
begin
//var stackTrace := new System.Diagnostics.StackTrace(true);
//var ind := 1;
//if stackTrace.GetFrame(0).GetMethod().Name <> 'Assert' then
// ind := 0;
//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)
else if not cond then
begin
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.Contracts.Contract.Assert(cond,'Файл '+sourceFile+', строка '+line.ToString() + ': ' + message)
end;
function DiskFree(diskname: string): int64;
begin
try
var d := new System.IO.DriveInfo(diskname);
Result := d.TotalFreeSpace;
except
Result := -1;
end;
end;
function DiskSize(diskname: string): int64;
begin
try
var d := new System.IO.DriveInfo(diskname);
Result := d.TotalSize;
except
Result := -1;
end;
end;
function ConvertDiskToDiskName(disk: integer): string;
begin
if disk = 0 then
begin
var s := Paramstr(0);
var p := Pos(':', s);
if p > 0 then
Result := Copy(s, 1, p)
else Result := 'C:';
end
else
begin
if disk < 0 then disk := 0;
if disk > 26 then disk := 26;
var ch := 'A';
Inc(ch, disk - 1);
Result := ch + ':';
end;
end;
function DiskFree(disk: integer): int64;
begin
Result := DiskFree(ConvertDiskToDiskName(disk));
end;
function DiskSize(disk: integer): int64;
begin
Result := DiskSize(ConvertDiskToDiskName(disk));
end;
var
curr_time := DateTime.Now;
function Milliseconds: integer;
begin
curr_time := DateTime.Now;
Milliseconds := Convert.ToInt32((curr_time - StartTime).TotalMilliseconds);
end;
function MillisecondsDelta: integer;
begin
var t := DateTime.Now;
Result := Convert.ToInt32((t - curr_time).TotalMilliseconds);
curr_time := DateTime.Now;
end;
procedure Halt;
begin
Halt(ExitCode);
end;
procedure Halt(exitCode: integer);
begin
//System.Diagnostics.Process.GetCurrentProcess.Kill;
//WINAPI_TerminateProcess(System.Diagnostics.Process.GetCurrentProcess.Handle, exitCode);
System.Environment.Exit(exitCode);
end;
procedure Sleep(ms: integer);
begin
System.Threading.Thread.Sleep(ms);
end;
function GetEXEFileName: string;
begin
Result := System.Reflection.Assembly.GetEntryAssembly().ManifestModule.FullyQualifiedName;
end;
function PointerToString(p: pointer): string;
begin
//result:= Convert.ToString(integer(p), 16);
if p = nil then
result := 'nil'
else if Environment.Is64BitProcess then
result := '$' + int64(p).ToString('X')
else
result := '$' + integer(p).ToString('X')
end;
procedure Exec(filename: string);
begin
System.Diagnostics.Process.Start(filename)
end;
procedure Exec(filename: string; args: string);
begin
System.Diagnostics.Process.Start(filename, args)
end;
procedure Execute(filename: string);
begin
System.Diagnostics.Process.Start(filename)
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)
end;
function EnumerateAllFiles(path: string; searchPattern: string): sequence of string;
begin
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)
end;
function EnumerateAllDirectories(path: string): sequence of string;
begin
Result := System.IO.Directory.EnumerateDirectories(path, '*.*', System.IO.SearchOption.AllDirectories)
end;
// -----------------------------------------------------
// File name functions: implementation
// -----------------------------------------------------
function ExtractFileName(fname: string): string;
begin
var fi := new System.IO.FileInfo(fname);
Result := fi.Name;
end;
function ExtractFileExt(fname: string): string;
begin
var fi := new System.IO.FileInfo(fname);
Result := fi.Extension;
end;
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
Result += '\';
end;
function ExtractFileDir(fname: string): string;
begin
var fi := new System.IO.FileInfo(fname);
Result := fi.DirectoryName;
end;
function ExtractFileDrive(fname: string): string;
begin
try
var fi := new System.IO.FileInfo(fname);
Result := fi.DirectoryName;
var p := Pos(':', Result);
if p > 0 then
Result := Copy(Result, 1, p)
else Result := '';
except
on e: Exception do
raise e;
end;
end;
function ExpandFileName(fname: string): string;
begin
var fi := new System.IO.FileInfo(fname);
Result := fi.FullName;
end;
// -----------------------------------------------------
// Mathematical functions: implementation
// -----------------------------------------------------
function Sign(x: shortint): integer := Math.Sign(x);
function Sign(x: smallint): integer := Math.Sign(x);
function Sign(x: integer): integer := Math.Sign(x);
function Sign(x: BigInteger) := x.Sign;
function Sign(x: int64) := Math.Sign(x);
function Sign(x: byte): integer := 1;
function Sign(x: word): integer := 1;
function Sign(x: longword): integer := 1;
function Sign(x: uint64): integer := 1;
function Sign(x: real): integer := Math.Sign(x);
function Abs(x: shortint): shortint := Math.Abs(x);
function Abs(x: smallint): smallint := Math.Abs(x);
function Abs(x: integer): integer := Math.Abs(x);
function Abs(x: int64): int64 := Math.Abs(x);
function Abs(x: BigInteger): BigInteger := BigInteger.Abs(x);
function Abs(x: byte): byte := x;
function Abs(x: word): word := x;
function Abs(x: longword): longword := x;
function Abs(x: uint64): uint64 := x;
function Abs(x: real): real := Math.Abs(x);
function Abs(x: single): single := Math.Abs(x);
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: byte): integer := x * x;
function Sqr(x: word): uint64 := 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
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 Power(x: BigInteger; y: integer) := BigInteger.Pow(x, y);
function Round(x: real) := Convert.ToInt32(x);
function Round(x: real; digits: integer) := Math.Round(x,digits);
function RoundBigInteger(x: real) := BigInteger.Create(Math.Round(x));
function Trunc(x: real) := Convert.ToInt32(Math.Truncate(x));
function TruncBigInteger(x: real) := BigInteger.Create(Math.Truncate(x));
function Int(x: real) := x >= 0 ? Math.Floor(x) : Math.Ceiling(x);
function Frac(x: real) := x - Int(x);
function Floor(x: real) := Convert.ToInt32(Math.Floor(x));
function Ceil(x: real) := Convert.ToInt32(Math.Ceiling(x));
function RadToDeg(x: real) := x * 180 / Pi;
function DegToRad(x: real) := x * Pi / 180;
procedure Randomize;
begin
rnd := new System.Random;
end;
procedure Randomize(seed: integer);
begin
rnd := new System.Random(seed);
end;
function Random(MaxValue: integer) := rnd.Next(MaxValue);
function Random(a, b: integer): integer;
begin
if a > b then Swap(a, b);
Result := rnd.Next(a, b + 1);
end;
function Random(a, b: real): real;
begin
if a > b then Swap(a, b);
Result := a + Random()*(b-a);
end;
function Random := rnd.NextDouble;
function Random(MaxValue: real) := Random()*Abs(MaxValue);
function Random2(maxValue: integer) := (Random(maxValue), Random(maxValue));
function Random2(maxValue: real) := (Random(maxValue), Random(maxValue));
function Random2(a, b: integer) := (Random(a, b), Random(a, b));
function Random2(a, b: real) := (Random(a, b), Random(a, b));
function Random2 := (Random, Random);
function Random3(maxValue: integer) := (Random(maxValue), Random(maxValue), Random(maxValue));
function Random3(maxValue: Real) := (Random(maxValue), Random(maxValue), Random(maxValue));
function Random3(a, b: integer) := (Random(a, b), Random(a, b), Random(a, b));
function Random3(a, b: real) := (Random(a, b), Random(a, b), Random(a, b));
function Random3 := (Random, Random, Random);
function Max(a, b: byte) := Math.Max(a, b);
function Max(a, b: shortint) := Math.Max(a, b);
function Max(a, b: word) := Math.Max(a, b);
function Max(a, b: smallint) := Math.Max(a, b);
function Max(a, b: integer) := Math.Max(a, b);
function Max(a, b: BigInteger) := BigInteger.Max(a, b);
function Max(a, b: longword) := Math.Max(a, b);
function Max(a, b: int64) := Math.Max(a, b);
function Max(a, b: uint64) := Math.Max(a, b);
function Max(a, b: real) := Math.Max(a, b);
function Max(a, b, c: real): real;
begin
Result := a;
if b > Result then Result := b;
if c > Result then Result := c;
end;
function Max(a, b, c, d: real): real;
begin
Result := a;
if b > Result then Result := b;
if c < Result then Result := c;
if d > Result then Result := d;
end;
function Max(params a: array of integer): integer := a.Max;
function Max(params a: array of real): real := a.Max;
function Min(a, b: byte) := Math.Min(a, b);
function Min(a, b: shortint) := Math.Min(a, b);
function Min(a, b: word) := Math.Min(a, b);
function Min(a, b: smallint) := Math.Min(a, b);
function Min(a, b: integer) := Math.Min(a, b);
function Min(a, b: BigInteger) := BigInteger.Min(a, b);
function Min(a, b: longword) := Math.Min(a, b);
function Min(a, b: int64) := Math.Min(a, b);
function Min(a, b: uint64) := Math.Min(a, b);
function Min(a, b: real) := Math.Min(a, b);
function Min(a, b, c: real): real;
begin
Result := a;
if b < Result then Result := b;
if c < Result then Result := c;
end;
function Min(a, b, c, d: real): real;
begin
Result := a;
if b < Result then Result := b;
if c < Result then Result := c;
if d < Result then Result := d;
end;
function Min(params a: array of integer): integer := a.Min;
function Min(params a: array of real): real := a.Min;
function Odd(i: byte) := (i mod 2) <> 0;
function Odd(i: shortint) := (i mod 2) <> 0;
function Odd(i: word) := (i mod 2) <> 0;
function Odd(i: smallint) := (i mod 2) <> 0;
function Odd(i: integer) := (i mod 2) <> 0;
function Odd(i: BigInteger) := not i.IsEven;
function Odd(i: longword) := (i mod 2) <> 0;
function Odd(i: int64) := (i mod 2) <> 0;
function Odd(i: uint64) := (i mod 2) <> 0;
function Cplx(re, im: real) := new Complex(re, im);
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
// -----------------------------------------------------
function Low(i: System.Array): integer;
begin
if i <> nil then
Result := i.GetLowerBound(0)
else Result := 0;
end;
function High(i: System.Array): integer;
begin
if i <> nil then
Result := i.GetUpperBound(0)
else Result := -1;
end;
function Length(a: &Array): integer;
begin
if a = nil then
Result := 0
else Result := a.Length;
end;
function Length(a: &Array; dim: integer): integer;
begin
if a = nil then
Result := 0
else Result := a.GetLength(dim);
end;
function Copy(a: &Array): &Array;
begin
Result := &Array(a.Clone());
end;
procedure Sort<T>(a: array of T);
begin
System.Array.Sort(a);
end;
procedure Sort<T>(a: array of T; cmp: (T,T)->integer);
begin
System.Array.Sort(a, cmp);
end;
procedure Sort<T>(a: array of T; less: (T,T)->boolean);
begin
System.Array.Sort(a, (x, y)-> less(x, y) ? -1 : (less(y, x) ? 1 : 0));
end;
procedure Sort<T>(l: List<T>);
begin
l.Sort();
end;
procedure Sort<T>(l: List<T>; cmp: (T,T)->integer);
begin
l.Sort(cmp);
end;
procedure Sort<T>(l: List<T>; less: (T,T)->boolean);
begin
l.Sort((x, y)-> less(x, y) ? -1 : (less(y, x) ? 1 : 0));
end;
procedure SortDescending<T>(a: array of T);
begin
Sort(a);
Reverse(a);
end;
procedure SortDescending<T>(l: List<T>);
begin
Sort(l);
Reverse(l);
end;
procedure Reverse<T>(a: array of T);
begin
System.Array.Reverse(a);
end;
procedure Reverse<T>(a: array of T; index, count: integer);
begin
System.Array.Reverse(a, index, count);
end;
procedure Reverse<T>(a: List<T>);
begin
a.Reverse
end;
procedure Reverse<T>(a: List<T>; index, count: integer);
begin
a.Reverse(index, count)
end;
procedure Reverse(var s: string);
begin
var cc := s.ToCharArray;
Reverse(cc);
s := new string(cc);
end;
procedure Reverse(var s: string; index, count: integer);
begin
var cc := s.ToCharArray;
Reverse(cc,index-1,count);
s := new string(cc);
end;
procedure Shuffle<T>(a: array of T);
begin
var n := a.Length;
for var i := 0 to n - 1 do
Swap(a[i], a[Random(n)]);
end;
procedure Shuffle<T>(l: List<T>);
begin
var n := l.Count;
for var i := 0 to n - 1 do
begin
var v := l[i];
l[i] := l[Random(n)];
l[Random(n)] := v;
end;
end;
// -----------------------------------------------------
// Char and String: implementation
// -----------------------------------------------------
function ChrAnsi(a: Byte): char;
begin
if a < 128 then
Result := char(a)
else
begin
__one_byte[0] := a;
Result := AnsiOrdChrEncoding.GetChars(__one_byte)[0];
end;
end;
function OrdAnsi(a: char): byte;
begin
if a < #128 then
Result := byte(a)
else
begin
__one_char[0] := a;
Result := AnsiOrdChrEncoding.GetBytes(__one_char)[0];
end;
end;
function Ord(a: integer): integer;
begin
Result := a;
end;
function Ord(a: longword): longword;
begin
Result := a;
end;
function Ord(a: int64): int64;
begin
Result := a;
end;
function Ord(a: uint64): uint64;
begin
Result := a;
end;
function Ord(a: boolean): integer;
begin
Result := integer(a);
end;
function Chr(a: word): char;
begin
Result := Convert.ToChar(a);
end;
function Ord(a: char): word;
begin
Result := word(a);
end;
function ChrUnicode(a: word): char;
begin
Result := Convert.ToChar(a);
end;
function OrdUnicode(a: char): word;
begin
Result := word(a);
end;
function UpperCase(ch: char): char;
begin
Result := char.ToUpper(ch);
end;
function LowerCase(ch: char): char;
begin
Result := char.ToLower(ch);
end;
function UpCase(ch: char): char;
begin
Result := char.ToUpper(ch);
end;
function LowCase(ch: char): char;
begin
Result := char.ToLower(ch);
end;
procedure Str(i: integer; var s: string);
begin
s := i.ToString;
end;
procedure Str(i: longword; var s: string);
begin
s := i.ToString;
end;
procedure Str(i: int64; var s: string);
begin
s := i.ToString;
end;
procedure Str(i: uint64; var s: string);
begin
s := i.ToString;
end;
procedure Str(s1: string; var s: string);
begin
s := s1;
end;
procedure Str(r: single; var s: string);
begin
s := Convert.ToString(r, nfi);
end;
procedure Str(r: real; var s: string);
begin
s := Convert.ToString(r, nfi);
end;
function Pos(subs, s: string; from: integer): integer;
begin
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;
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;
end;
function LastPos(subs, s: string; from: integer): integer;
begin
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;
end;
{function Pos(c: char; s: string; from: integer): integer;
begin
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) := Pos(c,s,from);
function LastPos(c: char; s: string): integer;
begin
Result := s.LastIndexOf(c, s.Length - 1, System.StringComparison.Ordinal) + 1;
end;
function LastPos(c: char; s: string; from: integer): integer;
begin
if from > s.Length then
Result := 0;
Result := s.LastIndexOf(c, from - 1, System.StringComparison.Ordinal) + 1;
end;}
function Length(s: string): integer;
begin
if s <> nil then
Result := s.Length
else Result := 0;
end;
procedure SetLength(var s: string; n: integer);
begin
if n < 0 then
raise new System.ArgumentOutOfRangeException('n');
if n = 0 then
s := String.Empty
else if s.Length > n then
s := s.Substring(0, n)
else if s.Length < n then
s += new string(' ', n - s.Length);
end;
procedure SetLengthForShortString(var s: string; n, sz: integer);
begin
if n < 0 then
raise new System.ArgumentOutOfRangeException('n');
if n = 0 then
s := String.Empty
else if s.Length > n then
s := s.Substring(0, n)
else if s.Length < n then
if n <= sz then
s += new string(' ', n - s.Length)
else
s += new String(' ', sz - s.Length)
end;
procedure Insert(source: string; var s: string; index: integer);
// Insert никогда не возвращает исключения
begin
if index < 1 then
index := 1;
if index > s.Length + 1 then
index := s.Length + 1;
s := s.Insert(index - 1, source);
end;
procedure InsertInShortString(source: string; var s: string; index, n: integer);
begin
if index < 1 then
index := 1;
if index > n then
exit;
try
s := s.Insert(index - 1, source);
if s.Length > n then s := s.Substring(0, n);
except
s := s.Insert(s.Length, source);
if s.Length > n then s := s.Substring(0, n);
end;
end;
procedure Delete(var s: string; index, count: integer);
// Delete никогда не возвращает исключения
begin
if (index < 1) or (index > s.Length) or (count <= 0) then
Exit;
if index + count - 1 > s.Length then
count := s.Length - index + 1;
s := s.Remove(index - 1, count);
end;
function Copy(s: string; index, count: integer): string;
// Copy никогда не возвращает исключения
begin
if index < 1 then
index := 1;
if (index > s.Length) or (count <= 0) then
begin
Result := '';
exit;
end;
if index + count - 1 > s.Length then
count := s.Length - index + 1;
Result := s.SubString(index - 1, count);
end;
function Concat(s1, s2: string): string;
begin
Result := s1 + s2;
end;
function Concat(params strs: array of string): string;
begin
var sb := new System.Text.StringBuilder;
for var i := 0 to strs.length - 1 do
sb.Append(strs[i]);
concat := sb.ToString;
end;
function LowerCase(s: string): string;
begin
Result := s.ToLower;
end;
function UpperCase(s: string): string;
begin
Result := s.ToUpper;
end;
function StringOfChar(ch: char; count: integer): string;
begin
Result := new string(ch, count);
end;
function ReverseString(s: string): string;
begin
var ca := s.ToCharArray;
&Array.Reverse(ca);
Result := new string(ca);
end;
function ReverseString(s: string; index,length: integer): string;
begin
var ca := s.ToCharArray;
&Array.Reverse(ca,index,length);
Result := new string(ca);
end;
function CompareStr(s1, s2: string): Integer;
begin
Result := string.CompareOrdinal(s1, s2);
end;
function LeftStr(s: string; count: integer): string;
begin
if count > s.Length then
count := s.Length;
Result := s.Substring(0, count)
end;
function RightStr(s: string; count: integer): string;
begin
if count > s.Length then
count := s.Length;
Result := s.Substring(s.Length - count, count);
end;
function Trim(s: string): string;
begin
Result := s.Trim(' ');
end;
function TrimLeft(s: string): string;
begin
Result := s.TrimStart(' ');
end;
function TrimRight(s: string): string;
begin
Result := s.TrimEnd(' ');
end;
function StrToInt(s: string): integer;
begin
var j := 1;
while (j <= s.Length) and char.IsWhiteSpace(s[j]) do
j += 1;
if (j > s.Length) then
raise new System.FormatException(ErrorStringFromResource('Format_InvalidString'));
var sign := 0;
if s[j] = '-' then
begin
sign := -1;
j += 1;
end
else if s[j] = '+' then
begin
sign := 1;
j += 1;
end;
if (j > s.Length) then
raise new System.FormatException(ErrorStringFromResource('Format_InvalidString'));
var c := integer(s[j]);
if (c < 48) or (c > 57) then
raise new System.FormatException(ErrorStringFromResource('Format_InvalidString'));
Result := c - 48;
j += 1;
while j <= s.Length do
begin
c := integer(s[j]);
if c > 57 then
break;
if c < 48 then
break;
if Result > 214748364 then
raise new System.OverflowException(ErrorStringFromResource('Overflow_Int32'));
Result := Result * 10 + (c - 48);
j += 1;
end;
if Result < 0 then
if (Result = -2147483648) and (sign = -1) then
exit
else raise new System.OverflowException(ErrorStringFromResource('Overflow_Int32'));
if sign = -1 then
Result := -Result;
while (j <= s.Length) and char.IsWhiteSpace(s[j]) do
j += 1;
if j <= s.Length then
raise new System.FormatException(ErrorStringFromResource('Format_InvalidString'));
end;
function TryStrToInt(s: string; var value: integer): boolean;
begin
Result := True;
var Res := 0;
var j := 1;
while (j <= s.Length) and char.IsWhiteSpace(s[j]) do
j += 1;
if (j > s.Length) then
begin
Result := False;
exit
end;
var sign := 0;
if s[j] = '-' then
begin
sign := -1;
j += 1;
end
else if s[j] = '+' then
begin
sign := 1;
j += 1;
end;
if (j > s.Length) then
begin
Result := False;
exit
end;
var c := integer(s[j]);
if (c < 48) or (c > 57) then
begin
Result := False;
exit
end;
Res := c - 48;
j += 1;
while j <= s.Length do
begin
c := integer(s[j]);
if c > 57 then
break;
if c < 48 then
break;
if Res > 214748364 then
begin
Result := False;
exit
end;
Res := Res * 10 + (c - 48);
j += 1;
end;
if Res < 0 then
if (Res = -2147483648) and (sign = -1) then
exit
else
begin
Result := False;
exit
end;
if sign = -1 then
Res := -Res;
while (j <= s.Length) and char.IsWhiteSpace(s[j]) do
j += 1;
if j <= s.Length then
begin
Result := False;
exit
end;
value := Res;
end;
function StrToInt64(s: string) := Convert.ToInt64(s);
function StrToReal(s: string) := Convert.ToDouble(s, nfi);
function StrToFloat(s: string) := StrToReal(s);
function TryStrToInt64(s: string; var value: int64) := int64.TryParse(s, value);
function TryStrToReal(s: string; var value: real) := real.TryParse(s,System.Globalization.NumberStyles.Float,new System.Globalization.NumberFormatInfo,value);
function TryStrToSingle(s: string; var value: single) := single.TryParse(s,System.Globalization.NumberStyles.Float,new System.Globalization.NumberFormatInfo,value);
function TryStrToFloat(s: string; var value: real) := TryStrToReal(s, value);
function TryStrToFloat(s: string; var value: single) := TryStrToSingle(s, value);
function ReadIntegerFromString(s: string; var from: integer): integer;
begin
while (from <= s.Length) and char.IsWhiteSpace(s[from]) do
from += 1;
if (from > s.Length) then
raise new System.FormatException(ErrorStringFromResource('Format_InvalidString'));
var sign := 0;
if s[from] = '-' then
begin
sign := -1;
from += 1;
end
else if s[from] = '+' then
begin
sign := 1;
from += 1;
end;
if (from > s.Length) then
raise new System.FormatException(ErrorStringFromResource('Format_InvalidString'));
var c := integer(s[from]);
if (c < 48) or (c > 57) then
raise new System.FormatException(ErrorStringFromResource('Format_InvalidString'));
Result := c - 48;
from += 1;
while from <= s.Length do
begin
c := integer(s[from]);
if c > 57 then
break;
if c < 48 then
break;
if Result > 214748364 then
raise new System.OverflowException(ErrorStringFromResource('Overflow_Int32'));
Result := Result * 10 + (c - 48);
from += 1;
end;
if Result < 0 then
if (Result = -2147483648) and (sign = -1) then
exit
else raise new System.OverflowException(ErrorStringFromResource('Overflow_Int32'));
if sign = -1 then
Result := -Result;
end;
function ReadWordFromString(s: string; var from: integer): string;
begin
while (from <= s.Length) and char.IsWhiteSpace(s[from]) do
from += 1;
var res := new System.Text.StringBuilder();
while (from <= s.Length) and not char.IsWhiteSpace(s[from]) do
begin
res.Append(s[from]);
from += 1;
end;
Result := res.ToString;
end;
function ReadRealFromString(s: string; var from: integer): real;
begin
Result := real.Parse(ReadWordFromString(s, from));
end;
function TryReadRealFromString(s: string; var from: integer; var res: real): boolean;
begin
Result := real.TryParse(ReadWordFromString(s, from), res);
end;
function StringIsEmpty(s: string; var from: integer): boolean;
begin
while (from <= s.Length) and char.IsWhiteSpace(s[from]) do
from += 1;
Result := from > s.Length;
end;
function TryReadIntegerFromString(s: string; var from: integer; var res: integer): boolean;
begin
Result := TryStrToInt(ReadWordFromString(s, from), res);
end;
procedure Val(s: string; var value: integer; var err: integer);
begin
if TryStrToInt(s, value) then
err := 0
else err := 1;
end;
procedure Val(s: string; var value: real; var err: integer);
begin
if TryStrToFloat(s, value) then
err := 0
else err := 1;
end;
procedure Val(s: string; var value: single; var err: integer);
begin
try
err := 0;
value := Convert.ToSingle(s, nfi);
except
value := 0;
err := 1;
end;
end;
procedure Val(s: string; var value: shortint; var err: integer);
begin
if shortint.TryParse(s, value) then
err := 0
else err := 1;
end;
procedure Val(s: string; var value: smallint; var err: integer);
begin
if smallint.TryParse(s, value) then
err := 0
else err := 1;
end;
procedure Val(s: string; var value: int64; var err: integer);
begin
if int64.TryParse(s, value) then
err := 0
else err := 1;
end;
procedure Val(s: string; var value: byte; var err: integer);
begin
if byte.TryParse(s, value) then
err := 0
else err := 1;
end;
procedure Val(s: string; var value: word; var err: integer);
begin
if word.TryParse(s, value) then
err := 0
else err := 1;
end;
procedure Val(s: string; var value: longword; var err: integer);
begin
if longword.TryParse(s, value) then
err := 0
else err := 1;
end;
procedure Val(s: string; var value: uint64; var err: integer);
begin
if uint64.TryParse(s, value) then
err := 0
else err := 1;
end;
function IntToStr(a: integer): string;
begin
Result := a.ToString;
end;
function IntToStr(a: int64): string;
begin
Result := a.ToString;
end;
function FloatToStr(a: real): string;
begin
Result := a.ToString(nfi);
end;
function Format(formatstring: string; params pars: array of object): string;
begin
try
Result := string.Format(nfi, formatstring, pars);
except
on e: Exception do
raise e;
end;
end;
// -----------------------------------------------------
// Общие подпрограммы
// -----------------------------------------------------
procedure Inc(var i: integer);
begin
i += 1;
end;
procedure Inc(var i: integer; n: integer);
begin
i += n;
end;
procedure Dec(var i: integer);
begin
i -= 1;
end;
procedure Dec(var i: integer; n: integer);
begin
i -= n;
end;
procedure Inc(var c: char);
begin
c := ChrUnicode(word(c) + 1);
end;
procedure Inc(var c: char; n: integer);
begin
c := ChrUnicode(word(c) + n);
end;
procedure Dec(var c: char);
begin
c := ChrUnicode(word(c) - 1);
end;
procedure Dec(var c: char; n: integer);
begin
c := ChrUnicode(word(c) - n);
end;
procedure Inc(var b: byte);
begin
b += 1;
end;
procedure Inc(var b: byte; n: integer);
begin
b += n;
end;
procedure Dec(var b: byte);
begin
b -= 1;
end;
procedure Dec(var b: byte; n: integer);
begin
b -= n;
end;
procedure Inc(var f: boolean);
begin
f := not f;
end;
procedure Dec(var f: boolean);
begin
f := not f;
end;
//------------------------------------------------------------------------------
//PRED-SUCC
function Succ(x: boolean): boolean;
begin
Result := not x;
end;
function Succ(x: byte): byte;
begin
Result := x + 1;
end;
function Succ(x: shortint): shortint;
begin
Result := x + 1;
end;
function succ(x: smallint): smallint;
begin
Result := x + 1;
end;
function Succ(x: word): word;
begin
Result := x + 1;
end;
function Succ(x: integer): integer;
begin
Result := x + 1;
end;
function Succ(x: longword): longword;
begin
Result := x + 1;
end;
function Succ(x: int64): int64;
begin
Result := x + 1;
end;
function Succ(x: uint64): uint64;
begin
Result := x + 1;
end;
function Succ(x: char): char;
begin
//Result := System.Convert.ToChar(System.Convert.ToUInt16(x) + 1);
Result := char(integer(x)+1);
end;
function Succ(x: char; n: integer): char;
begin
//Result := System.Convert.ToChar(System.Convert.ToUInt16(x) + 1);
Result := char(integer(x)+n);
end;
function Pred(x: boolean): boolean;
begin
Result := not x;
end;
function Pred(x: byte): byte;
begin
Result := x - 1;
end;
function Pred(x: shortint): shortint;
begin
Result := x - 1;
end;
function Pred(x: smallint): smallint;
begin
Result := x - 1;
end;
function Pred(x: word): word;
begin
Result := x - 1;
end;
function Pred(x: integer): integer;
begin
Result := x - 1;
end;
function Pred(x: longword): longword;
begin
Result := x - 1;
end;
function Pred(x: int64): int64;
begin
Result := x - 1;
end;
function Pred(x: uint64): uint64;
begin
Result := x - 1;
end;
function Pred(x: char): char;
begin
Result := char(integer(x)-1);
//Result := System.Convert.ToChar(System.Convert.ToUInt16(x) - 1);
end;
function Pred(x: char; n: integer): char;
begin
Result := char(integer(x)-n);
end;
procedure Swap<T>(var a, b: T);
begin
var v := a;
a := b;
b := v;
end;
//{{{doc: Начало методов расширения }}}
// -----------------------------------------------------
//>> Генерация бесконечных последовательностей # Infinite sequences
// -----------------------------------------------------
// Дополнения февраль 2016: Iterate, Step, &Repeat, Cycle
// Возвращает бесконечную рекуррентную последовательность элементов, задаваемую начальным элементом и функцией next
///--
function Iterate<T>(Self: T; next: T->T): sequence of T; extensionmethod;
begin
Result := Iterate&<T>(Self, next);
end;
// Возвращает бесконечную рекуррентную последовательность элементов, задаваемую начальным элементом, следующим за ним элементом и функцией next
///--
function Iterate<T>(Self, second: T; next: (T,T) ->T): sequence of T; extensionmethod;
begin
Result := Iterate&<T>(Self, second, next);
end;
/// Возвращает бесконечную последовательность целых от текущего значения с шагом 1
function Step(Self: integer): sequence of integer; extensionmethod;
begin
while True do
begin
yield Self;
Self += 1;
end;
end;
/// Возвращает бесконечную последовательность целых от текущего значения с шагом step
function Step(Self: integer; step: integer): sequence of integer; extensionmethod;
begin
while True do
begin
yield Self;
Self += step;
end;
end;
/// Возвращает бесконечную последовательность вещественных от текущего значения с шагом step
function Step(Self: real; step: real): sequence of real; extensionmethod;
begin
while True do
begin
yield Self;
Self += step;
end;
end;
// Возвращает бесконечную последовательность элементов, совпадающих с данным
///--
function &Repeat<T>(Self: T): sequence of T; extensionmethod;
begin
while True do
yield Self;
end;
/// Повторяет последовательность бесконечное число раз
function Cycle<T>(Self: sequence of T): sequence of T; extensionmethod;
begin
while True do
begin
foreach var x in Self do
yield x;
end;
end;
// -----------------------------------------------------
//>> Фиктивная секция XXX - не удалять! # XXX
// -----------------------------------------------------
type
AdjGroupClass<T> = class
private
cur: T;
enm: IEnumerator<T>;
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: int64): int64; 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 Print(Self: string): string; extensionmethod;
begin
PABCSystem.Print(Self);
Result := Self;
end;
function Println(Self: integer): integer; extensionmethod;
begin
PABCSystem.Println(Self);
Result := Self;
end;
function Println(Self: int64): int64; 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;
function Println(Self: string): string; extensionmethod;
begin
PABCSystem.Println(Self);
Result := Self;
end;
//------------------------------------------------------------------------------
//>> Методы расширения последовательностей # Extension methods for sequence of T
//------------------------------------------------------------------------------
/// Выводит последовательность на экран, используя delim в качестве разделителя
function Print<T>(Self: sequence of T; delim: string): sequence of T; extensionmethod;
begin
var g := Self.GetEnumerator();
if g.MoveNext() then
begin
Write(g.Current);
while g.MoveNext() do
if delim <> '' then
Write(delim, g.Current)
else Write(g.Current);
end;
Result := Self;
end;
/// Выводит последовательность на экран, используя пробел в качестве разделителя
function Print<T>(Self: sequence of T): sequence of T; extensionmethod;
begin
if typeof(T) = typeof(char) then
Result := Self.Print('')
else
Result := Self.Print(PrintDelimDefault);
end;
/// Выводит последовательность на экран, используя delim в качестве разделителя, и переходит на новую строку
function Println<T>(Self: sequence of T; delim: string): sequence of T; extensionmethod;
begin
Self.Print(delim);
Writeln;
Result := Self;
end;
/// Выводит последовательность на экран, используя пробел качестве разделителя, и переходит на новую строку
function Println<T>(Self: sequence of T): sequence of T; extensionmethod;
begin
if typeof(T) = typeof(char) then
Result := Self.Println('')
else
Result := Self.Println(PrintDelimDefault);
end;
/// Выводит последовательность строк в файл
function WriteLines(Self: sequence of string; fname: string): sequence of string; extensionmethod;
begin
WriteLines(fname, Self);
Result := Self
end;
/// Выводит последовательность, каждый элемент выводится на новой строке
function PrintLines<T>(Self: sequence of T): sequence of T; extensionmethod;
begin
Self.Println(NewLine);
Result := Self
end;
/// Выводит последовательность, каждый элемент отображается с помощью функции map и выводится на новой строке
function PrintLines<T,T1>(Self: sequence of T; map: T->T1): sequence of T; extensionmethod;
begin
Self.Select(map).Println(NewLine);
Result := Self
end;
/// Преобразует элементы последовательности в строковое представление, после чего объединяет их в строку, используя delim в качестве разделителя
function JoinToString<T>(Self: sequence of T; delim: string): string; extensionmethod;
begin
var g := Self.GetEnumerator();
var sb := new System.Text.StringBuilder('');
if g.MoveNext() then
begin
sb.Append(g.Current.ToString());
while g.MoveNext() do
sb.Append(delim + g.Current.ToString());
end;
Result := sb.ToString;
end;
///--
function JoinIntoString<T>(Self: sequence of T; delim: string): string; extensionmethod
:= Self.JoinToString(delim);
/// Преобразует элементы последовательности в строковое представление, после чего объединяет их в строку, используя пробел в качестве разделителя
function JoinToString<T>(Self: sequence of T): string; extensionmethod;
begin
if typeof(T) = typeof(char) then
Result := Self.JoinIntoString('')
else Result := Self.JoinIntoString(' ');
end;
///--
function JoinIntoString<T>(Self: sequence of T): string; extensionmethod
:= Self.JoinToString();
/// Применяет действие к каждому элементу последовательности
procedure &ForEach<T>(Self: sequence of T; action: T -> ()); extensionmethod;
begin
foreach x: T in Self do
action(x);
end;
/// Применяет действие к каждому элементу последовательности, зависящее от номера элемента
procedure &ForEach<T>(Self: sequence of T; action: (T,integer) -> ()); extensionmethod;
begin
var i := 0;
foreach x: T in Self do
begin
action(x, i);
i += 1;
end;
end;
/// Возвращает произведение элементов последовательности
function Product(Self: sequence of real): real; extensionmethod;
begin
Result := 1.0;
foreach var x in Self do
Result *= x;
end;
/// Возвращает произведение элементов последовательности
function Product(Self: sequence of integer): int64; extensionmethod;
begin
Result := 1;
foreach var x in Self do
Result *= x;
end;
/// Возвращает отсортированную по возрастанию последовательность
function Sorted<T>(Self: sequence of T): sequence of T; extensionmethod;
begin
Result := Self.OrderBy(x -> x);
end;
/// Возвращает отсортированную по убыванию последовательность
function SortedDescending<T>(Self: sequence of T): sequence of T; extensionmethod;
begin
Result := Self.OrderByDescending(x -> x);
end;
/// Возвращает отсортированную по возрастанию последовательность
function Order<T>(Self: sequence of T): sequence of T; extensionmethod;
begin
Result := Self.OrderBy(x -> x);
end;
/// Возвращает отсортированную по убыванию последовательность
function OrderDescending<T>(Self: sequence of T): sequence of T; extensionmethod;
begin
Result := Self.OrderByDescending(x -> x);
end;
/// Возвращает множество HashSet по данной последовательности
function ToHashSet<T>(Self: sequence of T): HashSet<T>; extensionmethod;
begin
Result := new HashSet<T>(Self);
end;
/// Возвращает множество SortedSet по данной последовательности
function ToSortedSet<T>(Self: sequence of T): SortedSet<T>; extensionmethod;
begin
Result := new SortedSet<T>(Self);
end;
/// Возвращает LinkedList по данной последовательности
function ToLinkedList<T>(Self: sequence of T): LinkedList<T>; extensionmethod;
begin
Result := new LinkedList<T>(Self);
end;
// Дополнения февраль 2016: MinBy, MaxBy, TakeLast, Slice, Cartesian, SplitAt,
// Partition, ZipTuple, UnZipTuple, Interleave, Numerate, Tabulate, Pairwise, Batch
/// Возвращает первый элемент последовательности с минимальным значением ключа
function MinBy<T, TKey>(Self: sequence of T; selector: T->TKey): T; extensionmethod;
begin
if selector = nil then
raise new ArgumentNullException('selector');
var comp := Comparer&<TKey>.Default;
Result := Self.Aggregate((min, x)-> comp.Compare(selector(x), selector(min)) < 0 ? x : min);
end;
/// Возвращает первый элемент последовательности с максимальным значением ключа
function MaxBy<T, TKey>(Self: sequence of T; selector: T->TKey): T; extensionmethod;
begin
if selector = nil then
raise new ArgumentNullException('selector');
var comp := Comparer&<TKey>.Default;
Result := Self.Aggregate((max, x)-> comp.Compare(selector(x), selector(max)) > 0 ? x : max);
end;
/// Возвращает последний элемент последовательности с минимальным значением ключа
function LastMinBy<T, TKey>(Self: sequence of T; selector: T->TKey): T; extensionmethod;
begin
if selector = nil then
raise new ArgumentNullException('selector');
var comp := Comparer&<TKey>.Default;
Result := Self.Aggregate((min, x)-> comp.Compare(selector(x), selector(min)) <= 0 ? x : min);
end;
/// Возвращает последний элемент последовательности с максимальным значением ключа
function LastMaxBy<T, TKey>(Self: sequence of T; selector: T->TKey): T; extensionmethod;
begin
if selector = nil then
raise new ArgumentNullException('selector');
var comp := Comparer&<TKey>.Default;
Result := Self.Aggregate((max, x)-> comp.Compare(selector(x), selector(max)) >= 0 ? x : max);
end;
/// Возвращает последние count элементов последовательности
function TakeLast<T>(Self: sequence of T; count: integer): sequence of T; extensionmethod;
begin
if count < 0 then
raise new System.ArgumentOutOfRangeException('count', count, GetTranslation(PARAMETER_MUST_BE_GREATER_EQUAL_0));
if Self is IList<T> then
begin
var lst := Self as IList<T>;
var ind := lst.Count - count;
if ind<0 then ind := 0;
for var i:=ind to lst.Count-1 do
yield lst[i];
exit;
end;
var buf := new List<T>;
var p := 0;
foreach var x in Self do
if buf.Count<count then
buf.Add(x)
else
begin
buf[p] := x;
p := (p+1) mod count;
end;
for var i:=0 to buf.Count do
begin
yield buf[p];
p := (p+1) mod count;
end;
end;
{function TakeLast<T>(Self: sequence of T; count: integer): sequence of T; extensionmethod;
begin
Result := Self.Reverse.Take(count).Reverse;
end;}
/// Возвращает последовательность без последних count элементов
function SkipLast<T>(Self: sequence of T; count: integer): sequence of T; extensionmethod;
begin
if count < 0 then
raise new System.ArgumentOutOfRangeException('count', count, GetTranslation(PARAMETER_MUST_BE_GREATER_EQUAL_0));
if Self is IList<T> then
begin
var lst := Self as IList<T>;
for var i:=0 to lst.Count - count - 1 do
yield lst[i];
exit;
end;
var buf := new List<T>(count);
var p := 0;
foreach var x in Self do
if buf.Count<count then
buf.Add(x)
else
begin
yield buf[p];
buf[p] := x;
p := (p+1) mod count;
end;
end;
function SkipLast<T>(Self: sequence of T): sequence of T; extensionmethod :=
Self.SkipLast(1);
{function SkipLast<T>(self: sequence of T; count: integer := 1): sequence of T; extensionmethod;
begin
Result := Self.Reverse.Skip(count).Reverse;
end;}
/// Декартово произведение последовательностей
function Cartesian<T, T1>(Self: sequence of T; b: sequence of T1): sequence of (T, T1); extensionmethod;
begin
if b = nil then
raise new System.ArgumentNullException('b');
foreach var x in Self do
foreach var y in b do
yield (x, y)
end;
/// Декартово произведение последовательностей
function Cartesian<T, T1, T2>(Self: sequence of T; b: sequence of T1; func: (T,T1)->T2): sequence of T2; extensionmethod;
begin
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)
end;
/// Разбивает последовательность на две в позиции ind. Реализуется двухпроходным алгоритмом
function SplitAt<T>(Self: sequence of T; ind: integer): (sequence of T, sequence of T); extensionmethod;
begin
Result := (Self.Take(ind), Self.Skip(ind));
end;
// ToDo: то же для TakeWhile
// ToDo: SequenceCompare
/// Разделяет последовательность на две по заданному условию. Реализуется двухпроходным алгоритмом
function Partition<T>(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)));
end;
/// Разделяет последовательность на две по заданному условию, в котором участвует индекс. Реализуется двухпроходным алгоритмом
function Partition<T>(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)));
end;
/// Объединяет две последовательности в последовательность двухэлементных кортежей
function ZipTuple<T, T1>(Self: sequence of T; a: sequence of T1): sequence of (T, T1); extensionmethod;
begin
if a = nil then
raise new System.ArgumentNullException('a');
Result := Self.Zip(a, (x, y) -> (x, y));
end;
/// Объединяет три последовательности в последовательность трехэлементных кортежей
function ZipTuple<T, T1, T2>(Self: sequence of T; a: sequence of T1; b: sequence of T2): sequence of (T, T1, T2); extensionmethod;
begin
if a = nil then
raise new System.ArgumentNullException('a');
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));
end;
/// Объединяет четыре последовательности в последовательность четырехэлементных кортежей
function ZipTuple<T, T1, T2, T3>(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
raise new System.ArgumentNullException('a');
if b = nil then
raise new System.ArgumentNullException('b');
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));
end;
/// Разъединяет последовательность двухэлементных кортежей на две последовательности. Реализуется двухпроходным алгоритмом
function UnZipTuple<T, T1>(Self: sequence of (T, T1)): (sequence of T, sequence of T1); extensionmethod;
begin
Result := (Self.Select(x -> x[0]), Self.Select(x -> x[1]))
end;
/// Разъединяет последовательность трехэлементных кортежей на три последовательности. Реализуется многопроходным алгоритмом
function UnZipTuple<T, T1, T2>(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]))
end;
/// Разъединяет последовательность четырехэлементных кортежей на четыре последовательности. Реализуется многопроходным алгоритмом
function UnZipTuple<T, T1, T2, T3>(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]))
end;
// ToDo - сделать UnZipTuple с функцией-проекцией
/// Чередует элементы двух последовательностей
function Interleave<T>(Self: sequence of T; a: sequence of T): sequence of T; extensionmethod;
begin
if a = nil then
raise new System.ArgumentNullException('a');
Result := Self.ZipTuple(a).SelectMany(x -> Seq(x[0], x[1]))
end;
/// Чередует элементы трех последовательностей
function Interleave<T>(Self: sequence of T; a, b: sequence of T): sequence of T; extensionmethod;
begin
if a = nil then
raise new System.ArgumentNullException('a');
if b = nil then
raise new System.ArgumentNullException('b');
Result := Self.ZipTuple(a, b).SelectMany(x -> Seq(x[0], x[1], x[2]))
end;
/// Чередует элементы четырех последовательностей
function Interleave<T>(Self: sequence of T; a, b, c: sequence of T): sequence of T; extensionmethod;
begin
if a = nil then
raise new System.ArgumentNullException('a');
if b = nil then
raise new System.ArgumentNullException('b');
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]))
end;
/// Нумерует последовательность с единицы
function Numerate<T>(Self: sequence of T): sequence of (integer, T); extensionmethod;
begin
var i := 1;
foreach var x in Self do
begin
yield (i,x);
i += 1;
end;
end;
/// Нумерует последовательность с номера from
function Numerate<T>(Self: sequence of T; from: integer): sequence of (integer, T); extensionmethod;
begin
var i := from;
foreach var x in Self do
begin
yield (i,x);
i += 1;
end;
end;
/// Табулирует функцию последовательностью
function Tabulate<T, T1>(Self: sequence of T; F: T->T1): sequence of (T, T1); extensionmethod;
begin
Result := Self.Select(x -> (x, f(x)));
end;
/// Превращает последовательность в последовательность пар соседних элементов
function Pairwise<T>(Self: sequence of T): sequence of (T, T); extensionmethod;
begin
var previous: T;
var it := Self.GetEnumerator();
if (it.MoveNext()) then
previous := it.Current;
while (it.MoveNext()) do
begin
yield (previous, it.Current);
previous := it.Current;
end
end;
/// Превращает последовательность в последовательность пар соседних элементов, применяет func к каждой паре полученных элементов и получает новую последовательность
function Pairwise<T, Res>(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;
while (it.MoveNext()) do
begin
yield func(previous, it.Current);
previous := it.Current;
end
// Result := Self.ZipTuple(Self.Skip(1)).Select(x->func(x[0],x[1]));
end;
/// Разбивает последовательность на серии длины size
function Batch<T>(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))
end;
/// Разбивает последовательность на серии длины size и применяет проекцию к каждой серии
function Batch<T, Res>(Self: sequence of T; size: integer; proj: Func<IEnumerable<T>, 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));
end;
///--
function SliceSeqImpl<T>(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)
end;
/// Возвращает срез последовательности от номера from с шагом step > 0
function Slice<T>(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)
end;
/// Возвращает срез последовательности от номера from с шагом step > 0 длины не более count
function Slice<T>(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)
end;
// Дополнения июль 2016: Incremental
///--
function IncrementalSeq(Self: sequence of integer): sequence of integer;
begin
var iter := Self.GetEnumerator();
if iter.MoveNext() then
begin
var prevItem := iter.Current;
while iter.MoveNext() do
begin
var nextItem := iter.Current;
yield nextItem - prevItem;
prevItem := nextItem;
end
end
end;
///--
function IncrementalSeq(Self: sequence of real): sequence of real;
begin
var iter := Self.GetEnumerator();
if iter.MoveNext() then
begin
var prevItem := iter.Current;
while iter.MoveNext() do
begin
var nextItem := iter.Current;
yield nextItem - prevItem;
prevItem := nextItem;
end
end
end;
/// Возвращает последовательность разностей соседних элементов исходной последовательности
function Incremental(Self: sequence of integer): sequence of integer; extensionmethod;
begin
Result := IncrementalSeq(Self);
end;
/// Возвращает последовательность разностей соседних элементов исходной последовательности
function Incremental(Self: array of integer): sequence of integer; extensionmethod;
begin
Result := IncrementalSeq(Self);
end;
/// Возвращает последовательность разностей соседних элементов исходной последовательности
function Incremental(Self: List<integer>): sequence of integer; extensionmethod;
begin
Result := IncrementalSeq(Self);
end;
/// Возвращает последовательность разностей соседних элементов исходной последовательности
function Incremental(Self: LinkedList<integer>): sequence of integer; extensionmethod;
begin
Result := IncrementalSeq(Self);
end;
/// Возвращает последовательность разностей соседних элементов исходной последовательности
function Incremental(Self: sequence of real): sequence of real; extensionmethod;
begin
Result := IncrementalSeq(Self);
end;
/// Возвращает последовательность разностей соседних элементов исходной последовательности
function Incremental(Self: array of real): sequence of real; extensionmethod;
begin
Result := IncrementalSeq(Self);
end;
/// Возвращает последовательность разностей соседних элементов исходной последовательности
function Incremental(Self: List<real>): sequence of real; extensionmethod;
begin
Result := IncrementalSeq(Self);
end;
/// Возвращает последовательность разностей соседних элементов исходной последовательности
function Incremental(Self: LinkedList<real>): sequence of real; extensionmethod;
begin
Result := IncrementalSeq(Self);
end;
/// Возвращает последовательность разностей соседних элементов исходной последовательности. В качестве функции разности используется func
function Incremental<T, T1>(Self: sequence of T; func: (T,T)->T1): sequence of T1; extensionmethod;
begin
var iter := Self.GetEnumerator();
if iter.MoveNext() then
begin
var prevItem := iter.Current;
while iter.MoveNext() do
begin
var nextItem := iter.Current;
yield func(prevItem, nextItem);
prevItem := nextItem;
end
end
end;
/// Возвращает последовательность разностей соседних элементов исходной последовательности. В качестве функции разности используется func
function Incremental<T, T1>(Self: sequence of T; func: (T,T,integer)->T1): sequence of T1; extensionmethod;
begin
var iter := Self.GetEnumerator();
if iter.MoveNext() then
begin
var ind := 0;
var prevItem := iter.Current;
while iter.MoveNext() do
begin
var nextItem := iter.Current;
ind += 1;
yield func(prevItem, nextItem, ind);
prevItem := nextItem;
end
end
end;
/// Группирует одинаковые подряд идущие элементы, получая последовательность массивов
function AdjacentGroup<T>(Self: sequence of T): sequence of array of T; extensionmethod;
begin
var c := new AdjGroupClass<T>(Self);
while c.fin do
yield c.TakeGroup().ToArray;
end;
// ToDo Сделать AdjacentGroup с функцией сравнения
// -----------------------------------------------------
//>> Методы расширения списков # Extension methods for List T
// -----------------------------------------------------
/// Возвращает последовательность индексов списка
function Indices<T>(Self: List<T>): sequence of integer; extensionmethod := Range(0, Self.Count - 1);
/// Возвращает последовательность индексов элементов списка, удовлетворяющих условию
function Indices<T>(Self: List<T>; cond: T->boolean): sequence of integer; extensionmethod;
begin
for var i := 0 to Self.Count - 1 do
if cond(Self[i]) then
yield i;
end;
/// Возвращает последовательность индексов элементов списка, удовлетворяющих условию
function Indices<T>(Self: List<T>; cond: (T,integer) ->boolean): sequence of integer; extensionmethod;
begin
for var i := 0 to Self.Count - 1 do
if cond(Self[i], i) then
yield i;
end;
/// Перемешивает элементы списка случайным образом
function Shuffle<T>(Self: List<T>): List<T>; extensionmethod;
begin
var n := Self.Count;
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;
end;
/// Находит первую пару подряд идущих одинаковых элементов и возвращает индекс первого элемента пары. Если не найден, возвращается -1
function AdjacentFind<T>(Self: IList<T>; 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<T>(Self: IList<T>; 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<T>(Self: List<T>; index: integer := 0): integer; extensionmethod; where T: IComparable<T>;
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<T>(Self: List<T>; index: integer := 0): integer; extensionmethod; where T: System.IComparable<T>;
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;
/// Возвращает индекс первого минимального элемента начиная с позиции index
function IndexMin<T>(Self: array of T; index: integer := 0): integer; extensionmethod; where T: IComparable<T>;
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<T>(Self: array of T; index: integer := 0): integer; extensionmethod; where T: System.IComparable<T>;
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;
/// Возвращает индекс последнего минимального элемента в диапазоне [0,index-1]
function LastIndexMin<T>(Self: List<T>; index: integer): integer; extensionmethod; where T: System.IComparable<T>;
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;
/// Возвращает индекс последнего минимального элемента в диапазоне [0,index-1]
function LastIndexMin<T>(Self: array of T; index: integer): integer; extensionmethod; where T: System.IComparable<T>;
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 LastIndexMin<T>(Self: List<T>): integer; extensionmethod; where T: System.IComparable<T>;
begin
Result := Self.LastIndexMin(Self.Count - 1);
end;
/// Возвращает индекс последнего минимального элемента
function LastIndexMin<T>(Self: array of T): integer; extensionmethod; where T: System.IComparable<T>;
begin
Result := Self.LastIndexMin(Self.Length - 1);
end;
/// Возвращает индекс последнего минимального элемента в диапазоне [0,index-1]
function LastIndexMax<T>(Self: List<T>; index: integer): integer; extensionmethod; where T: System.IComparable<T>;
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;
/// Возвращает индекс последнего минимального элемента в диапазоне [0,index-1]
function LastIndexMax<T>(Self: array of T; index: integer): integer; extensionmethod; where T: System.IComparable<T>;
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;
/// Возвращает индекс последнего максимального элемента
function LastIndexMax<T>(Self: List<T>): integer; extensionmethod; where T: System.IComparable<T>;
begin
Result := Self.LastIndexMax(Self.Count - 1);
end;
/// Возвращает индекс последнего максимального элемента
function LastIndexMax<T>(Self: array of T): integer; extensionmethod; where T: System.IComparable<T>;
begin
Result := Self.LastIndexMax(Self.Count - 1);
end;
/// Заменяет в массиве или списке все вхождения одного значения на другое
procedure Replace<T>(Self: IList<T>; 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<T>(Self: IList<T>; f: T->T); extensionmethod;
begin
for var i := 0 to Self.Count - 1 do
Self[i] := f(Self[i]);
end;
/// Преобразует элементы массива или списка по заданному правилу
procedure Transform<T>(Self: IList<T>; f: (T,integer)->T); extensionmethod;
begin
for var i := 0 to Self.Count - 1 do
Self[i] := f(Self[i],i);
end;
/// Заполняет элементы массива или списка значениями, вычисляемыми по некоторому правилу
procedure Fill<T>(Self: IList<T>; f: integer->T); extensionmethod;
begin
for var i := 0 to Self.Count - 1 do
Self[i] := f(i);
end;
///--
function CreateSliceFromListInternal<T>(Self: List<T>; from, step, count: integer): List<T>;
begin
Result := new List<T>(count);
var f := from;
loop count do
begin
Result.Add(Self[f]);
f += step;
end;
end;
///--
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 System.ArgumentOutOfRangeException('count', count, GetTranslation(PARAMETER_MUST_BE_GREATER_EQUAL_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;
if count > cntstep then
count := cntstep;
end;
///--
function SliceListImpl<T>(Self: List<T>; from, step, count: integer): List<T>;
begin
CorrectCountForSlice(Self.Count, from, step, count);
Result := CreateSliceFromListInternal(Self, from, step, count);
end;
/// Возвращает срез списка от индекса from с шагом step
function Slice<T>(Self: List<T>; from, step: integer): List<T>; extensionmethod;
begin
Result := SliceListImpl(Self, from, step, integer.MaxValue);
end;
/// Возвращает срез списка от индекса from с шагом step длины не более count
function Slice<T>(Self: List<T>; from, step, count: integer): List<T>; extensionmethod;
begin
Result := SliceListImpl(Self, from, step, count);
end;
/// Удаляет последний элемент. Если элементов нет, генерирует исключение
function RemoveLast<T>(Self: List<T>): List<T>; extensionmethod;
begin
Self.RemoveAt(Self.Count - 1);
Result := Self;
end;
procedure CorrectFromTo(situation: integer; Len: integer; var from, &to: integer; step: integer);
begin
if situation=0 then exit;
if step > 0 then
begin
case situation of
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: (from, &to) := (Len - 1, -1);
end;
end;
end;
///--
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
begin
if from < 0 then
from += (step - from - 1) div step * step;
// from может оказаться > Len - 1
var m := Min(Len,&to);
if from >= m then
Result := 0
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);
if from <= m then
Result := 0
else Result := (from - m - 1) div (-step) + 1
end;
end;
///--
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 отсутствуют
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));
if situation > 0 then
CorrectFromTo(situation, Len, from, &to, step);
// s[a:b] - Opt
if step = 1 then
begin
Result := &to - from;
if Result<0 then
Result := 0;
exit;
end;
var count: integer;
if step > 0 then
begin
var cnt := &to - from;
if cnt <= 0 then
count := 0
else count := (cnt - 1) div step + 1;
end
else
begin
var cnt := from - &to;
if cnt <= 0 then
count := 0
else count := (cnt - 1) div (-step) + 1;
end;
Result := count;
end;
///--
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 отсутствуют
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<T>(Self: List<T>; situation: integer; from, &to: integer; step: integer := 1): List<T>;
begin
var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation, Self.Count, from, &to, step);
{if (step=1) and (count>32) then // 32 - empirical
begin
Result := Self.GetRange(from,count);
end
else} Result := CreateSliceFromListInternal(Self, from, step, count);
end;
///--
function SystemSlice<T>(Self: List<T>; situation: integer; from, &to: integer): List<T>; extensionmethod;
begin
Result := SystemSliceListImpl(Self, situation, from, &to, 1);
end;
///--
function SystemSlice<T>(Self: List<T>; situation: integer; from, &to, step: integer): List<T>; extensionmethod;
begin
Result := SystemSliceListImpl(Self, situation, from, &to, step);
end;
///--
function SystemSliceListImplQuestion<T>(Self: List<T>; situation: integer; from, &to: integer; step: integer := 1): List<T>;
begin
var count := CorrectFromToAndCalcCountForSystemSliceQuestion(situation, Self.Count, from, &to, step);
Result := CreateSliceFromListInternal(Self, from, step, count);
end;
///--
function SystemSliceQuestion<T>(Self: List<T>; situation: integer; from, &to: integer): List<T>; extensionmethod;
begin
Result := SystemSliceListImplQuestion(Self, situation, from, &to, 1);
end;
///--
function SystemSliceQuestion<T>(Self: List<T>; situation: integer; from, &to, step: integer): List<T>; extensionmethod;
begin
Result := SystemSliceListImplQuestion(Self, situation, from, &to, step);
end;
// -----------------------------------------------------
//>> Методы расширения двумерных динамических массивов # Extension methods for array [,] of T
// -----------------------------------------------------
/// Количество строк в двумерном массиве
function RowCount<T>(Self: array [,] of T): integer; extensionmethod;
begin
Result := Self.GetLength(0);
end;
/// Количество столбцов в двумерном массиве
function ColCount<T>(Self: array [,] of T): integer; extensionmethod;
begin
Result := Self.GetLength(1);
end;
/// Вывод двумерного массива, w - ширина поля вывода
function Print<T>(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
begin
if PrintMatrixWithFormat then
Write(StructuredObjectToString(Self[i, j]).PadLeft(w))
else Print(Self[i, j]);
end;
Writeln;
end;
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
begin
if PrintMatrixWithFormat then
Write(FormatValue(Self[i, j], w, f))
else Print(Self[i, j]);
end;
Writeln;
end;
Result := Self;
end;
/// Вывод двумерного массива и переход на следующую строку, w - ширина поля вывода
function Println<T>(Self: array [,] of T; w: integer := 4): array [,] of T; extensionmethod;
begin
Self.Print(w);
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;
end;
/// k-тая строка двумерного массива
function Row<T>(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];
Result := res;
end;
/// k-тый столбец двумерного массива
function Col<T>(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];
Result := res;
end;
/// k-тая строка двумерного массива как последовательность
function RowSeq<T>(Self: array [,] of T; k: integer): sequence of T; extensionmethod;
begin
for var j := 0 to Self.ColCount - 1 do
yield Self[k, j];
end;
/// k-тый столбец двумерного массива как последовательность
function ColSeq<T>(Self: array [,] of T; k: integer): sequence of T; extensionmethod;
begin
for var i := 0 to Self.RowCount - 1 do
yield Self[i, k];
end;
/// Возвращает последовательность строк двумерного массива
function Rows<T>(Self: array [,] of T): sequence of sequence of T; extensionmethod;
begin
for var i := 0 to Self.RowCount - 1 do
yield Self.RowSeq(i);
end;
/// Возвращает последовательность столбцов двумерного массива
function Cols<T>(Self: array [,] of T): sequence of sequence of T; extensionmethod;
begin
for var j := 0 to Self.ColCount - 1 do
yield Self.ColSeq(j);
end;
/// Меняет местами две строки двумерного массива с номерами k1 и k2
procedure SwapRows<T>(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])
end;
/// Меняет местами два столбца двумерного массива с номерами k1 и k2
procedure SwapCols<T>(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])
end;
/// Меняет строку k двумерного массива на другую строку
procedure SetRow<T>(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 SetRow<T>(Self: array [,] of T; k: integer; a: sequence of T); extensionmethod := Self.SetRow(k,a.ToArray);
/// Меняет столбец k двумерного массива на другой столбец
procedure SetCol<T>(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;
/// Меняет столбец k двумерного массива на другой столбец
procedure SetCol<T>(Self: array [,] of T; k: integer; a: sequence of T); extensionmethod := Self.SetCol(k,a.ToArray);
/// Возвращает по заданному двумерному массиву последовательность (a[i,j],i,j)
function ElementsWithIndices<T>(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 Indices<T>(Self: array [,] of T; cond: T -> boolean): sequence of (integer, integer); extensionmethod;
begin
for var i := 0 to Self.RowCount - 1 do
for var j := 0 to Self.ColCount - 1 do
if cond(Self[i,j]) then
yield (i, j)
end;
/// Возвращает по заданному двумерному массиву последовательность его элементов по строкам
function ElementsByRow<T>(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<T>(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<T, T1>(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;
/// Преобразует элементы двумерного массива и возвращает преобразованный массив
function ConvertAll<T, T1>(Self: array [,] of T; converter: (T,integer,integer)->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],i,j);
end;
/// Преобразует элементы двумерного массива по заданному правилу
procedure Transform<T>(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 Transform<T>(Self: array [,] of T; f: (T,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(Self[i, j],i,j);
end;
/// Заполняет элементы двумерного массива значениями, вычисляемыми по некоторому правилу
procedure Fill<T>(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;
/// Применяет действие к каждому элементу двумерного массива
procedure &ForEach<T>(Self: array [,] of T; act: T -> ()); extensionmethod;
begin
for var i := 0 to Self.RowCount - 1 do
for var j := 0 to Self.ColCount - 1 do
act(Self[i, j]);
end;
/// Применяет действие к каждому элементу двумерного массива
procedure &ForEach<T>(Self: array [,] of T; act: (T,integer,integer) -> ()); extensionmethod;
begin
for var i := 0 to Self.RowCount - 1 do
for var j := 0 to Self.ColCount - 1 do
act(Self[i, j],i,j);
end;
function InR(Self: integer; a,b: integer): boolean;
begin
Result := (a <= Self) and (Self <= b);
end;
/// Возвращает срез двумерного массива. RowIndex и ColIndex задают срезаемые строки и столбцы
function MatrSlice<T>(Self: array[,] of T; RowIndex: array of integer; ColIndex: array of integer): array[,] of T; extensionmethod;
begin
if RowIndex = nil then
raise new System.ArgumentNullException('RowIndex');
if ColIndex = nil then
raise new System.ArgumentNullException('ColIndex');
if RowIndex.Any(i->not InR(i,0,Self.RowCount-1)) then
raise new System.ArgumentOutOfRangeException(GetTranslation(BAD_ROW_INDEX),new Exception);
if ColIndex.Any(i->not InR(i,0,Self.ColCount-1)) then
raise new System.ArgumentOutOfRangeException(GetTranslation(BAD_COL_INDEX),new Exception);
Result := new T[RowIndex.Length, ColIndex.Length];
var r := 0;
foreach var ir in RowIndex do
begin
var c := 0;
foreach var jc in ColIndex do
begin
Result[r, c] := Self[ir, jc];
c += 1;
end;
r += 1;
end
end;
/// Возвращает срез двумерного массива между строками FromRow, ToRow и столбцами FromCol, ToCol
function MatrSlice<T>(Self: array[,] of T; FromRow, ToRow, FromCol, ToCol: integer): array[,] of T; extensionmethod;
begin
if not InR(FromRow,0,Self.RowCount-1) then
raise new System.ArgumentOutOfRangeException(GetTranslation(BAD_ROW_INDEX_FROM),new Exception);
if not InR(ToRow,0,Self.RowCount-1) then raise new System.ArgumentOutOfRangeException(GetTranslation(BAD_ROW_INDEX_TO),new Exception);
if not InR(FromCol,0,Self.ColCount-1) then
raise new System.ArgumentOutOfRangeException(GetTranslation(BAD_COL_INDEX_FROM),new Exception);
if not InR(ToCol,0,Self.ColCount-1) then
raise new System.ArgumentOutOfRangeException(GetTranslation(BAD_COL_INDEX_TO),new Exception);
Result := new T[ToRow-FromRow+1, ToCol-FromCol+1];
var r := 0;
for var ir:=FromRow to ToRow do
begin
var c := 0;
for var jc:=FromCol to ToCol do
begin
Result[r, c] := Self[ir, jc];
c += 1;
end;
r += 1;
end
end;
// -----------------------------------------------------
//>> Фиктивная секция YYY - не удалять! # YYY
// -----------------------------------------------------
function Matr<T>(m,n: integer; params data: array of T): array [,] of T;
begin
if data.Length<>m*n then
raise new System.ArgumentException(GetTranslation(INITELEM_COUNT_MUST_BE_EQUAL_TO_MATRIX_ELEMS_COUNT));
Result := new T[m, n];
var k := 0;
for var i:=0 to Result.RowCount-1 do
for var j:=0 to Result.ColCount-1 do
begin
Result[i,j] := data[k];
k += 1;
end;
end;
function Matr<T>(params aa: array of array of T): array [,] of T;
begin
var cols := aa.Max(a -> a.Length);
var r := new T[aa.Length,cols];
for var i:=0 to aa.Length-1 do
for var j:=0 to aa[i].Length-1 do
r[i,j] := aa[i][j];
Result := r;
end;
// Реализация операций с матрицами - только после введения RowCount и ColCount
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);
end;
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);
end;
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;
end;
function MatrFill<T>(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;
end;
function MatrGen<T>(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);
end;
function Transpose<T>(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]
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;
// -----------------------------------------------------
//>> Методы расширения одномерных динамических массивов # Extension methods for array of T
// -----------------------------------------------------
// Дополнения февраль 2016: Shuffle, AdjacentFind, IndexMin, IndexMax, Replace, Transform
// Статические методы - в методы расширения: BinarySearch, ConvertAll, Find, FindIndex, FindAll,
// FindLast, FindLastIndex, IndexOf, Contains, LastIndexOf, Reverse, Sort
/// Перемешивает элементы массива случайным образом
function Shuffle<T>(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;
end;
{/// Находит первую пару подряд идущих одинаковых элементов и возвращает индекс первого элемента пары. Если не найден, возвращается -1
function AdjacentFind<T>(Self: array of T; start: integer := 0): integer; extensionmethod;
begin
Result := -1;
for var i:=start to Self.Length-2 do
if Self[i]=Self[i+1] then
begin
Result := i;
exit;
end;
end;
/// Находит первую пару подряд идущих одинаковых элементов, используя функцию сравнения eq, и возвращает индекс первого элемента пары. Если не найден, возвращается -1
function AdjacentFind<T>(Self: array of T; eq: (T,T)->boolean; start: integer := 0): integer; extensionmethod;
begin
Result := -1;
for var i:=start to Self.Length-2 do
if eq(Self[i],Self[i+1]) then
begin
Result := i;
exit;
end;
end;}
/// Возвращает минимальный элемент
function Min<T>(Self: array of T): T; extensionmethod; where T: System.IComparable<T>;
begin
Result := Self[0];
for var i := 1 to Self.Length - 1 do
if Self[i].CompareTo(Result) < 0 then
Result := Self[i];
end;
/// Возвращает максимальный элемент
function Max<T>(Self: array of T): T; extensionmethod; where T: System.IComparable<T>;
begin
Result := Self[0];
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;
begin
Result := Self[0];
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;
begin
Result := Self[0];
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;
begin
Result := Self[0];
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;
begin
Result := Self[0];
for var i := 1 to Self.Length - 1 do
if Self[i] > Result then
Result := Self[i];
end;
{/// Возвращает индекс первого минимального элемента начиная с позиции index
function IndexMin<T>(Self: array of T; index: integer := 0): integer; extensionmethod; where T: System.IComparable<T>;
begin
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;
min := Self[i];
end;
end;
/// Возвращает индекс первого максимального элемента начиная с позиции index
function IndexMax<T>(self: array of T; index: integer := 0): integer; extensionmethod; where T: System.IComparable<T>;
begin
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;
max := Self[i];
end;
end;
/// Возвращает индекс последнего минимального элемента
function LastIndexMin<T>(Self: array of T): integer; extensionmethod; where T: System.IComparable<T>;
begin
var min := Self[Self.Length-1];
Result := Self.Length-1;
for var i:=Self.Length-2 downto 0 do
if Self[i].CompareTo(min)<0 then
begin
Result := i;
min := Self[i];
end;
end;
/// Возвращает индекс последнего минимального элемента в диапазоне [0,index]
function LastIndexMin<T>(Self: array of T; index: integer): integer; extensionmethod; where T: System.IComparable<T>;
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<T>(Self: array of T): integer; extensionmethod; where T: System.IComparable<T>;
begin
var max := Self[Self.Length-1];
Result := Self.Length-1;
for var i:=Self.Length-2 downto 0 do
if Self[i].CompareTo(max)>0 then
begin
Result := i;
max := Self[i];
end;
end;
/// Возвращает индекс последнего минимального элемента в диапазоне [0,index]
function LastIndexMax<T>(Self: array of T; index: integer): integer; extensionmethod; where T: System.IComparable<T>;
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<T>(Self: array of T; oldValue,newValue: T); extensionmethod;
begin
for var i:=0 to Self.Length-1 do
if Self[i] = oldValue then
Self[i] := newValue;
end;
/// Преобразует элементы массива по заданному правилу
procedure Transform<T>(self: array of T; f: T -> T); extensionmethod;
begin
for var i:=0 to Self.Length-1 do
Self[i] := f(Self[i]);
end;
/// Заполняет элементы массива значениями, вычисляемыми по некоторому правилу
procedure Fill<T>(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<T>(Self: array of T; x: T): integer; extensionmethod;
begin
Result := System.Array.BinarySearch(self, x);
end;
/// Преобразует элементы массива и возвращает преобразованный массив
function ConvertAll<T, T1>(Self: array of T; converter: T->T1): array of T1; extensionmethod;
begin
Result := System.Array.ConvertAll(self, t -> converter(t));
end;
/// Преобразует элементы массива и возвращает преобразованный массив
function ConvertAll<T, T1>(Self: array of T; converter: (T,integer)->T1): array of T1; extensionmethod;
begin
Result := new T1[Self.Length];
for var i := 0 to Self.Length - 1 do
Result[i] := converter(Self[i],i);
end;
/// Выполняет поиск первого элемента в массиве, удовлетворяющего предикату. Если не найден, возвращается нулевое значение соответствующего типа
function Find<T>(Self: array of T; p: T->boolean): T; extensionmethod;
begin
Result := System.Array.Find(self, p);
end;
/// Выполняет поиск индекса первого элемента в массиве, удовлетворяющего предикату. Если не найден, возвращается -1
function FindIndex<T>(Self: array of T; p: T->boolean): integer; extensionmethod;
begin
Result := System.Array.FindIndex(self, p);
end;
/// Выполняет поиск индекса первого элемента в массиве, удовлетворяющего предикату, начиная с индекса start. Если не найден, возвращается -1
function FindIndex<T>(Self: array of T; start: integer; p: T->boolean): integer; extensionmethod;
begin
Result := System.Array.FindIndex(self, start, p);
end;
/// Возвращает в виде массива все элементы, удовлетворяющие предикату
function FindAll<T>(Self: array of T; p: T->boolean): array of T; extensionmethod;
begin
Result := System.Array.FindAll(self, p);
end;
/// Выполняет поиск последнего элемента в массиве, удовлетворяющего предикату. Если не найден, возвращается нулевое значение соответствующего типа
function FindLast<T>(Self: array of T; p: T->boolean): T; extensionmethod;
begin
Result := System.Array.FindLast(self, p);
end;
/// Выполняет поиск индекса последнего элемента в массиве, удовлетворяющего предикату. Если не найден, возвращается -1
function FindLastIndex<T>(Self: array of T; p: T->boolean): integer; extensionmethod;
begin
Result := System.Array.FindLastIndex(self, p);
end;
/// Выполняет поиск индекса последнего элемента в массиве, удовлетворяющего предикату, в диапазоне индексов от 0 до start. Если не найден, возвращается -1
function FindLastIndex<T>(self: array of T; start: integer; p: T->boolean): integer; extensionmethod;
begin
Result := System.Array.FindLastIndex(Self, start, p);
end;
/// Возвращает индекс первого вхождения элемента или -1 если элемент не найден
function IndexOf<T>(Self: array of T; x: T): integer; extensionmethod;
begin
Result := System.Array.IndexOf(Self, x);
end;
/// Возвращает индекс первого вхождения элемента начиная с индекса start или -1 если элемент не найден
function IndexOf<T>(Self: array of T; x: T; start: integer): integer; extensionmethod;
begin
Result := System.Array.IndexOf(Self, x, start);
end;
/// Возвращает индекс последнего вхождения элемента или -1 если элемент не найден
function LastIndexOf<T>(Self: array of T; x: T): integer; extensionmethod;
begin
Result := System.Array.LastIndexOf(Self, x);
end;
/// Возвращает индекс последнего вхождения элемента начиная с индекса start или -1 если элемент не найден
function LastIndexOf<T>(Self: array of T; x: T; start: integer): integer; extensionmethod;
begin
Result := System.Array.LastIndexOf(Self, x, start);
end;
/// Сортирует массив по возрастанию
procedure Sort<T>(Self: array of T); extensionmethod;
begin
System.Array.Sort(Self);
end;
/// Сортирует массив по возрастанию, используя cmp в качестве функции сравнения элементов
procedure Sort<T>(Self: array of T; cmp: (T,T) ->integer); extensionmethod;
begin
System.Array.Sort(Self, cmp);
end;
/// Возвращает индекс последнего элемента массива
function High(Self: System.Array); extensionmethod := High(Self);
/// Возвращает индекс первого элемента массива
function Low(Self: System.Array); extensionmethod := Low(Self);
/// Возвращает последовательность индексов одномерного массива
function Indices<T>(Self: array of T): sequence of integer; extensionmethod := Range(0, Self.Length - 1);
/// Возвращает последовательность индексов элементов одномерного массива, удовлетворяющих условию
function Indices<T>(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 Indices<T>(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<T>(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
begin
Result[i] := Self[f];
f += step;
end;
end;
///--
function SliceArrayImpl<T>(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)
end;
/// Возвращает срез массива от индекса from с шагом step
function Slice<T>(Self: array of T; from, step: integer): array of T; extensionmethod;
begin
Result := SliceArrayImpl(Self, from, step, integer.MaxValue);
end;
/// Возвращает срез массива от индекса from с шагом step длины не более count
function Slice<T>(Self: array of T; from, step, count: integer): array of T; extensionmethod;
begin
Result := SliceArrayImpl(Self, from, step, count);
end;
///--
function SystemSliceArrayImpl<T>(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);
{if (step = 1) and (count>32) then // 32 - empirical
begin
Result := new T[count];
System.Array.Copy(Self,from,Result,0,count);
end
else} Result := CreateSliceFromArrayInternal(Self, from, step, count)
end;
///--
function SystemSlice<T>(Self: array of T; situation: integer; from, &to: integer): array of T; extensionmethod;
begin
Result := SystemSliceArrayImpl(Self, situation, from, &to, 1);
end;
///--
function SystemSlice<T>(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<T>(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<T>(Self: array of T; situation: integer; from, &to: integer): array of T; extensionmethod;
begin
Result := SystemSliceArrayImplQuestion(Self, situation, from, &to, 1);
end;
///--
function SystemSliceQuestion<T>(Self: array of T; situation: integer; from, &to, step: integer): array of T; extensionmethod;
begin
Result := SystemSliceArrayImplQuestion(Self, situation, from, &to, step);
end;
// -----------------------------------------------------
//>> Методы расширения типа integer # Extension methods for integer
// -----------------------------------------------------
/// Возвращает квадратный корень числа
function Sqrt(Self: integer): real; extensionmethod;
begin
Result := Sqrt(Self);
end;
/// Возвращает квадрат числа
function Sqr(Self: integer): integer; extensionmethod;
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;
///--
function InRangeInternal(x: integer; a,b: integer): boolean;
begin
Result := (a <= x) and (x <= b)
end;
///--
function InRangeInternal(x: char; a,b: char): boolean;
begin
Result := (a <= x) and (x <= b)
end;
// Дополнения февраль 2016: IsEven, IsOdd
/// Возвращает, является ли целое четным
function IsEven(Self: integer): boolean; extensionmethod;
begin
Result := Self mod 2 = 0;
end;
/// Возвращает, является ли целое нечетным
function IsOdd(Self: integer): boolean; extensionmethod;
begin
Result := Self mod 2 <> 0;
end;
/// Возвращает последовательность чисел от 1 до данного
function Range(Self: integer): sequence of integer; extensionmethod;
begin
Result := Range(1, Self);
end;
// Дополнения февраль 2016: &To, &Downto, Times
/// Генерирует последовательность целых от текущего значения до n
function &To(Self: integer; n: integer): sequence of integer; extensionmethod;
begin
Result := Range(Self, n);
end;
/// Генерирует последовательность целых от текущего значения до n в убывающем порядке
function &Downto(Self: integer; n: integer): sequence of integer; extensionmethod;
begin
Result := Range(Self, n, -1);
end;
/// Возвращает последовательность целых 0,1,...n-1
function Times(Self: integer): sequence of integer; extensionmethod;
begin
Result := Range(0, Self - 1);
end;
/// Возвращает число, ограниченное диапазоном от bottom до top включительно
function Clamp(Self: integer; bottom,top: integer): integer; extensionmethod;
begin
if Self < bottom then
Result := bottom
else if Self > top then
Result := top
else Result := Self;
end;
/// Возвращает число, ограниченное величиной top сверху
function ClampTop(Self: integer; top: integer): integer; extensionmethod;
begin
if Self > top then
Result := top
else Result := Self;
end;
/// Возвращает число, ограниченное величиной bottom снизу
function ClampBottom(Self: integer; bottom: integer): integer; extensionmethod;
begin
if Self < bottom then
Result := bottom
else Result := Self;
end;
// -----------------------------------------------------
//>> Методы расширения типа BigInteger # Extension methods for BigInteger
// -----------------------------------------------------
/// Возвращает квадратный корень числа
function Sqrt(Self: BigInteger): real; extensionmethod;
begin
Result := Sqrt(real(Self));
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;
/// Возвращает True если значение находится между двумя другими
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
Result := Sqrt(Self);
end;
/// Возвращает квадрат числа
function Sqr(Self: real): real; extensionmethod;
begin
Result := Sqr(Self);
end;
/// Возвращает число, округленное до ближайшего целого
function Round(Self: real): integer; extensionmethod;
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
Result := RoundBigInteger(Self);
end;
/// Возвращает целую часть вещественного числа
function Trunc(Self: real): integer; extensionmethod;
begin
Result := Trunc(Self);
end;
/// Возвращает целую часть вещественного числа как длинное целое
function TruncBigInteger(Self: real): BigInteger; extensionmethod;
begin
Result := TruncBigInteger(Self);
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)
end;
/// Возвращает число, ограниченное диапазоном от bottom до top включительно
function Clamp(Self: real; bottom,top: real): real; extensionmethod;
begin
if Self < bottom then
Result := bottom
else if Self > top then
Result := top
else Result := Self;
end;
/// Возвращает число, ограниченное величиной top сверху
function ClampTop(Self: real; top: real): real; extensionmethod;
begin
if Self > top then
Result := top
else Result := Self;
end;
/// Возвращает число, ограниченное величиной bottom снизу
function ClampBottom(Self: real; bottom: real): real; extensionmethod;
begin
if Self < bottom then
Result := bottom
else Result := Self;
end;
//------------------------------------------------------------------------------
//>> Методы расширения типа char # Extension methods for char
//------------------------------------------------------------------------------
/// Возвращает True если значение находится между двумя другими
function Between(Self: char; a, b: char): boolean; extensionmethod;
begin
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); extensionmethod := PABCSystem.Succ(Self);
/// Код символа в кодировке Unicode
function Code(Self: char): integer; extensionmethod := word(Self);
/// Является ли символ цифрой
function IsDigit(Self: char); extensionmethod := char.IsDigit(Self);
/// Является ли символ буквой
function IsLetter(Self: char): boolean; extensionmethod;
begin
Result := char.IsLetter(Self);
end;
/// Принадлежит ли символ к категории букв нижнего регистра
function IsLower(Self: char): boolean; extensionmethod;
begin
Result := char.IsLower(Self);
end;
/// Принадлежит ли символ к категории букв верхнего регистра
function IsUpper(Self: char): boolean; extensionmethod;
begin
Result := char.IsUpper(Self);
end;
/// Преобразует символ в цифру
function ToDigit(Self: char): integer; extensionmethod;
begin
Result := OrdUnicode(Self) - OrdUnicode('0');
if (Result < 0) or (Result >= 10) then
raise new System.FormatException('not a Digit');
end;
/// Преобразует символ в нижний регистр
function ToLower(Self: char): char; extensionmethod;
begin
Result := char.ToLower(Self);
end;
/// Преобразует символ в верхний регистр
function ToUpper(Self: char): char; extensionmethod;
begin
Result := char.ToUpper(Self);
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
Result := ReadIntegerFromString(Self, from);
end;
/// Считывает вещественное из строки начиная с позиции from и устанавливает from за считанным значением
function ReadReal(Self: string; var from: integer): real; extensionmethod;
begin
Result := ReadRealFromString(Self, from);
end;
/// Считывает слово из строки начиная с позиции from и устанавливает from за считанным значением
function ReadWord(Self: string; var from: integer): string; extensionmethod;
begin
Result := ReadwordFromString(Self, from);
end;
/// Преобразует строку в целое
function ToInteger(Self: string): integer; extensionmethod := StrToInt(Self);
/// Преобразует строку в BigInteger
function ToBigInteger(Self: string): BigInteger; extensionmethod := BigInteger.Parse(Self);
/// Преобразует строку в вещественное
function ToReal(Self: string): real; extensionmethod := real.Parse(Self, nfi);
/// Преобразует строку в целое и записывает его в value.
///При невозможности преобразования возвращается False
function TryToInteger(Self: string; var value: integer): boolean; extensionmethod := TryStrToInt(Self,value);
/// Преобразует строку в вещественное и записывает его в value.
///При невозможности преобразования возвращается False
function TryToReal(Self: string; var value: real): boolean; extensionmethod := TryStrToReal(Self,value);
/// Преобразует строку в целое
///При невозможности преобразования возвращается defaultvalue
function ToInteger(Self: string; defaultvalue: integer): integer; extensionmethod;
begin
var b := TryStrToInt(Self,Result);
if not b then
Result := defaultvalue
end;
/// Преобразует строку в вещественное
///При невозможности преобразования возвращается defaultvalue
function ToReal(Self: string; defaultvalue: real): real; extensionmethod;
begin
var b := TryStrToReal(Self,Result);
if not b then
Result := defaultvalue
end;
/// Преобразует строку в массив слов
function ToWords(Self: string; params delim: array of char): array of string; extensionmethod;
begin
Result := Self.Split(delim, System.StringSplitOptions.RemoveEmptyEntries);
end;
procedure PassSpaces(var s: string; var from: integer);
begin
while (from <= s.Length) and (s[from]=' ') do
from += 1;
end;
/// Преобразует строку в массив целых
function ToIntegers(Self: string): array of integer; extensionmethod;
begin
//Result := Self.ToWords().ConvertAll(s -> StrToInt(s));
// SSM ускорение в 5 раз 19.01.20
var l := new List<integer>(10);
var from := 1;
while from <= Self.Length do
begin
l.Add(ReadIntegerFromString(Self,from));
PassSpaces(Self,from);
end;
Result := l.ToArray;
end;
/// Считывает из строки массив из N целых
function ToIntegers(Self: string; N: integer): array of integer; extensionmethod;
begin
// SSM Скорость работы на 30% выше чем у ToIntegers без параметров
Result := new integer[N];
var from := 1;
for var i:=0 to N-1 do
Result[i] := Self.ReadInteger(from);
end;
/// Преобразует строку в массив вещественных
function ToReals(Self: string): array of real; extensionmethod;
begin
Result := Self.ToWords().ConvertAll(s -> StrToFloat(s));
end;
/// Возвращает инверсию строки
function Inverse(Self: string): string; extensionmethod;
begin
var sb := new System.Text.StringBuilder(Self.Length);
for var i := Self.Length downto 1 do
sb.Append(Self[i]);
Result := sb.ToString;
end;
// Дополнения февраль 2016: Matches, MatchValue, MatchValues, IsMatch, RegexReplace, Remove, Right, Left
/// Заменяет в указанной строке все вхождения регулярного выражения указанной строкой замены и возвращает преобразованную строку
function RegexReplace(Self: string; reg, repl: string; options: RegexOptions := RegexOptions.None): string; extensionmethod;
begin
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>();
end;
/// Ищет в указанной строке первое вхождение регулярного выражения и возвращает его в виде строки
function MatchValue(Self: string; reg: string; options: RegexOptions := RegexOptions.None): string; extensionmethod;
begin
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);
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();
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)
else Result := Self;
end;
/// Возвращает подстроку, полученную вырезанием из строки length самых левых символов
function Left(Self: string; length: integer): string; extensionmethod;
begin
length := Max(length, 0);
if Self.Length > length then
Result := Self.Substring(0, length)
else Result := Self;
end;
function PrefixFunction(s: string): array of integer;
// возвращает массив граней для строки-аргумента
begin
var n := s.Length;
Result := ArrFill(n + 1, 0);
for var i := 1 to n - 1 do
begin
var temp := Result[i];
while (temp > 0) and (s[i + 1] <> s[temp + 1]) do
temp := Result[temp];
Result[i + 1] := s[i + 1] = s[temp + 1] ? temp + 1 : 0
end
end;
/// Возвращает массив индексов вхождений подстроки в основную строку
///Параметр overlay определяет, разрешены ли перекрытия вхождений подстрок
function IndicesOf(Self, SubS: string; overlay: boolean := False): array of integer; extensionmethod;
// Реализует КМП-алгоритм.
// Возвращает массив начальных позиций вхождений подстроки P в строку
// Параметр overlay определяет, разрешены ли перекрытия положений подстрок.
begin
var L := new List<integer>;
var (n, m) := (Self.Length, SubS.Length);
var border := PrefixFunction(SubS);
var temp := 0;
for var i := 1 to n do
begin
while (temp > 0) and (SubS[temp + 1] <> Self[i]) do
temp := border[temp];
if SubS[temp + 1] = Self[i] then
temp += 1;
if temp = m then
begin
var pos := i - m + 1;
if overlay or (L.Count = 0) or (pos >= L[L.Count - 1] + m) then
L.Add(pos);
temp := border[m]
end;
end;
Result := L.Select(i -> i - 1).ToArray
end;
///--
function CreateSliceFromStringInternal(Self: string; from, step, count: integer): string;
begin
var res := new StringBuilder(count);
loop count do
begin
res.Append(Self[from]);
from += step;
end;
Result := res.ToString;
end;
///--
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);
end;
/// Возвращает срез строки от индекса from с шагом step
function Slice(Self: string; from, step: integer): string; extensionmethod;
begin
Result := SliceStringImpl(Self, from, step, integer.MaxValue);
end;
/// Возвращает срез строки от индекса from с шагом step длины не более count
function Slice(Self: string; from, step, count: integer): string; extensionmethod;
begin
Result := SliceStringImpl(Self, from, step, count);
end;
///--
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);
if step = 1 then // Opt s[a:b]
Result := Self.Substring(fromv,count)
else Result := CreateSliceFromStringInternal(Self, fromv + 1, step, count)
end;
///--
function SystemSlice(Self: string; situation: integer; from, &to: integer): string; extensionmethod;
begin
Result := SystemSliceStringImpl(Self, situation, from, &to, 1);
end;
///--
function SystemSlice(Self: string; situation: integer; from, &to, step: integer): string; extensionmethod;
begin
Result := SystemSliceStringImpl(Self, situation, from, &to, step);
end;
///--
function SystemSliceStringImplQuestion(Self: string; situation: integer; from, &to: integer; step: integer := 1): string;
begin
var fromv := from - 1;
var tov := &to - 1;
var count := CorrectFromToAndCalcCountForSystemSliceQuestion(situation, Self.Length, fromv, tov, step);
Result := CreateSliceFromStringInternal(Self, fromv + 1, step, count);
end;
///--
function SystemSliceQuestion(Self: string; situation: integer; from, &to: integer): string; extensionmethod;
begin
Result := SystemSliceStringImplQuestion(Self, situation, from, &to, 1);
end;
///--
function SystemSliceQuestion(Self: string; situation: integer; from, &to, step: integer): string; extensionmethod;
begin
Result := SystemSliceStringImplQuestion(Self, situation, from, &to, step);
end;
//--------------------------------------------
//>> Методы расширения типа Func # Extension methods for Func
//--------------------------------------------
/// Суперпозиция функций
function Compose<T1, T2, TResult>(Self: T2->TResult; composer: T1->T2): T1->TResult; extensionmethod;
begin
if composer = nil then
raise new System.ArgumentNullException('composer');
var Slf := Self;
Result := x -> Slf(composer(x));
end;
//------------------------------------------------------------------------------
//>> Методы расширения типа Complex # Extension methods for Complex
//------------------------------------------------------------------------------
/// Возвращает комплексно сопряженное значение
function Conjugate(Self: Complex): Complex; extensionmethod;
begin
Result := Complex.Conjugate(Self);
end;
// -----------------------------------------------------------------------------
//>> Методы расширения словарей # Extension methods for IDictionary
// -----------------------------------------------------------------------------
/// Возвращает в словаре значение, связанное с указанным ключом, а если такого ключа нет, то значение по умолчанию
function Get<Key, Value>(Self: IDictionary<Key, Value>; K: Key): Value; extensionmethod;
begin
var b := Self.TryGetValue(K, Result);
if not b then
Result := default(Value);
end;
/// Возвращает словарь, сопоставляющий ключу группы количество элементов с данным ключом
function EachCount<Key,Source>(Self: sequence of System.Linq.IGrouping<Key,Source>): Dictionary<Key,integer>; extensionmethod;
begin
Result := Self.ToDictionary(g -> g.Key, g -> g.Count);
end;
/// Возвращает словарь, сопоставляющий ключу группы результат групповой операции
function Each<Key,Source,Res>(Self: sequence of System.Linq.IGrouping<Key,Source>; grOperation: System.Linq.IGrouping<Key,Source> -> Res): Dictionary<Key,Res>; extensionmethod;
begin
Result := Self.ToDictionary(g -> g.Key, g -> grOperation(g));
end;
/// Операция удаления из словаря пары с указанным значением ключа
procedure operator-=<Key,Value>(Self: IDictionary<Key,Value>; k: Key); extensionmethod;
begin
Self.Remove(k);
end;
//{{{--doc: Конец методов расширения }}}
//------------------------------------------------------------------------------
// Операции для Func
//------------------------------------------------------------------------------
///--
function operator*<T1, T2, TResult>(Self: T2->TResult; composer: T1->T2): T1->TResult; extensionmethod;
begin
if composer = nil then
raise new System.ArgumentNullException('composer');
Result := Self.Compose(composer);
end;
//------------------------------------------------------------------------------
// Операции для Tuple
//------------------------------------------------------------------------------
///--
function operator+<T1, T2, T3>(Self: (T1, T2); v: T3): (T1, T2, T3); extensionmethod;
begin
Result := (Self[0], Self[1], v);
end;
///--
function operator+<T1, T2, T3, T4>(Self: (T1, T2, T3); v: T4): (T1, T2, T3, T4); extensionmethod;
begin
Result := (Self[0], Self[1], Self[2], v);
end;
///--
function operator+<T1, T2, T3, T4, T5>(Self: (T1, T2, T3, T4); v: T5): (T1, T2, T3, T4, T5); extensionmethod;
begin
Result := (Self[0], Self[1], Self[2], Self[3], v);
end;
///--
function operator+<T1, T2, T3, T4, T5, T6>(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);
end;
///--
function operator+<T1, T2, T3, T4, T5, T6, T7>(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);
end;
///--
function InternalEqual<T1, T2> (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=<T1, T2> (x: (T1,T2); y: (T1,T2)): boolean; extensionmethod := InternalEqual(x,y);
///--
function operator<><T1, T2> (x: (T1,T2); y: (T1,T2)): boolean; extensionmethod := not InternalEqual(x,y);
///--
function CompareToTup2<T1, T2>(v1: (T1, T2); v2: (T1, T2)) := (v1 as System.IComparable).CompareTo(v2);
///--
function operator<<T1, T2>(Self: (T1, T2); v: (T1, T2)); extensionmethod := CompareToTup2(Self, v) < 0;
///--
function operator<=<T1, T2>(Self: (T1, T2); v: (T1, T2)); extensionmethod := CompareToTup2(Self, v) <= 0;
///--
function operator><T1, T2>(Self: (T1, T2); v: (T1, T2)); extensionmethod := CompareToTup2(Self, v) > 0;
///--
function operator>=<T1, T2>(Self: (T1, T2); v: (T1, T2)); extensionmethod := CompareToTup2(Self, v) >= 0;
///--
function InternalEqual<T1, T2, T3> (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=<T1, T2, T3> (x: (T1,T2,T3); y: (T1,T2,T3)); extensionmethod := InternalEqual(x,y);
///--
function operator<><T1, T2, T3> (x: (T1,T2,T3); y: (T1,T2,T3)); extensionmethod := not InternalEqual(x,y);
///--
function CompareToTup3<T1, T2, T3>(v1: (T1, T2, T3); v2: (T1, T2, T3)) := (v1 as System.IComparable).CompareTo(v2);
///--
function operator<<T1,T2,T3>(Self: (T1, T2, T3); v: (T1, T2, T3)); extensionmethod := CompareToTup3(Self, v) < 0;
///--
function operator<=<T1,T2,T3>(Self: (T1, T2, T3); v: (T1, T2, T3)); extensionmethod := CompareToTup3(Self, v) <= 0;
///--
function operator><T1,T2,T3>(Self: (T1, T2, T3); v: (T1, T2, T3)); extensionmethod := CompareToTup3(Self, v) > 0;
///--
function operator>=<T1,T2,T3>(Self: (T1, T2, T3); v: (T1, T2, T3)); extensionmethod := CompareToTup3(Self, v) >= 0;
///--
function InternalEqual<T1, T2, T3, T4> (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=<T1, T2, T3, T4> (x: (T1,T2,T3,T4); y: (T1,T2,T3,T4)); extensionmethod := InternalEqual(x,y);
///--
function operator<><T1, T2, T3, T4> (x: (T1,T2,T3,T4); y: (T1,T2,T3,T4)); extensionmethod := not InternalEqual(x,y);
///--
function CompareToTup4<T1, T2, T3, T4>(v1: (T1, T2, T3, T4); v2: (T1, T2, T3, T4)) := (v1 as System.IComparable).CompareTo(v2);
///--
function operator<<T1,T2,T3,T4>(Self: (T1, T2, T3, T4); v: (T1, T2, T3, T4)); extensionmethod := CompareToTup4(Self, v) < 0;
///--
function operator<=<T1,T2,T3,T4>(Self: (T1, T2, T3, T4); v: (T1, T2, T3, T4)); extensionmethod := CompareToTup4(Self, v) <= 0;
///--
function operator><T1,T2,T3,T4>(Self: (T1, T2, T3, T4); v: (T1, T2, T3, T4)); extensionmethod := CompareToTup4(Self, v) > 0;
///--
function operator>=<T1,T2,T3,T4>(Self: (T1, T2, T3, T4); v: (T1, T2, T3, T4)); extensionmethod := CompareToTup4(Self, v) >= 0;
///--
function InternalEqual<T1, T2, T3, T4, T5> (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=<T1, T2, T3, T4,T5> (x: (T1,T2,T3,T4,T5); y: (T1,T2,T3,T4,T5)); extensionmethod := InternalEqual(x,y);
///--
function operator<><T1, T2, T3, T4,T5> (x: (T1,T2,T3,T4,T5); y: (T1,T2,T3,T4,T5)); extensionmethod := not InternalEqual(x,y);
///--
function CompareToTup5<T1, T2, T3, T4,T5>(v1: (T1, T2, T3, T4,T5); v2: (T1, T2, T3, T4,T5)) := (v1 as System.IComparable).CompareTo(v2);
///--
function operator<<T1,T2,T3,T4,T5>(Self: (T1, T2, T3, T4,T5); v: (T1, T2, T3, T4,T5)); extensionmethod := CompareToTup5(Self, v) < 0;
///--
function operator<=<T1,T2,T3,T4,T5>(Self: (T1, T2, T3, T4,T5); v: (T1, T2, T3, T4,T5)); extensionmethod := CompareToTup5(Self, v) <= 0;
///--
function operator><T1,T2,T3,T4,T5>(Self: (T1, T2, T3, T4,T5); v: (T1, T2, T3, T4,T5)); extensionmethod := CompareToTup5(Self, v) > 0;
///--
function operator>=<T1,T2,T3,T4,T5>(Self: (T1, T2, T3, T4,T5); v: (T1, T2, T3, T4,T5)); extensionmethod := CompareToTup5(Self, v) >= 0;
///--
function InternalEqual<T1, T2, T3, T4, T5, T6> (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=<T1, T2, T3, T4,T5,T6> (x: (T1,T2,T3,T4,T5,T6); y: (T1,T2,T3,T4,T5,T6)); extensionmethod := InternalEqual(x,y);
///--
function operator<><T1, T2, T3, T4,T5,T6> (x: (T1,T2,T3,T4,T5,T6); y: (T1,T2,T3,T4,T5,T6)); extensionmethod := not InternalEqual(x,y);
///--
function CompareToTup5<T1, T2, T3, T4,T5,T6>(v1: (T1, T2, T3, T4,T5,T6); v2: (T1, T2, T3, T4,T5,T6)) := (v1 as System.IComparable).CompareTo(v2);
///--
function operator<<T1,T2,T3,T4,T5,T6>(Self: (T1, T2, T3, T4,T5,T6); v: (T1, T2, T3, T4,T5,T6)); extensionmethod := CompareToTup5(Self, v) < 0;
///--
function operator<=<T1,T2,T3,T4,T5,T6>(Self: (T1, T2, T3, T4,T5,T6); v: (T1, T2, T3, T4,T5,T6)); extensionmethod := CompareToTup5(Self, v) <= 0;
///--
function operator><T1,T2,T3,T4,T5,T6>(Self: (T1, T2, T3, T4,T5,T6); v: (T1, T2, T3, T4,T5,T6)); extensionmethod := CompareToTup5(Self, v) > 0;
///--
function operator>=<T1,T2,T3,T4,T5,T6>(Self: (T1, T2, T3, T4,T5,T6); v: (T1, T2, T3, T4,T5,T6)); extensionmethod := CompareToTup5(Self, v) >= 0;
///--
function InternalEqual<T1, T2, T3, T4, T5, T6, T7> (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=<T1, T2, T3, T4,T5,T6,T7> (x: (T1,T2,T3,T4,T5,T6,T7); y: (T1,T2,T3,T4,T5,T6,T7)); extensionmethod := InternalEqual(x,y);
///--
function operator<><T1, T2, T3, T4,T5,T6,T7> (x: (T1,T2,T3,T4,T5,T6,T7); y: (T1,T2,T3,T4,T5,T6,T7)); extensionmethod := not InternalEqual(x,y);
///--
function CompareToTup5<T1, T2, T3, T4,T5,T6,T7>(v1: (T1, T2, T3, T4,T5,T6,T7); v2: (T1, T2, T3, T4,T5,T6,T7)) := (v1 as System.IComparable).CompareTo(v2);
///--
function operator<<T1,T2,T3,T4,T5,T6,T7>(Self: (T1, T2, T3, T4,T5,T6,T7); v: (T1, T2, T3, T4,T5,T6,T7)); extensionmethod := CompareToTup5(Self, v) < 0;
///--
function operator<=<T1,T2,T3,T4,T5,T6,T7>(Self: (T1, T2, T3, T4,T5,T6,T7); v: (T1, T2, T3, T4,T5,T6,T7)); extensionmethod := CompareToTup5(Self, v) <= 0;
///--
function operator><T1,T2,T3,T4,T5,T6,T7>(Self: (T1, T2, T3, T4,T5,T6,T7); v: (T1, T2, T3, T4,T5,T6,T7)); extensionmethod := CompareToTup5(Self, v) > 0;
///--
function operator>=<T1,T2,T3,T4,T5,T6,T7>(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<T1, T2, T3>(Self: (T1, T2); v: T3): (T1, T2, T3); extensionmethod;
begin
Result := (Self[0], Self[1], v);
end;
// Добавляет поле к кортежу
function Add<T1, T2, T3, T4>(Self: (T1, T2, T3); v: T4): (T1, T2, T3, T4); extensionmethod;
begin
Result := (Self[0], Self[1], Self[2], v);
end;
// Добавляет поле к кортежу
function Add<T1, T2, T3, T4, T5>(Self: (T1, T2, T3, T4); v: T5): (T1, T2, T3, T4, T5); extensionmethod;
begin
Result := (Self[0], Self[1], Self[2], Self[3], v);
end;
// Добавляет поле к кортежу
function Add<T1, T2, T3, T4, T5, T6>(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);
end;
// Добавляет поле к кортежу
function Add<T1, T2, T3, T4, T5, T6, T7>(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);
end;
// Выводит кортеж
procedure Print<T1, T2>(Self: (T1, T2)); extensionmethod := Print(Self);
// Выводит кортеж
procedure Print<T1, T2, T3>(Self: (T1, T2, T3)); extensionmethod := Print(Self);
// Выводит кортеж
procedure Print<T1, T2, T3, T4>(Self: (T1, T2, T3, T4)); extensionmethod := Print(Self);
// Выводит кортеж
procedure Print<T1, T2, T3, T4, T5>(Self: (T1, T2, T3, T4, T5)); extensionmethod := Print(Self);
// Выводит кортеж
procedure Print<T1, T2, T3, T4, T5, T6>(Self: (T1, T2, T3, T4, T5, T6)); extensionmethod := Print(Self);
// Выводит кортеж
procedure Print<T1, T2, T3, T4, T5, T6, T7>(Self: (T1, T2, T3, T4, T5, T6, T7)); extensionmethod := Print(Self);
// Выводит кортеж и переходит на новую строку
procedure Println<T1, T2>(Self: (T1, T2)); extensionmethod := Println(Self);
// Выводит кортеж и переходит на новую строку
procedure Println<T1, T2, T3>(Self: (T1, T2, T3)); extensionmethod := Println(Self);
// Выводит кортеж и переходит на новую строку
procedure Println<T1, T2, T3, T4>(Self: (T1, T2, T3, T4)); extensionmethod := Println(Self);
// Выводит кортеж и переходит на новую строку
procedure Println<T1, T2, T3, T4, T5>(Self: (T1, T2, T3, T4, T5)); extensionmethod := Println(Self);
// Выводит кортеж и переходит на новую строку
procedure Println<T1, T2, T3, T4, T5, T6>(Self: (T1, T2, T3, T4, T5, T6)); extensionmethod := Println(Self);
// Выводит кортеж и переходит на новую строку
procedure Println<T1, T2, T3, T4, T5, T6, T7>(Self: (T1, T2, T3, T4, T5, T6, T7)); extensionmethod := Println(Self);
{// Определяет, есть ли указанный элемент в массиве
function Contains<T>(self: array of T; x: T): boolean; extensionmethod;
begin
Result := System.Array.IndexOf(self,x)<>-1;
end;}
{// Изменяет порядок элементов в массиве на обратный
procedure Reverse<T>(self: array of T); extensionmethod;
begin
System.Array.Reverse(self);
end;
// Изменяет порядок элементов на обратный в диапазоне массива, заданном началом и длиной
procedure Reverse<T>(self: array of T; index,len: integer); extensionmethod;
begin
System.Array.Reverse(self,index,len);
end;}
//{{{ Конец секции реализации прикладных методов }}}
//{{{ Начало секции реализации внутренних системных методов }}}
// -----------------------------------------------------
// Standard Exceptions: implementation
// -----------------------------------------------------
constructor BadGenericInstanceParameterException.Create(ActualParameterType: System.Type);
begin
InstanceType := ActualParameterType;
end;
function CanNotUseTypeForPointersException.ToString: string;
begin
result := InstanceType.FullName + ' непригоден для указателей.';
end;
function CanNotUseTypeForTypedFilesException.ToString: string;
begin
result := InstanceType.FullName + ' непригоден для типизированных файлов.';
end;
function CanNotUseTypeForFilesException.ToString: string;
begin
result := InstanceType.FullName + ' непригоден для файлов.';
end;
// -----------------------------------------------------
// Internal System subprograms: implementation
// -----------------------------------------------------
function check_in_range(val: int64; low, up: int64): int64;
begin
if (val < low) or (val > up) then
raise new RangeException(GetTranslation(RANGE_ERROR_MESSAGE));
Result := val;
end;
function check_in_range_char(val: char; low, up: char): char;
begin
if (val < low) or (val > up) then
raise new RangeException(GetTranslation(RANGE_ERROR_MESSAGE));
Result := val;
end;
function RunTimeSizeOf(t: System.Type): integer;
var
t1: System.Type;
elem: object;
fa: array of System.Reflection.FieldInfo;
NullBasedArray: System.Array;
fi: System.Reflection.FieldInfo;
begin
if t.IsPrimitive or t.IsEnum then
//begin
case System.Type.GetTypeCode(t) of
TypeCode.Boolean: Result := sizeof(Boolean);
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);
else if t.IsEnum then Result := sizeof(integer);
end//;
//end
else
if t.IsValueType then // it is a record
begin
//elem := Activator.CreateInstance(t); //ssyy commented
fa := t.GetFields(System.Reflection.BindingFlags.GetField or System.Reflection.BindingFlags.Instance or System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.NonPublic);
Result := 0;
for var i := 0 to fa.Length - 1 do
if {not fa[i].IsStatic and} not fa[i].IsLiteral then
Result := Result + RunTimeSizeOf(fa[i].FieldType)
end
else if t = typeof(string) then
Result := 0
else
if t = typeof(TypedSet) then
begin
//elem := Activator.CreateInstance(t); //ssyy commented
Result := 256 div 8;
end
else
begin
fi := t.GetField(InternalNullBasedArrayName);
if fi = nil then
raise new SystemException(GetTranslation(BAD_TYPE_IN_RUNTIMESIZEOF));
elem := Activator.CreateInstance(t);
NullBasedArray := GetNullBasedArray(elem);
t1 := NullBasedArray.GetType.GetElementType;
Result := RunTimeSizeOf(t1) * NullBasedArray.Length;
end;
end;
// -----------------------------------------------------------------------------
// Внутренние функции для работы с короткими строками
// -----------------------------------------------------------------------------
[System.Diagnostics.DebuggerStepThrough]
function GetCharInShortString(s: string; ind, n: integer): char;
begin
if ind < 0 then
raise new IndexOutOfRangeException;
if ind = 0 then
Result := char(s.Length)
else
try
Result := s[ind];
except
on e: Exception do
if ind > n then raise;
end;
end;
[System.Diagnostics.DebuggerStepThrough]
function SetCharInShortString(s: string; ind, n: integer; c: char): string;
begin
if ind < 0 then
raise new IndexOutOfRangeException;
if ind <> 0 then
begin
var sb := new System.Text.StringBuilder();
sb.Append(s);
if ind - 1 < sb.Length then
sb[ind - 1] := c;
if ind > n then raise new IndexOutOfRangeException;
Result := sb.ToString;
end
else
begin
//Result := s.PadRight(integer(c));
raise new IndexOutOfRangeException;
end;
end;
[System.Diagnostics.DebuggerStepThrough]
function ClipShortString(s: string; len: integer): string;
begin
if s.Length <= len then
Result := s
else Result := s.Substring(0, len);
end;
function GetResourceStream(ResourceFileName: string): Stream;
begin
Result := System.Reflection.Assembly.GetEntryAssembly().GetManifestResourceStream(ResourceFileName);
end;
function FormatValue(value: object; NumOfChars: integer): string;
begin
if value <> nil then
Result := StructuredObjectToString(value)
else
Result := 'nil';
Result := Result.PadLeft(NumOfChars);
end;
function FormatValue(value: integer; NumOfChars: integer): string;
begin
Result := value.ToString;
Result := Result.PadLeft(NumOfChars);
end;
function FormatValue(value: int64; NumOfChars: integer): string;
begin
Result := value.ToString;
Result := Result.PadLeft(NumOfChars);
end;
function FormatValue(value: real; NumOfChars: integer): string;
begin
Result := value.ToString(nfi);
Result := Result.PadLeft(NumOfChars);
end;
function FormatValue(value: real; NumOfChars, NumOfSignesAfterDot: integer): string;
begin
// SSM 31.03.09
var FmtStr := '{0,' + NumOfChars.ToString + ':f' + abs(NumOfSignesAfterDot).ToString + '}';
Result := Format(FmtStr, value);
end;
procedure StringDefaultPropertySet(var s: string; index: integer; c: char);
begin
var chars := s.ToCharArray;
chars[index] := c;
s := new String(chars);
end;
procedure ChangeChar(var c: char; val: char);
begin
c := val;
end;
procedure CheckCanUsePointerOnType(T: System.Type);
begin
if T.IsPointer then
begin
CheckCanUsePointerOnType(T.GetElementType());
exit;
end;
if T.IsValueType then
begin
var fields := T.GetFields();
foreach var fi in fields do
if not fi.IsStatic then
CheckCanUsePointerOnType(fi.FieldType);
exit;
end;
raise new CanNotUseTypeForPointersException(T);
end;
procedure CheckCanUseTypeForFiles(T: System.Type; FileIsBinary: boolean);
var
fields: array of System.Reflection.FieldInfo;
begin
if T.IsPrimitive or T.IsEnum then
exit;
if T = typeof(TypedSet) then
begin
//TODO: обработать множества
raise new CanNotUseTypeForFilesException(T);
end;
if T = typeof(string) then
if FileIsBinary then
exit
else
raise new CanNotUseTypeForTypedFilesException(T);
if T.IsValueType then
begin
fields := T.GetFields();
foreach var fi in fields do
if not fi.IsStatic then
CheckCanUseTypeForFiles(fi.FieldType, FileIsBinary);
exit;
end;
raise new CanNotUseTypeForFilesException(T);
end;
procedure CheckCanUseTypeForBinaryFiles(T: System.Type);
begin
CheckCanUseTypeForFiles(T, true);
end;
procedure CheckCanUseTypeForTypedFiles(T: System.Type);
begin
CheckCanUseTypeForFiles(T, false);
end;
function RuntimeDetermineType(T: System.Type): byte;
begin
result := 0;
if T.IsValueType and (T.GetMethod('$Init$') <> nil) then
begin
result := 1;
exit;
end;
if T = typeof(string) then
begin
result := 2;
exit;
end;
if T = typeof(TypedSet) then
begin
result := 3;
exit;
end;
if T = typeof(Text) then
begin
result := 4;
exit;
end;
if T = typeof(BinaryFile) then
begin
result := 5;
exit;
end;
end;
function RuntimeInitialize(kind: byte; variable: object): object;
begin
case kind of
1:
begin
variable.GetType.InvokeMember('$Init$',
System.Reflection.BindingFlags.InvokeMethod or
System.Reflection.BindingFlags.Instance or
System.Reflection.BindingFlags.Public, nil, variable, nil);
result := variable;
end;
2: result := '';
3: result := new TypedSet;
4: result := new Text;
5: result := new BinaryFile;
end;
end;
function GetRuntimeSize<T>: integer;
var
val: T;
begin
result := System.Runtime.InteropServices.Marshal.SizeOf(val);
end;
// -----------------------------------------------------------------------------
// Внутренние вспомогательные функции
// -----------------------------------------------------------------------------
function get_sizes(a: &Array): array of integer;
begin
var rank := a.Rank;
Result := Result;
SetLength(Result, rank);
for var i := 0 to rank - 1 do
Result[i] := a.GetLength(i);
end;
procedure internal_copy(source, dest: &Array; source_sizes, dest_sizes: array of integer; i: integer; var src_ind, dest_ind: integer; flag: byte);
begin
if i <> source_sizes.Length - 1 then
begin
for var j := 0 to min(source_sizes[i], dest_sizes[i]) - 1 do
internal_copy(source, dest, source_sizes, dest_sizes, i + 1, src_ind, dest_ind, flag);
if dest_sizes[i] > source_sizes[i] then
for var j := source_sizes[i] to dest_sizes[i] - 1 do
begin
internal_copy(source, dest, source_sizes, dest_sizes, i + 1, src_ind, dest_ind, 1);
end
else
if dest_sizes[i] < source_sizes[i] then
for var j := dest_sizes[i] to source_sizes[i] - 1 do
begin
internal_copy(source, dest, source_sizes, dest_sizes, i + 1, src_ind, dest_ind, 2);
end
end
else
begin
if flag = 0 then
begin
System.Array.Copy(source, src_ind, dest, dest_ind, min(source_sizes[source_sizes.Length - 1], dest_sizes[source_sizes.Length - 1]));
src_ind += source_sizes[source_sizes.Length - 1];
dest_ind += dest_sizes[source_sizes.Length - 1];
end
else if flag = 1 then
dest_ind += dest_sizes[source_sizes.Length - 1]
else
src_ind += source_sizes[source_sizes.Length - 1];
end;
end;
function CopyWithSize(source, dest: &Array): &Array;
begin
if source <> nil then
begin
//System.Array.Copy(source,dest,min(source.Length,dest.Length));
var source_sizes := get_sizes(source);
var dest_sizes := get_sizes(dest);
var src_ind := 0;
var dest_ind := 0;
internal_copy(source, dest, source_sizes, dest_sizes, 0, src_ind, dest_ind, 0);
end;
Result := dest;
end;
{function TypedSetComparer.Equals(x: System.Object; y: System.Object): boolean;
begin
//Result := object.Equals(x,y);
Result := object.Equals(x, y);
if not Result then
begin
var left_type := x.GetType;
var right_type := y.GetType;
case System.Type.GetTypeCode(left_type) of
TypeCode.Byte:
begin
case System.Type.GetTypeCode(right_type) of
TypeCode.Byte: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.SByte: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.Int16: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.UInt16: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.Int32: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.UInt32: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.Int64: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.UInt64: Result := Convert.ToUInt64(x) = Convert.ToUInt64(y);
end;
end;
TypeCode.SByte:
begin
case System.Type.GetTypeCode(right_type) of
TypeCode.Byte: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.SByte: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.Int16: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.UInt16: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.Int32: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.UInt32: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.Int64: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.UInt64: Result := Convert.ToUInt64(x) = Convert.ToUInt64(y);
end;
end;
TypeCode.UInt16:
begin
case System.Type.GetTypeCode(right_type) of
TypeCode.Byte: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.SByte: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.Int16: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.UInt16: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.Int32: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.UInt32: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.Int64: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.UInt64: Result := Convert.ToUInt64(x) = Convert.ToUInt64(y);
end;
end;
TypeCode.Int16:
begin
case System.Type.GetTypeCode(right_type) of
TypeCode.Byte: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.SByte: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.Int16: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.UInt16: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.Int32: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.UInt32: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.Int64: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.UInt64: Result := Convert.ToUInt64(x) = Convert.ToUInt64(y);
end;
end;
TypeCode.Int32:
begin
case System.Type.GetTypeCode(right_type) of
TypeCode.Byte: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.SByte: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.Int16: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.UInt16: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.Int32: Result := Convert.ToInt32(x) = Convert.ToInt32(y);
TypeCode.UInt32: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.Int64: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.UInt64: Result := Convert.ToUInt64(x) = Convert.ToUInt64(y);
end;
end;
TypeCode.UInt32:
begin
case System.Type.GetTypeCode(right_type) of
TypeCode.Byte: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.SByte: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.Int16: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.UInt16: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.Int32: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.UInt32: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.Int64: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.UInt64: Result := Convert.ToUInt64(x) = Convert.ToUInt64(y);
end;
end;
TypeCode.Int64:
begin
case System.Type.GetTypeCode(right_type) of
TypeCode.Byte: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.SByte: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.Int16: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.UInt16: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.Int32: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.UInt32: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.Int64: Result := Convert.ToInt64(x) = Convert.ToInt64(y);
TypeCode.UInt64: Result := Convert.ToUInt64(x) = Convert.ToUInt64(y);
end;
end;
TypeCode.UInt64:
begin
case System.Type.GetTypeCode(right_type) of
TypeCode.Byte: Result := Convert.ToUInt64(x) = Convert.ToInt64(y);
TypeCode.SByte: Result := Convert.ToUInt64(x) = Convert.ToInt64(y);
TypeCode.Int16: Result := Convert.ToUInt64(x) = Convert.ToInt64(y);
TypeCode.UInt16: Result := Convert.ToUInt64(x) = Convert.ToInt64(y);
TypeCode.Int32: Result := Convert.ToUInt64(x) = Convert.ToInt64(y);
TypeCode.UInt32: Result := Convert.ToUInt64(x) = Convert.ToInt64(y);
TypeCode.Int64: Result := Convert.ToUInt64(x) = Convert.ToInt64(y);
TypeCode.UInt64: Result := Convert.ToUInt64(x) = Convert.ToUInt64(y);
end;
end;
end;
end;
end;
function TypedSetComparer.GetHashCode(obj: System.Object): integer;
begin
case System.Type.GetTypeCode(obj.GetType) of
TypeCode.Byte: Result := Convert.ToByte(obj);
TypeCode.SByte: Result := Convert.ToSByte(obj);
TypeCode.UInt16: Result := Convert.ToUInt16(obj);
TypeCode.Int16: Result := Convert.ToInt16(obj);
TypeCode.Int32: Result := Convert.ToInt32(obj);
TypeCode.UInt32: Result := Convert.ToUInt32(obj).GetHashCode();
TypeCode.Int64: Result := Convert.ToInt64(obj).GetHashCode();
TypeCode.UInt64: Result := Convert.ToUInt64(obj).GetHashCode();
else
Result := obj.GetHashCode();
end;
end;}
var
__from_dll := false;
function ExecuteAssemlyIsDll: boolean;
begin
Result := not __from_dll and (System.IO.Path.GetExtension(System.Reflection.Assembly.GetExecutingAssembly.ManifestModule.FullyQualifiedName).ToLower = '.dll');
end;
function IsUnix: boolean;
begin
Result := (Environment.OSVersion.Platform = PlatformID.Unix) or (Environment.OSVersion.Platform = PlatformID.MacOSX);
end;
function __StandardFilesDirectory: string;
begin
// Грубо. Исправить, сделав поиск
Result := 'C:\Program Files (x86)\PascalABC.NET\Files\';
end;
function __FindFile(filename: string): string;
begin
Result := __StandardFilesDirectory+filename;
if not FileExists(Result) then
Result := '';
if Result = '' then
Result := filename;
if not FileExists(Result) then
Result := '';
end;
function InternalRange(l,r: integer): IntRange := new IntRange(l,r);
function InternalRange(l,r: char): CharRange := new CharRange(l,r);
//------------------------------------------------------------------------------
//OMP
procedure omp_set_nested(nested: integer);
begin
OMP_NESTED := nested <> 0;
end;
function omp_get_nested: integer;
begin
if OMP_NESTED then
result := 1
else
result := 0;
end;
// -----------------------------------------------------
// Internal procedures for PABCRTL.dll: implementation
// -----------------------------------------------------
var
__initialized := false;
procedure __InitModule;
begin
DefaultEncoding := Encoding.GetEncoding(1251);
var arg := Environment.GetCommandLineArgs();
if arg.Length > 1 then begin
CommandLineArgs := new string[arg.Length - 1];
for var i := 1 to arg.Length - 1 do
CommandLineArgs[i - 1] := arg[i];
end else
CommandLineArgs := new string[0];
CurrentIOSystem := new IOStandardSystem;
// ENCultureInfo := new System.Globalization.CultureInfo('en-US');
var locale: object;
var locale_str := 'ru-RU';
if __CONFIG__.TryGetValue('full_locale', locale) then
locale_str := string(locale);
System.Threading.Thread.CurrentThread.CurrentUICulture := System.Globalization.CultureInfo.GetCultureInfo(locale_str);
nfi := new System.Globalization.NumberFormatInfo();
nfi.NumberGroupSeparator := '.';
{var ci := System.Globalization.CultureInfo.GetCultureInfo(locale_str);
ci.NumberFormat.NumberDecimalSeparator := '.';
System.Threading.Thread.CurrentThread.CurrentCulture := ci;
System.Threading.Thread.CurrentThread.CurrentUICulture := ci;}
// SSM 1.08.18 только в текущем потоке будет точка в вещественных
// В Net 4.6 System.Globalization.CultureInfo.DefaultThreadCurrentCulture := ci
// Но как сделать чтобы работало и в младших NET - не знаю
//var ci := (System.Globalization.CultureInfo.CurrentCulture.Clone as System.Globalization.CultureInfo);
//ci.NumberFormat := nfi;
//System.Globalization.CultureInfo.CurrentCulture := ci;
// SSM 10/11/18 восстановил эту строку чтобы в главном потоке в вещественных была точка
System.Threading.Thread.CurrentThread.CurrentCulture := new System.Globalization.CultureInfo('en-US');
//rnd := new System.Random;
output := new TextFile();
input := new TextFile();
//var tmp := __CONFIG__;
if (Environment.OSVersion.Platform = PlatformID.Unix) or (Environment.OSVersion.Platform = PlatformID.MacOSX) then
foreach var listener in System.Diagnostics.Trace.Listeners do
if listener is System.Diagnostics.DefaultTraceListener then
(listener as System.Diagnostics.DefaultTraceListener).AssertUiEnabled := true;
StartTime := DateTime.Now;
end;
procedure __InitModule__;
begin
if not __initialized then
begin
__initialized := true;
__from_dll := true;
__InitModule;
end;
end;
procedure __InitPABCSystem;
begin
__InitModule__;
end;
procedure __FinalizeModule__;
begin
if (output.sw <> nil) and (output.sw.BaseStream <> nil) then
output.sw.Close;
if (input.sr <> nil) and (input.sr.BaseStream <> nil) then
input.sr.Close;
end;
// -----------------------------------------------------
// DQNToNullable for dot_question_node: implementation
// -----------------------------------------------------
function DQNToNullable<T>(v: T): System.Nullable<T>; where T: record;
begin
Result := new System.Nullable<T>(v);
end;
initialization
__InitModule;
finalization
__FinalizeModule__;
end.