faststrings
EmptyCollection и преобразование ее в List, Dictionary
t: (real,real) := (1,2)
This commit is contained in:
Mikhalkovich Stanislav 2025-01-26 23:42:48 +03:00
parent bba132bd5d
commit 8fbd7fdfc3
11 changed files with 352 additions and 113 deletions

View file

@ -14,8 +14,8 @@ internal static class RevisionClass
{
public const string Major = "3";
public const string Minor = "10";
public const string Build = "2";
public const string Revision = "3597";
public const string Build = "3";
public const string Revision = "3602";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%COREVERSION%=3
%REVISION%=3602
%MINOR%=10
%REVISION%=3597
%COREVERSION%=2
%MAJOR%=3

View file

@ -0,0 +1,14 @@
// 6.0 sec PascalABC.NET vs 11.4 sec Python
begin
var mx := 0;
for var n := 4 to 9999 do
begin
var s: faststring := '4' + '1' * n;
while ('411' in s) or ('1111' in s) do
s.Replace('411', '14', 1).Replace('1111', '1', 1);
mx := max(mx, s.ToString.Sum(d -> d.todigit));
end;
print(mx, Milliseconds / 1000);
end.

View file

@ -1 +1 @@
3.10.2.3597
3.10.3.3602

View file

@ -1 +1 @@
!define VERSION '3.10.2.3597'
!define VERSION '3.10.3.3602'

View file

@ -5,6 +5,8 @@ using System.Text;
namespace PascalABCCompiler.SyntaxTree
{
// По идее из разных мест сюда всё собрано в три разных хаотичных класса
#region Генерация новых узлов синтаксического дерева
/// <summary>
/// Класс для генерации новых узлов синтаксического дерева
@ -295,11 +297,11 @@ namespace PascalABCCompiler.SyntaxTree
private static procedure_definition InternalCreateProcedureDefinitionNode(string methName, formal_parameters formalPars, bool classKeyword, statement procBody, SourceContext sc)
{
return SyntaxTreeNodesConstructor.CreateProcedureDefinitionNode(new method_name(methName),
formalPars,
false,
classKeyword,
procBody,
sc);
formalPars,
false,
classKeyword,
procBody,
sc);
}
public static procedure_definition CreateProcedureDefinitionNode(string methName, formal_parameters formalPars, bool classKeyword, statement procBody, SourceContext sc)
@ -315,12 +317,12 @@ namespace PascalABCCompiler.SyntaxTree
private static procedure_definition InternalCreateFunctionDefinitionNode(string methName, formal_parameters formalPars, bool classKeyword, statement procBody, type_definition returnType, SourceContext sc)
{
return SyntaxTreeNodesConstructor.CreateFunctionDefinitionNode(new method_name(methName),
formalPars,
false,
classKeyword,
procBody,
returnType,
sc);
formalPars,
false,
classKeyword,
procBody,
returnType,
sc);
}
public static procedure_definition CreateFunctionDefinitionNode(string methName, formal_parameters formalPars, bool classKeyword, statement procBody, type_definition returnType, SourceContext sc)
@ -355,10 +357,14 @@ namespace PascalABCCompiler.SyntaxTree
public static SourceContext BuildGenSC = new SourceContext(0, 777777, 0, 0, 0, 0);
private static int GenIdNum = 0;
public static ident GenIdentName()
public static string UniqueString()
{
GenIdNum++;
return new ident("$GenId" + GenIdNum.ToString());
return GenIdNum.ToString();
}
public static ident GenIdentName()
{
return new ident("$GenId" + UniqueString());
}
public static type_definition BuildSimpleType(string name)
@ -420,6 +426,23 @@ namespace PascalABCCompiler.SyntaxTree
return sl;
}
// SSM 25.01.25
public static procedure_definition BuildSimpleFunction(string name, List<ident> paramNames, List<type_definition> paramTypes, type_definition returnType, statement procBody, SourceContext sc = null)
{
var fp = SyntaxTreeBuilder.BuildFormalParameters(paramNames, paramTypes);
var fdn = SyntaxTreeNodesConstructor.CreateFunctionDefinitionNode(new method_name(name), fp, false, false, procBody, returnType, sc);
return fdn;
}
public static procedure_definition BuildSimpleFunctionOneParameter(string name, string paramName, type_definition paramType, type_definition returnType, statement procBody, SourceContext sc = null)
{
var lstNames = new List<ident>();
lstNames.Add(new ident(paramName));
var lstTypes = new List<type_definition>();
lstTypes.Add(paramType);
var fp = SyntaxTreeBuilder.BuildFormalParameters(lstNames, lstTypes);
var fdn = SyntaxTreeNodesConstructor.CreateFunctionDefinitionNode(new method_name(name), fp, false, false, procBody, returnType, sc);
return fdn;
}
public static procedure_definition BuildSimpleConstructor(List<ident> fields, List<ident> formal_names, List<type_definition> types)
{
var fp = SyntaxTreeBuilder.BuildFormalParameters(formal_names, types);

View file

@ -105,7 +105,7 @@ type
/// Представляет произвольно большое целое число
BigInteger = System.Numerics.BigInteger;
/// Представляет дату и время
DateTime = System.DateTime;
@ -181,6 +181,9 @@ type
/// Представляет изменяемую строку символов
StringBuilder = System.Text.StringBuilder;
/// Представляет строку с эффективным изменением
faststring = StringBuilder;
/// Тип кодировки символов
Encoding = System.Text.Encoding;
@ -483,7 +486,7 @@ type
end;}
type
NewSetEmpty = class;
EmptyCollection = class;
/// Тип встроенного множества
NewSet<T> = record(IEnumerable<T>)
@ -558,66 +561,77 @@ type
begin
Result._hs := new HashSet<T>(a);
end;
static function operator implicit(ns: NewSetEmpty): NewSet<T>; begin end;
static function operator:=(var s: NewSet<T>; st: NewSet<T>): NewSet<T>; // Эту функцию обязательно здесь определять
begin
s._hs := new HashSet<T>(st.hs);
end;
static function operator implicit(ns: EmptyCollection): NewSet<T>; begin end;
end;
NewSetEmpty = class
EmptyCollection = class
public
static function operator=<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := s1.Count = 0;
static function operator=<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := s1.Count = 0;
static function operator<><T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := not (s1 = s2);
static function operator<><T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := not (s1 = s2);
static function operator><T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := s1.Count > 0;
static function operator><T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := False;
static function operator<<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := False;
static function operator<<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := s1.Count > 0;
static function operator>=<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := s1.Count >= 0;
static function operator>=<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := False;
static function operator<=<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := False;
static function operator<=<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := s1.Count >= 0;
static function operator=<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := s1.Count = 0;
static function operator=<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := s1.Count = 0;
static function operator<><T>(s1: NewSet<T>; s2: EmptyCollection): boolean := not (s1 = s2);
static function operator<><T>(s2: EmptyCollection; s1: NewSet<T>): boolean := not (s1 = s2);
static function operator><T>(s1: NewSet<T>; s2: EmptyCollection): boolean := s1.Count > 0;
static function operator><T>(s2: EmptyCollection; s1: NewSet<T>): boolean := False;
static function operator<<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := False;
static function operator<<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := s1.Count > 0;
static function operator>=<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := s1.Count >= 0;
static function operator>=<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := False;
static function operator<=<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := False;
static function operator<=<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := s1.Count >= 0;
// ToDo: определить то же для массивов на будущее
static function operator+(first, second: NewSetEmpty): NewSetEmpty := new NewSetEmpty;
static function operator-(first, second: NewSetEmpty): NewSetEmpty := new NewSetEmpty;
static function operator*(first, second: NewSetEmpty): NewSetEmpty := new NewSetEmpty;
static function operator+<T>(first: NewSetEmpty; second: array of T): NewSet<T>;
static function operator+(first, second: EmptyCollection): EmptyCollection := new EmptyCollection;
static function operator-(first, second: EmptyCollection): EmptyCollection := new EmptyCollection;
static function operator*(first, second: EmptyCollection): EmptyCollection := new EmptyCollection;
static function operator+<T>(first: EmptyCollection; second: array of T): NewSet<T>;
begin
Result.hs.UnionWith(second);
end;
static function operator+<T>(first: array of T; second: NewSetEmpty): NewSet<T>;
static function operator+<T>(first: array of T; second: EmptyCollection): NewSet<T>;
begin
Result.hs.UnionWith(first);
end;
static function operator+<T>(first: NewSet<T>; second: NewSetEmpty): NewSet<T> := first;
static function operator+<T>(first: NewSetEmpty; second: NewSet<T>): NewSet<T> := second;
static function operator*<T>(first: NewSet<T>; second: NewSetEmpty): NewSet<T>; begin end;
static function operator*<T>(first: NewSetEmpty; second: NewSet<T>): NewSet<T>; begin end;
static function operator-<T>(first: NewSet<T>; second: NewSetEmpty): NewSet<T> := first;
static function operator-<T>(first: NewSetEmpty; second: NewSet<T>): NewSet<T>; begin end;
static function operator+<T>(first: NewSet<T>; second: EmptyCollection): NewSet<T> := first;
static function operator+<T>(first: EmptyCollection; second: NewSet<T>): NewSet<T> := second;
static function operator*<T>(first: NewSet<T>; second: EmptyCollection): NewSet<T>; begin end;
static function operator*<T>(first: EmptyCollection; second: NewSet<T>): NewSet<T>; begin end;
static function operator-<T>(first: NewSet<T>; second: EmptyCollection): NewSet<T> := first;
static function operator-<T>(first: EmptyCollection; second: NewSet<T>): NewSet<T>; begin end;
static function operator*<T>(first: NewSetEmpty; second: array of T): NewSet<T>; begin end;
static function operator*<T>(first: array of T; second: NewSetEmpty): NewSet<T>; begin end;
static function operator-<T>(first: NewSetEmpty; second: array of T): NewSet<T>; begin end;
static function operator-<T>(first: array of T; second: NewSetEmpty): NewSet<T>;
static function operator*<T>(first: EmptyCollection; second: array of T): NewSet<T>; begin end;
static function operator*<T>(first: array of T; second: EmptyCollection): NewSet<T>; begin end;
static function operator-<T>(first: EmptyCollection; second: array of T): NewSet<T>; begin end;
static function operator-<T>(first: array of T; second: EmptyCollection): NewSet<T>;
begin
Result.hs.UnionWith(first);
end;
function ToString: string; override := '{}';
function ToSet<T>(): NewSet<T>; begin end;
static function operator implicit<T>(Self: NewSetEmpty): array of T;
static function operator implicit<T>(Self: EmptyCollection): array of T;
begin
Result := new T[0];
Result := new T[0]//System.Array.Empty&<T>;
end;
static function operator implicit<T>(Self: NewSetEmpty): HashSet<T>;
static function operator implicit<T>(Self: EmptyCollection): HashSet<T>;
begin
Result := new HashSet<T>;
end;
static function operator implicit<T>(Self: EmptyCollection): SortedSet<T>;
begin
Result := new SortedSet<T>;
end;
static function operator implicit<T>(Self: EmptyCollection): List<T>;
begin
Result := new List<T>;
end;
static function operator implicit<K,V>(Self: EmptyCollection): Dictionary<K,V>;
begin
Result := new Dictionary<K,V>;
end;
end;
type
@ -667,7 +681,7 @@ type
end;
/// Значение пустого множества
function EmptySet: NewSetEmpty;
function EmptySet: EmptyCollection;
/// Генератор множества
function __NewSetCreatorInternal<T>(params a: array of T): NewSet<T>;
@ -14689,6 +14703,81 @@ begin
&to.IndexValue := Self.Count - &to.IndexValue + 1;
Result := SystemSliceStringImplQuestion(Self, situation, from.IndexValue, &to.IndexValue, step, 0);
end;
//--------------------------------------------
//>> Методы расширения типа faststring (StringBuilder) # Extension methods for faststring (StringBuilder)
//--------------------------------------------
/// Возвращает индекс вхождения подстроки в быструю строку
function IndexOf(Self: faststring; subs: string; from: integer := 0): integer; extensionmethod;
begin
var lens := Self.Length;
var lens1 := subs.Length;
if (from < 0) or (lens1 > lens - from) then
begin
Result := -1;
exit;
end;
if lens1 = 0 then
begin
Result := from;
exit;
end;
for var i := from to lens - lens1 do
begin
var found := True;
for var j := 0 to lens1 - 1 do
begin
if Self[i + j] <> subs[j + 1] then
begin
found := False;
break;
end;
end;
if found then
begin
Result := i;
exit;
end;
end;
Result := -1;
end;
/// Преобразует быструю строку в последовательность символов
function ToSequence(Self: faststring): sequence of char; extensionmethod;
begin
for var i:=0 to Self.Length - 1 do
yield Self[i];
end;
function operator in(subs: string; s: faststring): boolean; extensionmethod;
begin
Result := s.IndexOf(subs) <> -1;
end;
/// Замещает n вхождений указанной строки на другую строку (все при n = 0)
function Replace(Self: faststring; OldValue, NewValue: string; n: integer): faststring; extensionmethod;
begin
if n = 0 then
Self.Replace(OldValue, NewValue) // стандартный метод StringBuilder
else begin
var from := 0;
loop n do
begin
var index := Self.IndexOf(OldValue, from);
if index = -1 then exit;
Self.Remove(index, OldValue.Length);
Self.Insert(index, NewValue);
from := index + NewValue.Length;
end;
end;
Result := Self;
end;
//--------------------------------------------
//>> Методы расширения типа Func # Extension methods for Func
//--------------------------------------------
@ -15415,7 +15504,7 @@ end;}
// Присваивание реализовано в PABCExtensions. Здесь не работает
var _emptyset: NewSetEmpty := new NewSetEmpty;
var _emptyset: EmptyCollection := new EmptyCollection;
type
SetCreatorFunctionAttribute = class(Attribute)

View file

@ -6,7 +6,9 @@ using System.Collections.Generic;
using System.Linq;
using PascalABCCompiler.SemanticTree;
using PascalABCCompiler.SyntaxTree;
using PascalABCCompiler.TreeRealization;
using static PascalABCCompiler.SyntaxTree.SyntaxTreeBuilder;
namespace PascalABCCompiler.TreeConverter
{
@ -1208,36 +1210,56 @@ namespace PascalABCCompiler.TreeConverter
else
{
// SSM 20/01/25 - Tuple<int,int> -> Tuple<double,double>
/*if (formal_param_type.original_generic != null
if (formal_param_type.original_generic != null
&& formal_param_type.original_generic.BaseFullName.StartsWith("System.Tuple`")
&& factparams[i].type.original_generic != null
&& factparams[i].type.original_generic.BaseFullName.StartsWith("System.Tuple`")
&& formal_param_type.instance_params.Count == factparams[i].type.instance_params.Count
&& factparams[i] is IFunctionCallNode fpf
&& fpf.function.name == "Create")
//&& factparams[i] is IFunctionCallNode fpf
//&& fpf.function.name == "Create"
)
{
expressions_list el = null;
function_node fn = null;
if (fpf is common_static_method_call fpf1) {
el = fpf1.parameters;
fn = fpf1.function_node;
}
else if (fpf is compiled_static_method_call fpf2) {
el = fpf2.parameters;
fn = fpf2.function_node;
}
var ccc = syntax_tree_visitor.create_constructor_call(formal_param_type,
el, factparams[i].location);
syntax_tree_visitor.contextChanger.SaveContextAndUpToGlobalLevel();
var sl = new statement_list();
var rettype = new semantic_type_node(formal_param_type);
//expressions_list parameters = null;
//if (fpf is common_static_method_call fpf1) {
// parameters = fpf1.parameters;
//}
//else if (fpf is compiled_static_method_call fpf2) {
// parameters = fpf2.parameters;
//}
var el = new expression_list();
for (int ii = 1; ii <= formal_param_type.instance_params.Count; ii++)
el.Add(new dot_node(new ident("x"), new ident("Item" + ii.ToString(),
factparams[i].location)));
//parameters[ii-1].location)));
SyntaxTree.expression ex = new SyntaxTree.new_expr(rettype,el);
sl.Add(new SyntaxTree.assign("Result", ex));
// Определим функцию преобразования на внешнем уровне
var fun = BuildSimpleFunctionOneParameter("_conv" + UniqueString(), "x",
new SyntaxTree.semantic_type_node(factparams[i].type),
rettype,
sl
);
// Теперь ее надо обойти
syntax_tree_visitor.ProcessNode(fun);
// Теперь до нее доберемся
var fn = syntax_tree_visitor.context.last_created_function.sym_info as function_node;
syntax_tree_visitor.contextChanger.RestoreCurrentContext();
//var ccc = syntax_tree_visitor.create_constructor_call(formal_param_type,
// el, factparams[i].location);
//factparams[i] = ccc;
possible_type_convertions ptci = new possible_type_convertions();
var ttttt = (ccc as compiled_constructor_call).function_node;
ptci.first = new type_conversion(ttttt);
ptci.first = new type_conversion(fn);
ptci.second = null;
ptci.from = factparams[i].type;
ptci.to = formal_param_type;
tc.AddElement(ptci);
return tc;
}*/
}
//issue #2161 - SSM 12.03.2020
//issue #348

View file

@ -15460,7 +15460,7 @@ namespace PascalABCCompiler.TreeConverter
{
// Отдельно для пустого множества
common_namespace_function_call cnfc = expr as common_namespace_function_call;
if (cnfc.type.name == "NewSetEmpty")
if (cnfc.type.name == "EmptyCollection")
{
constant = new common_namespace_function_call_as_constant(expr as common_namespace_function_call, loc);
return constant;
@ -15475,7 +15475,7 @@ namespace PascalABCCompiler.TreeConverter
return constant;
}
else if (expr is common_namespace_function_call_as_constant cnfcac
&& cnfcac.type.name == "NewSetEmpty")
&& cnfcac.type.name == "EmptyCollection")
{
expr = create_constructor_call(tn, new expressions_list(), loc);
constant = new common_constructor_call_as_constant(expr as common_constructor_call, loc);

View file

@ -235,6 +235,7 @@
<Key word = "word" />
<Key word = "integer" />
<Key word = "BigInteger" />
<Key word = "Complex" />
<Key word = "longword" />
<Key word = "uint64" />
<Key word = "cardinal" />
@ -242,6 +243,7 @@
<Key word = "single" />
<Key word = "longint" />
<Key word = "string" />
<Key word = "faststring" />
<Key word = "char" />
<Key word = "real" />
<Key word = "double" />

View file

@ -105,7 +105,7 @@ type
/// Представляет произвольно большое целое число
BigInteger = System.Numerics.BigInteger;
/// Представляет дату и время
DateTime = System.DateTime;
@ -181,6 +181,9 @@ type
/// Представляет изменяемую строку символов
StringBuilder = System.Text.StringBuilder;
/// Представляет строку с эффективным изменением
faststring = StringBuilder;
/// Тип кодировки символов
Encoding = System.Text.Encoding;
@ -483,7 +486,7 @@ type
end;}
type
NewSetEmpty = class;
EmptyCollection = class;
/// Тип встроенного множества
NewSet<T> = record(IEnumerable<T>)
@ -558,66 +561,77 @@ type
begin
Result._hs := new HashSet<T>(a);
end;
static function operator implicit(ns: NewSetEmpty): NewSet<T>; begin end;
static function operator:=(var s: NewSet<T>; st: NewSet<T>): NewSet<T>; // Эту функцию обязательно здесь определять
begin
s._hs := new HashSet<T>(st.hs);
end;
static function operator implicit(ns: EmptyCollection): NewSet<T>; begin end;
end;
NewSetEmpty = class
EmptyCollection = class
public
static function operator=<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := s1.Count = 0;
static function operator=<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := s1.Count = 0;
static function operator<><T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := not (s1 = s2);
static function operator<><T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := not (s1 = s2);
static function operator><T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := s1.Count > 0;
static function operator><T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := False;
static function operator<<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := False;
static function operator<<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := s1.Count > 0;
static function operator>=<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := s1.Count >= 0;
static function operator>=<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := False;
static function operator<=<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := False;
static function operator<=<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := s1.Count >= 0;
static function operator=<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := s1.Count = 0;
static function operator=<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := s1.Count = 0;
static function operator<><T>(s1: NewSet<T>; s2: EmptyCollection): boolean := not (s1 = s2);
static function operator<><T>(s2: EmptyCollection; s1: NewSet<T>): boolean := not (s1 = s2);
static function operator><T>(s1: NewSet<T>; s2: EmptyCollection): boolean := s1.Count > 0;
static function operator><T>(s2: EmptyCollection; s1: NewSet<T>): boolean := False;
static function operator<<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := False;
static function operator<<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := s1.Count > 0;
static function operator>=<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := s1.Count >= 0;
static function operator>=<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := False;
static function operator<=<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := False;
static function operator<=<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := s1.Count >= 0;
// ToDo: определить то же для массивов на будущее
static function operator+(first, second: NewSetEmpty): NewSetEmpty := new NewSetEmpty;
static function operator-(first, second: NewSetEmpty): NewSetEmpty := new NewSetEmpty;
static function operator*(first, second: NewSetEmpty): NewSetEmpty := new NewSetEmpty;
static function operator+<T>(first: NewSetEmpty; second: array of T): NewSet<T>;
static function operator+(first, second: EmptyCollection): EmptyCollection := new EmptyCollection;
static function operator-(first, second: EmptyCollection): EmptyCollection := new EmptyCollection;
static function operator*(first, second: EmptyCollection): EmptyCollection := new EmptyCollection;
static function operator+<T>(first: EmptyCollection; second: array of T): NewSet<T>;
begin
Result.hs.UnionWith(second);
end;
static function operator+<T>(first: array of T; second: NewSetEmpty): NewSet<T>;
static function operator+<T>(first: array of T; second: EmptyCollection): NewSet<T>;
begin
Result.hs.UnionWith(first);
end;
static function operator+<T>(first: NewSet<T>; second: NewSetEmpty): NewSet<T> := first;
static function operator+<T>(first: NewSetEmpty; second: NewSet<T>): NewSet<T> := second;
static function operator*<T>(first: NewSet<T>; second: NewSetEmpty): NewSet<T>; begin end;
static function operator*<T>(first: NewSetEmpty; second: NewSet<T>): NewSet<T>; begin end;
static function operator-<T>(first: NewSet<T>; second: NewSetEmpty): NewSet<T> := first;
static function operator-<T>(first: NewSetEmpty; second: NewSet<T>): NewSet<T>; begin end;
static function operator+<T>(first: NewSet<T>; second: EmptyCollection): NewSet<T> := first;
static function operator+<T>(first: EmptyCollection; second: NewSet<T>): NewSet<T> := second;
static function operator*<T>(first: NewSet<T>; second: EmptyCollection): NewSet<T>; begin end;
static function operator*<T>(first: EmptyCollection; second: NewSet<T>): NewSet<T>; begin end;
static function operator-<T>(first: NewSet<T>; second: EmptyCollection): NewSet<T> := first;
static function operator-<T>(first: EmptyCollection; second: NewSet<T>): NewSet<T>; begin end;
static function operator*<T>(first: NewSetEmpty; second: array of T): NewSet<T>; begin end;
static function operator*<T>(first: array of T; second: NewSetEmpty): NewSet<T>; begin end;
static function operator-<T>(first: NewSetEmpty; second: array of T): NewSet<T>; begin end;
static function operator-<T>(first: array of T; second: NewSetEmpty): NewSet<T>;
static function operator*<T>(first: EmptyCollection; second: array of T): NewSet<T>; begin end;
static function operator*<T>(first: array of T; second: EmptyCollection): NewSet<T>; begin end;
static function operator-<T>(first: EmptyCollection; second: array of T): NewSet<T>; begin end;
static function operator-<T>(first: array of T; second: EmptyCollection): NewSet<T>;
begin
Result.hs.UnionWith(first);
end;
function ToString: string; override := '{}';
function ToSet<T>(): NewSet<T>; begin end;
static function operator implicit<T>(Self: NewSetEmpty): array of T;
static function operator implicit<T>(Self: EmptyCollection): array of T;
begin
Result := new T[0];
Result := new T[0]//System.Array.Empty&<T>;
end;
static function operator implicit<T>(Self: NewSetEmpty): HashSet<T>;
static function operator implicit<T>(Self: EmptyCollection): HashSet<T>;
begin
Result := new HashSet<T>;
end;
static function operator implicit<T>(Self: EmptyCollection): SortedSet<T>;
begin
Result := new SortedSet<T>;
end;
static function operator implicit<T>(Self: EmptyCollection): List<T>;
begin
Result := new List<T>;
end;
static function operator implicit<K,V>(Self: EmptyCollection): Dictionary<K,V>;
begin
Result := new Dictionary<K,V>;
end;
end;
type
@ -667,7 +681,7 @@ type
end;
/// Значение пустого множества
function EmptySet: NewSetEmpty;
function EmptySet: EmptyCollection;
/// Генератор множества
function __NewSetCreatorInternal<T>(params a: array of T): NewSet<T>;
@ -14689,6 +14703,81 @@ begin
&to.IndexValue := Self.Count - &to.IndexValue + 1;
Result := SystemSliceStringImplQuestion(Self, situation, from.IndexValue, &to.IndexValue, step, 0);
end;
//--------------------------------------------
//>> Методы расширения типа faststring (StringBuilder) # Extension methods for faststring (StringBuilder)
//--------------------------------------------
/// Возвращает индекс вхождения подстроки в быструю строку
function IndexOf(Self: faststring; subs: string; from: integer := 0): integer; extensionmethod;
begin
var lens := Self.Length;
var lens1 := subs.Length;
if (from < 0) or (lens1 > lens - from) then
begin
Result := -1;
exit;
end;
if lens1 = 0 then
begin
Result := from;
exit;
end;
for var i := from to lens - lens1 do
begin
var found := True;
for var j := 0 to lens1 - 1 do
begin
if Self[i + j] <> subs[j + 1] then
begin
found := False;
break;
end;
end;
if found then
begin
Result := i;
exit;
end;
end;
Result := -1;
end;
/// Преобразует быструю строку в последовательность символов
function ToSequence(Self: faststring): sequence of char; extensionmethod;
begin
for var i:=0 to Self.Length - 1 do
yield Self[i];
end;
function operator in(subs: string; s: faststring): boolean; extensionmethod;
begin
Result := s.IndexOf(subs) <> -1;
end;
/// Замещает n вхождений указанной строки на другую строку (все при n = 0)
function Replace(Self: faststring; OldValue, NewValue: string; n: integer): faststring; extensionmethod;
begin
if n = 0 then
Self.Replace(OldValue, NewValue) // стандартный метод StringBuilder
else begin
var from := 0;
loop n do
begin
var index := Self.IndexOf(OldValue, from);
if index = -1 then exit;
Self.Remove(index, OldValue.Length);
Self.Insert(index, NewValue);
from := index + NewValue.Length;
end;
end;
Result := Self;
end;
//--------------------------------------------
//>> Методы расширения типа Func # Extension methods for Func
//--------------------------------------------
@ -15415,7 +15504,7 @@ end;}
// Присваивание реализовано в PABCExtensions. Здесь не работает
var _emptyset: NewSetEmpty := new NewSetEmpty;
var _emptyset: EmptyCollection := new EmptyCollection;
type
SetCreatorFunctionAttribute = class(Attribute)