Изменена реализация метода Slice и срезов a[f,t,s]
This commit is contained in:
parent
7278c5136d
commit
8d7c9fca46
|
|
@ -15,7 +15,7 @@ internal static class RevisionClass
|
|||
public const string Major = "3";
|
||||
public const string Minor = "1";
|
||||
public const string Build = "0";
|
||||
public const string Revision = "1203";
|
||||
public const string Revision = "1207";
|
||||
|
||||
public const string MainVersion = Major + "." + Minor;
|
||||
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%COREVERSION%=0
|
||||
%REVISION%=1203
|
||||
%REVISION%=1207
|
||||
%MINOR%=1
|
||||
%MAJOR%=3
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!define VERSION '3.1.0.1203'
|
||||
!define VERSION '3.1.0.1207'
|
||||
|
|
|
|||
|
|
@ -1871,7 +1871,10 @@ const
|
|||
BAD_TYPE_IN_RUNTIMESIZEOF = 'Bad Type in RunTimeSizeOf';
|
||||
PARAMETER_COUNT_MUST_BE_GREATER_0 = 'Параметр count должен быть > 0!!Parameter count must be > 0';
|
||||
PARAMETER_COUNT_MUST_BE_GREATER_1 = 'Параметр count должен быть > 1!!Parameter count must be > 1';
|
||||
PARAMETER_COUNT_MUST_BE_NOT_EQUAL_0 = 'Параметр step не может быть равен 0!!The step parameter must be not equal to 0';
|
||||
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';
|
||||
|
||||
// -----------------------------------------------------
|
||||
// WINAPI
|
||||
|
|
@ -3494,7 +3497,7 @@ end;
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
type
|
||||
// Вспомогательный класс для генерации всех последовательностей. К сожалению, пока с object
|
||||
// Вспомогательный класс для генерации всех последовательностей
|
||||
SeqBase<T> = class(IEnumerable<T>,IEnumerator<T>)
|
||||
public
|
||||
function System.Collections.IEnumerable.GetEnumerator(): System.Collections.IEnumerator;
|
||||
|
|
@ -8113,12 +8116,23 @@ 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
|
||||
function Slice<T>(Self: sequence of T; from,step: integer): sequence of T; extensionmethod;
|
||||
begin
|
||||
if step=0 then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_COUNT_MUST_BE_NOT_EQUAL_0));
|
||||
{if step=0 then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0));
|
||||
if step<0 then
|
||||
begin
|
||||
if from<0 then
|
||||
|
|
@ -8133,14 +8147,21 @@ begin
|
|||
else
|
||||
if from<=0 then
|
||||
Result := Self.Where((x,i)->(i-from) mod step = 0)
|
||||
else Result := Self.Skip(from).Where((x,i)->i mod step = 0);
|
||||
else Result := Self.Skip(from).Where((x,i)->i mod step = 0);}
|
||||
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 длины не более 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_COUNT_MUST_BE_NOT_EQUAL_0));
|
||||
{if step=0 then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0));
|
||||
if step<0 then
|
||||
begin
|
||||
if from<0 then
|
||||
|
|
@ -8162,7 +8183,15 @@ begin
|
|||
count -= abs(from+1) div step + 1;
|
||||
Result := Self.Where((x,i)->(i-from) mod step = 0).Take(count)
|
||||
end
|
||||
else Result := Self.Skip(from).Where((x,i)->i mod step = 0).Take(count);
|
||||
else Result := Self.Skip(from).Where((x,i)->i mod step = 0).Take(count);}
|
||||
|
||||
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;
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
|
@ -8183,18 +8212,145 @@ begin
|
|||
Result := Self;
|
||||
end;
|
||||
|
||||
///--
|
||||
function CreateSliceFromListInternal<T>(Self: List<T>; from,step,count: integer): List<T>;
|
||||
begin
|
||||
Result := new List<T>(count);
|
||||
|
||||
var f := from;
|
||||
for var i:=0 to count-1 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 ArgumentException(GetTranslation(PARAMETER_COUNT_MUST_BE_GREATER_0));
|
||||
|
||||
if (from < 0) or (from > Len - 1) then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE));
|
||||
|
||||
var cnt := step > 0 ? Len - from : from + 1;
|
||||
var cntstep := (cnt-1) div abs(step) + 1;
|
||||
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);
|
||||
{if step = 0 then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0));
|
||||
|
||||
if (from < 0) or (from > Self.Count - 1) then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE));
|
||||
|
||||
var cnt := step > 0 ? Self.Count - from : from + 1;
|
||||
var cntstep := (cnt-1) div abs(step) + 1;
|
||||
if count > cntstep then
|
||||
count := cntstep;}
|
||||
|
||||
Result := CreateSliceFromListInternal(Self,from,step,count);
|
||||
end;
|
||||
|
||||
/// Возвращает срез списка от индекса from с шагом step
|
||||
function Slice<T>(Self: List<T>; from,step: integer): List<T>; extensionmethod;
|
||||
begin
|
||||
Result := Self.AsEnumerable.Slice(from,step).ToList;
|
||||
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 := Self.AsEnumerable.Slice(from,step,count).ToList;
|
||||
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;
|
||||
|
||||
///--
|
||||
function CalcCountForSystemSlice(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 (from < 0) or (from > Len - 1) then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE));
|
||||
|
||||
if (&to < -1) or (&to > Len) then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_TO_OUT_OF_RANGE));
|
||||
|
||||
var count: integer;
|
||||
|
||||
if step>0 then
|
||||
begin
|
||||
case situation of
|
||||
1: from := 0;
|
||||
2: &to := Len;
|
||||
3: begin
|
||||
from := 0;
|
||||
&to := Len;
|
||||
end;
|
||||
end;
|
||||
|
||||
var cnt := &to - from;
|
||||
if cnt<=0 then
|
||||
count := 0
|
||||
else count := (cnt-1) div step + 1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
case situation of
|
||||
1: from := Len - 1;
|
||||
2: &to := -1;
|
||||
3: begin
|
||||
from := Len - 1;
|
||||
&to := -1;
|
||||
end;
|
||||
end;
|
||||
|
||||
var cnt := from - &to;
|
||||
if cnt<=0 then
|
||||
count := 0
|
||||
else count := (cnt-1) div (-step) + 1;
|
||||
end;
|
||||
Result := count;
|
||||
end;
|
||||
|
||||
///--
|
||||
function SystemSliceListImpl<T>(Self: List<T>; situation: integer; from,&to: integer; step: integer := 1): List<T>;
|
||||
begin
|
||||
var count := CalcCountForSystemSlice(situation,Self.Count,from,&to,step);
|
||||
|
||||
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;
|
||||
|
||||
// -----------------------------------------------------
|
||||
//>> Методы расширения типа array of T # Extension methods for array of T
|
||||
|
|
@ -8290,7 +8446,7 @@ begin
|
|||
Result := System.Array.FindIndex(self,p);
|
||||
end;
|
||||
|
||||
/// Возвращает в виде массива все элементы, удовлетворяющие предикатуы
|
||||
/// Возвращает в виде массива все элементы, удовлетворяющие предикату
|
||||
function FindAll<T>(self: array of T; p: T->boolean): array of T; extensionmethod;
|
||||
begin
|
||||
Result := System.Array.FindAll(self,p);
|
||||
|
|
@ -8338,18 +8494,68 @@ begin
|
|||
System.Array.Sort(self,cmp);
|
||||
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 := Self.AsEnumerable.Slice(from,step).ToArray;
|
||||
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 := Self.AsEnumerable.Slice(from,step,count).ToArray;
|
||||
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 := CalcCountForSystemSlice(situation,Self.Length,from,&to,step);
|
||||
|
||||
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;
|
||||
|
||||
// -----------------------------------------------------
|
||||
//>> Методы расширения типа integer # Extension methods for integer
|
||||
|
|
@ -8636,18 +8842,73 @@ begin
|
|||
else Result := Self;
|
||||
end;
|
||||
|
||||
///--
|
||||
function CreateSliceFromStringInternal(Self: string; from,step,count: integer): string;
|
||||
begin
|
||||
var res := new StringBuilder(count);
|
||||
|
||||
for var i:=0 to count-1 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 := Self.AsEnumerable.Slice(from,step).JoinIntoString('');
|
||||
Result := SliceStringImpl(Self,from,step,integer.MaxValue);
|
||||
end;
|
||||
|
||||
/// Возвращает срез строки от индекса from с шагом step длины не более count
|
||||
function Slice(Self: string; from,step,count: integer): string; extensionmethod;
|
||||
begin
|
||||
Result := Self.AsEnumerable.Slice(from,step,count).JoinIntoString('');
|
||||
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 := CalcCountForSystemSlice(situation,Self.Length,fromv,tov,step);
|
||||
|
||||
Result := CreateSliceFromStringInternal(Self,fromv+1,step,count)
|
||||
end;
|
||||
|
||||
///--
|
||||
function SystemSlice(Self: string; situation: integer; from,&to: integer): string; extensionmethod;
|
||||
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;
|
||||
|
||||
|
||||
//--------------------------------------------
|
||||
//>> Методы расширения типа Func # Extension methods for Func
|
||||
//--------------------------------------------
|
||||
|
|
@ -8732,7 +8993,7 @@ end;
|
|||
// -------------------------------------------
|
||||
// Дополнения февраль 2016
|
||||
|
||||
// Добавляет поле к кортежу
|
||||
{// Добавляет поле к кортежу
|
||||
function Add<T1, T2, T3> (Self: (T1,T2); v: T3): (T1,T2,T3); extensionmethod;
|
||||
begin
|
||||
Result := (Self[0],Self[1],v);
|
||||
|
|
@ -8760,7 +9021,7 @@ 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;
|
||||
end;}
|
||||
|
||||
{// Определяет, есть ли указанный элемент в массиве
|
||||
function Contains<T>(self: array of T; x: T): boolean; extensionmethod;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ namespace PascalABCCompiler.TreeConverter
|
|||
public override void visit(SyntaxTree.var_statement defs)
|
||||
{
|
||||
indef = true;
|
||||
ProcessNode(defs.var_def.vars); // исключаем типы - просматриваем только имена переменных
|
||||
ProcessNode(defs.var_def.vars); // исключаем типы -
|
||||
// просматриваем только имена переменных
|
||||
indef = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18871,15 +18871,40 @@ namespace PascalABCCompiler.TreeConverter
|
|||
}
|
||||
}
|
||||
|
||||
// Это в куче мест надо. Потому что либо compiled_type_node, либо compiled_generic_instance_type_node
|
||||
// compiled_type_node если в записи A<T> все типы NETовские
|
||||
// compiled_generic_instance_type_node если в записи A<T> хоть один тип - паскалевский
|
||||
public Type ConvertSemanticTypeNodeToNETType(type_node tn)
|
||||
{
|
||||
if (tn is compiled_generic_instance_type_node)
|
||||
{
|
||||
var tnc = (tn as compiled_generic_instance_type_node);
|
||||
var itnc = tnc.original_generic as compiled_type_node;
|
||||
var tt = itnc.compiled_type;
|
||||
if (tt.IsGenericType)
|
||||
tt = tt.GetGenericTypeDefinition();
|
||||
return tt;
|
||||
}
|
||||
else if (tn is compiled_type_node)
|
||||
{
|
||||
var itnc = (tn as compiled_type_node);
|
||||
var tt = itnc.compiled_type;
|
||||
if (tt.IsGenericType)
|
||||
tt = tt.GetGenericTypeDefinition();
|
||||
return tt;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void visit(SyntaxTree.assign_tuple asstup)
|
||||
{
|
||||
// Проверить, что справа - Tuple
|
||||
var expr = convert_strong(asstup.expr);
|
||||
|
||||
var ent = expr.type as compiled_type_node;
|
||||
if (ent == null)
|
||||
var t = ConvertSemanticTypeNodeToNETType(expr.type);
|
||||
if (t == null)
|
||||
AddError(expr.location, "TUPLE_EXPECTED");
|
||||
var t = ent.compiled_type;
|
||||
//if (t != typeof(System.Tuple<>))
|
||||
if (!t.FullName.StartsWith("System.Tuple"))
|
||||
AddError(expr.location, "TUPLE_EXPECTED");
|
||||
|
||||
|
|
@ -18904,6 +18929,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
|
||||
public override void visit(SyntaxTree.slice_expr sl)
|
||||
{
|
||||
// Устарело
|
||||
// Преобразуется в вызов a.Slice
|
||||
// from, step сохраняются, count вычисляется как count = (to-from+step-sign(step)) div step
|
||||
// Для a: нужно to присвоить очень большое целое
|
||||
|
|
@ -18911,16 +18937,35 @@ namespace PascalABCCompiler.TreeConverter
|
|||
// Для a::step нужно использовать a.Slice(from,step)
|
||||
// Для :b:step нужно закодировать from - from := -MaxInt div 2 и в методе Slice это проверить и поправить from в зависимости от знака step
|
||||
|
||||
// Новое
|
||||
// Последовательности исключены
|
||||
// Преобразуется в вызов a.SystemSlice(situation,from,to,step)
|
||||
// situation = 0 - ничего не пропущено
|
||||
// situation = 1 - пропущен from
|
||||
// situation = 2 - пропущен to
|
||||
// situation = 3 - пропущены from и to
|
||||
|
||||
var semvar = convert_strong(sl.v);
|
||||
var semvartype = semvar.type;
|
||||
|
||||
var IsOrImplementsIEnumerableT = false; // проверим, является ли semvartype интерфейсом IEnumerable<T> или реализует его
|
||||
// semvartype должен быть array of T, List<T> или string
|
||||
|
||||
var ct = semvartype as compiled_type_node;
|
||||
var IsSlicedType = false; // проверим, является ли semvartype интерфейсом IEnumerable<T> или реализует его
|
||||
|
||||
var t = ConvertSemanticTypeNodeToNETType(semvartype);
|
||||
|
||||
if (t.IsArray)
|
||||
IsSlicedType = true;
|
||||
else if (t == typeof(System.String))
|
||||
IsSlicedType = true;
|
||||
else if (t.IsGenericType && t.GetGenericTypeDefinition()==typeof(System.Collections.Generic.List<>))
|
||||
IsSlicedType = true;
|
||||
|
||||
/*var ct = semvartype as compiled_type_node;
|
||||
if (ct != null && ct.compiled_type.IsGenericType && ct.compiled_type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.IEnumerable<>)) // это он и есть
|
||||
IsOrImplementsIEnumerableT = true;
|
||||
IsSlicedType = true;
|
||||
|
||||
if (!IsOrImplementsIEnumerableT)
|
||||
if (!IsSlicedType)
|
||||
foreach (SemanticTree.ITypeNode itn in semvartype.ImplementingInterfaces) // Ищем интерфейс IEnumerable<T>
|
||||
{
|
||||
if (itn is compiled_generic_instance_type_node)
|
||||
|
|
@ -18930,7 +18975,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
|
||||
if (tt == typeof(System.Collections.Generic.IEnumerable<>))
|
||||
{
|
||||
IsOrImplementsIEnumerableT = true;
|
||||
IsSlicedType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -18944,15 +18989,44 @@ namespace PascalABCCompiler.TreeConverter
|
|||
|
||||
if (tt1 == typeof(System.Collections.Generic.IEnumerable<>))
|
||||
{
|
||||
IsOrImplementsIEnumerableT = true;
|
||||
IsSlicedType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsOrImplementsIEnumerableT)
|
||||
*/
|
||||
|
||||
if (!IsSlicedType)
|
||||
AddError(get_location(sl.v), "BAD_SLICE_OBJECT");
|
||||
|
||||
int situation = 0;
|
||||
if (sl.from == null && sl.to != null)
|
||||
situation = 1;
|
||||
else if (sl.from != null && sl.to == null)
|
||||
situation = 2;
|
||||
else if (sl.from == null && sl.to == null)
|
||||
situation = 3;
|
||||
|
||||
var zero = new int32_const(0);
|
||||
|
||||
// заполняем пустые чем-нибудь
|
||||
if (sl.from == null)
|
||||
sl.from = zero;
|
||||
if (sl.to == null)
|
||||
sl.to = zero;
|
||||
if (sl.step == null)
|
||||
sl.step = new int32_const(1);
|
||||
|
||||
var el = new SyntaxTree.expression_list();
|
||||
el.Add(new int32_const(situation));
|
||||
el.Add(sl.from);
|
||||
el.Add(sl.to);
|
||||
el.Add(sl.step);
|
||||
|
||||
var mc = new method_call(new dot_node(sl.v, new ident("SystemSlice", sl.v.source_context), sl.v.source_context), el, sl.source_context);
|
||||
visit(mc);
|
||||
/*
|
||||
// Ситуация from::step - вызвать Slice с двумя параметрами - пропустить вычисление и добавление count
|
||||
bool SituationFromSpaceStep = (sl.from != null) && (sl.to == null) && (sl.step != null);
|
||||
// Ситуация :to:step - закодировать from = -MaxInt div 2 и в Slice сделато коррекцию если step<0 !!!
|
||||
|
|
@ -19017,23 +19091,25 @@ namespace PascalABCCompiler.TreeConverter
|
|||
|
||||
var mc = new method_call(new dot_node(sl.v, new ident("Slice", sl.v.source_context), sl.v.source_context), el, sl.source_context);
|
||||
visit(mc);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/*public SyntaxTree.question_colon_expression ConvertToQCE(dot_question_node dqn)
|
||||
{
|
||||
// Неверно работает. Пока не используется. Доделать
|
||||
addressed_value left = dqn.left;
|
||||
addressed_value right = dqn.right;
|
||||
var eq = new bin_expr(left, new nil_const(), Operators.Equal, left.source_context);
|
||||
var dn = new dot_node(left, right, dqn.source_context);
|
||||
var q = new SyntaxTree.question_colon_expression(eq, new nil_const(), dn, dqn.source_context);
|
||||
return q;
|
||||
}
|
||||
public override void visit(SyntaxTree.dot_question_node dqn)
|
||||
{
|
||||
// a?.b
|
||||
var q = ConvertToQCE(dqn);
|
||||
visit(q);
|
||||
}*/
|
||||
/*public SyntaxTree.question_colon_expression ConvertToQCE(dot_question_node dqn)
|
||||
{
|
||||
// Неверно работает. Пока не используется. Доделать
|
||||
addressed_value left = dqn.left;
|
||||
addressed_value right = dqn.right;
|
||||
var eq = new bin_expr(left, new nil_const(), Operators.Equal, left.source_context);
|
||||
var dn = new dot_node(left, right, dqn.source_context);
|
||||
var q = new SyntaxTree.question_colon_expression(eq, new nil_const(), dn, dqn.source_context);
|
||||
return q;
|
||||
}
|
||||
public override void visit(SyntaxTree.dot_question_node dqn)
|
||||
{
|
||||
// a?.b
|
||||
var q = ConvertToQCE(dqn);
|
||||
visit(q);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -2374,6 +2374,127 @@
|
|||
</Node>
|
||||
</Items>
|
||||
</Node>
|
||||
<Node Name="Slices">
|
||||
<Items>
|
||||
<Node Name="Slice<T>(Self: sequence of T">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function Slice<T>(Self: sequence of T; from,step: integer): sequence of T; extensionmethod;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">function Slice < T > ( Self : sequence of T ; from , step : integer ) : sequence of T extensionmethod</i>
|
||||
<i Type="PAS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
<Node Name="Slice<T>(Self: List<T>">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function Slice<T>(Self: List<T>; from,step,count: integer): List<T>; extensionmethod;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">function Slice < T > ( Self : List < T > ; from , step , count : integer ) : List < T > extensionmethod</i>
|
||||
<i Type="PAS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
<Node Name="Slice<T>(Self: array of T">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function Slice<T>(Self: array of T; from,step: integer): array of T; extensionmethod;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">function Slice < T > ( Self : array of T ; from , step : integer ) : array of T extensionmethod</i>
|
||||
<i Type="PAS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
<Node Name="Slice(Self: string;">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function Slice(Self: string; from,step: integer): string; extensionmethod;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">function Slice ( Self : string ; from , step : integer ) : string extensionmethod</i>
|
||||
<i Type="PAS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
<Node Name="CalcCountForSystemSlice">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function CalcCountForSystemSlice(situation: integer; Len: integer; var from,&to: integer; step: integer): integer;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">function CalcCountForSystemSlice ( situation : integer ; Len : integer ; var from , &to : integer ; step : integer ) : integer</i>
|
||||
<i Type="PAS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
<Node Name="SliceListImpl<T>(Self: List<T>">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function SliceListImpl<T>(Self: List<T>; from,step,count: integer): List<T>;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">function SliceListImpl < T > ( Self : List < T > ; from , step , count : integer ) : List < T ></i>
|
||||
<i Type="PAS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
<Node Name="SliceArrayImpl<T>(Self: array of T">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function SliceArrayImpl<T>(Self: array of T; from,step,count: integer): array of T;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">function SliceArrayImpl < T > ( Self : array of T ; from , step , count : integer ) : array of T</i>
|
||||
<i Type="PAS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
<Node Name="SliceStringImpl(Self: string">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function SliceStringImpl(Self: string; from,step,count: integer): string;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">function SliceStringImpl ( Self : string ; from , step , count : integer ) : string</i>
|
||||
<i Type="PAS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
<Node Name="SystemSliceListImpl">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function SystemSliceListImpl<T>(Self: List<T>; situation: integer; from,&to: integer; step: integer := 1): List<T>;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">function SystemSliceListImpl < T > ( Self : List < T > ; situation : integer ; from , &to : integer ; step : integer : = 1 ) : List < T ></i>
|
||||
<i Type="PAS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
<Node Name="SystemSliceArrayImpl">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function SystemSliceListImpl<T>(Self: List<T>; situation: integer; from,&to: integer; step: integer := 1): List<T>;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">function SystemSliceListImpl < T > ( Self : List < T > ; situation : integer ; from , &to : integer ; step : integer : = 1 ) : List < T ></i>
|
||||
<i Type="PAS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
<Node Name="SystemSliceStringImpl">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function SystemSliceStringImpl(Self: string; situation: integer; from,&to: integer; step: integer := 1): string;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">function SystemSliceStringImpl ( Self : string ; situation : integer ; from , &to : integer ; step : integer : = 1 ) : string</i>
|
||||
<i Type="PAS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
<Node Name="CreateSliceFromArrayInternal">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function CreateSliceFromArrayInternal<T>(Self: array of T; from,step,count: integer): array of T;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">function CreateSliceFromArrayInternal < T > ( Self : array of T ; from , step , count : integer ) : array of T</i>
|
||||
<i Type="PAS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
<Node Name="CreateSliceFromStringInternal">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function CreateSliceFromStringInternal<T>(Self: string; from,count,step: integer): string;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">function CreateSliceFromStringInternal ( Self : string ; from , count , step : integer ) : string</i>
|
||||
<i Type="PAS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
</Items>
|
||||
</Node>
|
||||
<Node Name="read_lexem">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function read_lexem: string;// SSM 08.03.11 - пытаюсь исправить с peekом ситуацию с вводом '1 hello'. Должно работать</Text>
|
||||
|
|
@ -2497,15 +2618,6 @@
|
|||
<i Type="ClassMethod">procedure Reset ( )</i>
|
||||
</ICtx>
|
||||
</Node>
|
||||
<Node Name="Slice<T>(Self: sequence of T">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function Slice<T>(Self: sequence of T; from,step: integer): sequence of T; extensionmethod;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">function Slice < T > ( Self : sequence of T ; from , step : integer ) : sequence of T extensionmethod</i>
|
||||
<i Type="PAS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
</Items>
|
||||
</Node>
|
||||
</AspectFile>
|
||||
|
|
@ -1871,7 +1871,10 @@ const
|
|||
BAD_TYPE_IN_RUNTIMESIZEOF = 'Bad Type in RunTimeSizeOf';
|
||||
PARAMETER_COUNT_MUST_BE_GREATER_0 = 'Параметр count должен быть > 0!!Parameter count must be > 0';
|
||||
PARAMETER_COUNT_MUST_BE_GREATER_1 = 'Параметр count должен быть > 1!!Parameter count must be > 1';
|
||||
PARAMETER_COUNT_MUST_BE_NOT_EQUAL_0 = 'Параметр step не может быть равен 0!!The step parameter must be not equal to 0';
|
||||
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';
|
||||
|
||||
// -----------------------------------------------------
|
||||
// WINAPI
|
||||
|
|
@ -3494,7 +3497,7 @@ end;
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
type
|
||||
// Вспомогательный класс для генерации всех последовательностей. К сожалению, пока с object
|
||||
// Вспомогательный класс для генерации всех последовательностей
|
||||
SeqBase<T> = class(IEnumerable<T>,IEnumerator<T>)
|
||||
public
|
||||
function System.Collections.IEnumerable.GetEnumerator(): System.Collections.IEnumerator;
|
||||
|
|
@ -8113,12 +8116,23 @@ 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
|
||||
function Slice<T>(Self: sequence of T; from,step: integer): sequence of T; extensionmethod;
|
||||
begin
|
||||
if step=0 then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_COUNT_MUST_BE_NOT_EQUAL_0));
|
||||
{if step=0 then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0));
|
||||
if step<0 then
|
||||
begin
|
||||
if from<0 then
|
||||
|
|
@ -8133,14 +8147,21 @@ begin
|
|||
else
|
||||
if from<=0 then
|
||||
Result := Self.Where((x,i)->(i-from) mod step = 0)
|
||||
else Result := Self.Skip(from).Where((x,i)->i mod step = 0);
|
||||
else Result := Self.Skip(from).Where((x,i)->i mod step = 0);}
|
||||
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 длины не более 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_COUNT_MUST_BE_NOT_EQUAL_0));
|
||||
{if step=0 then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0));
|
||||
if step<0 then
|
||||
begin
|
||||
if from<0 then
|
||||
|
|
@ -8162,7 +8183,15 @@ begin
|
|||
count -= abs(from+1) div step + 1;
|
||||
Result := Self.Where((x,i)->(i-from) mod step = 0).Take(count)
|
||||
end
|
||||
else Result := Self.Skip(from).Where((x,i)->i mod step = 0).Take(count);
|
||||
else Result := Self.Skip(from).Where((x,i)->i mod step = 0).Take(count);}
|
||||
|
||||
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;
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
|
@ -8183,18 +8212,145 @@ begin
|
|||
Result := Self;
|
||||
end;
|
||||
|
||||
///--
|
||||
function CreateSliceFromListInternal<T>(Self: List<T>; from,step,count: integer): List<T>;
|
||||
begin
|
||||
Result := new List<T>(count);
|
||||
|
||||
var f := from;
|
||||
for var i:=0 to count-1 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 ArgumentException(GetTranslation(PARAMETER_COUNT_MUST_BE_GREATER_0));
|
||||
|
||||
if (from < 0) or (from > Len - 1) then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE));
|
||||
|
||||
var cnt := step > 0 ? Len - from : from + 1;
|
||||
var cntstep := (cnt-1) div abs(step) + 1;
|
||||
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);
|
||||
{if step = 0 then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0));
|
||||
|
||||
if (from < 0) or (from > Self.Count - 1) then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE));
|
||||
|
||||
var cnt := step > 0 ? Self.Count - from : from + 1;
|
||||
var cntstep := (cnt-1) div abs(step) + 1;
|
||||
if count > cntstep then
|
||||
count := cntstep;}
|
||||
|
||||
Result := CreateSliceFromListInternal(Self,from,step,count);
|
||||
end;
|
||||
|
||||
/// Возвращает срез списка от индекса from с шагом step
|
||||
function Slice<T>(Self: List<T>; from,step: integer): List<T>; extensionmethod;
|
||||
begin
|
||||
Result := Self.AsEnumerable.Slice(from,step).ToList;
|
||||
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 := Self.AsEnumerable.Slice(from,step,count).ToList;
|
||||
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;
|
||||
|
||||
///--
|
||||
function CalcCountForSystemSlice(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 (from < 0) or (from > Len - 1) then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE));
|
||||
|
||||
if (&to < -1) or (&to > Len) then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_TO_OUT_OF_RANGE));
|
||||
|
||||
var count: integer;
|
||||
|
||||
if step>0 then
|
||||
begin
|
||||
case situation of
|
||||
1: from := 0;
|
||||
2: &to := Len;
|
||||
3: begin
|
||||
from := 0;
|
||||
&to := Len;
|
||||
end;
|
||||
end;
|
||||
|
||||
var cnt := &to - from;
|
||||
if cnt<=0 then
|
||||
count := 0
|
||||
else count := (cnt-1) div step + 1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
case situation of
|
||||
1: from := Len - 1;
|
||||
2: &to := -1;
|
||||
3: begin
|
||||
from := Len - 1;
|
||||
&to := -1;
|
||||
end;
|
||||
end;
|
||||
|
||||
var cnt := from - &to;
|
||||
if cnt<=0 then
|
||||
count := 0
|
||||
else count := (cnt-1) div (-step) + 1;
|
||||
end;
|
||||
Result := count;
|
||||
end;
|
||||
|
||||
///--
|
||||
function SystemSliceListImpl<T>(Self: List<T>; situation: integer; from,&to: integer; step: integer := 1): List<T>;
|
||||
begin
|
||||
var count := CalcCountForSystemSlice(situation,Self.Count,from,&to,step);
|
||||
|
||||
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;
|
||||
|
||||
// -----------------------------------------------------
|
||||
//>> Методы расширения типа array of T # Extension methods for array of T
|
||||
|
|
@ -8290,7 +8446,7 @@ begin
|
|||
Result := System.Array.FindIndex(self,p);
|
||||
end;
|
||||
|
||||
/// Возвращает в виде массива все элементы, удовлетворяющие предикатуы
|
||||
/// Возвращает в виде массива все элементы, удовлетворяющие предикату
|
||||
function FindAll<T>(self: array of T; p: T->boolean): array of T; extensionmethod;
|
||||
begin
|
||||
Result := System.Array.FindAll(self,p);
|
||||
|
|
@ -8338,18 +8494,68 @@ begin
|
|||
System.Array.Sort(self,cmp);
|
||||
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 := Self.AsEnumerable.Slice(from,step).ToArray;
|
||||
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 := Self.AsEnumerable.Slice(from,step,count).ToArray;
|
||||
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 := CalcCountForSystemSlice(situation,Self.Length,from,&to,step);
|
||||
|
||||
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;
|
||||
|
||||
// -----------------------------------------------------
|
||||
//>> Методы расширения типа integer # Extension methods for integer
|
||||
|
|
@ -8636,18 +8842,73 @@ begin
|
|||
else Result := Self;
|
||||
end;
|
||||
|
||||
///--
|
||||
function CreateSliceFromStringInternal(Self: string; from,step,count: integer): string;
|
||||
begin
|
||||
var res := new StringBuilder(count);
|
||||
|
||||
for var i:=0 to count-1 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 := Self.AsEnumerable.Slice(from,step).JoinIntoString('');
|
||||
Result := SliceStringImpl(Self,from,step,integer.MaxValue);
|
||||
end;
|
||||
|
||||
/// Возвращает срез строки от индекса from с шагом step длины не более count
|
||||
function Slice(Self: string; from,step,count: integer): string; extensionmethod;
|
||||
begin
|
||||
Result := Self.AsEnumerable.Slice(from,step,count).JoinIntoString('');
|
||||
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 := CalcCountForSystemSlice(situation,Self.Length,fromv,tov,step);
|
||||
|
||||
Result := CreateSliceFromStringInternal(Self,fromv+1,step,count)
|
||||
end;
|
||||
|
||||
///--
|
||||
function SystemSlice(Self: string; situation: integer; from,&to: integer): string; extensionmethod;
|
||||
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;
|
||||
|
||||
|
||||
//--------------------------------------------
|
||||
//>> Методы расширения типа Func # Extension methods for Func
|
||||
//--------------------------------------------
|
||||
|
|
@ -8732,7 +8993,7 @@ end;
|
|||
// -------------------------------------------
|
||||
// Дополнения февраль 2016
|
||||
|
||||
// Добавляет поле к кортежу
|
||||
{// Добавляет поле к кортежу
|
||||
function Add<T1, T2, T3> (Self: (T1,T2); v: T3): (T1,T2,T3); extensionmethod;
|
||||
begin
|
||||
Result := (Self[0],Self[1],v);
|
||||
|
|
@ -8760,7 +9021,7 @@ 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;
|
||||
end;}
|
||||
|
||||
{// Определяет, есть ли указанный элемент в массиве
|
||||
function Contains<T>(self: array of T; x: T): boolean; extensionmethod;
|
||||
|
|
|
|||
Loading…
Reference in a new issue