Snippets

Updated by Stefan Glienke

File Spring.Span.pas Modified

  • Ignore whitespace
  • Hide word diff
     function GetIsEmpty: Boolean; inline;
     function GetItem(index: Integer): T; inline;
     procedure SetItem(index: Integer; const value: T); inline;
+    function GetRef(index: Integer): PT;
   public
     class function Create(const arr: TArray<T>): Span<T>; overload; static; inline;
     class function Create(const arr: TArray<T>; startIndex: Integer): Span<T>; overload; static; inline;
     property IsEmpty: Boolean read GetIsEmpty;
     property Items[index: Integer]: T read GetItem write SetItem; default;
     property Length: Integer read fLength;
+    property Refs[index: Integer]: PT read GetRef;
 
     class operator Implicit(const arr: TArray<T>): Span<T>; inline;
     class operator Equal(const left, right: Span<T>): Boolean; inline;
     class operator NotEqual(const left, right: ReadOnlySpan<T>): Boolean; inline;
   end;
 
+{$IFDEF DELPHIXE7_UP}
+  ReadOnlySpanOfCharHelper = record helper for ReadOnlySpan<Char>
+    class function &&op_Implicit(const value: string): ReadOnlySpan<Char>; static; inline;
+  end;
+{$ENDIF}
+
 function AsReadOnlySpan(const s: string): ReadOnlySpan<Char>; inline;
 
 implementation
   Result := fData[index];
 end;
 
+function Span<T>.GetRef(index: Integer): PT;
+begin
+{$IFOPT R+}
+  Guard.CheckIndex(fLength, index);
+{$ENDIF}
+  Result := @fData[index];
+end;
+
 function Span<T>.Slice(startIndex: Integer): Span<T>;
 begin
 {$IFOPT R+}
 {$ENDREGION}
 
 
+{$REGION 'ReadOnlySpanOfCharHelper'}
+
+{$IFDEF DELPHIXE7_UP}
+class function ReadOnlySpanOfCharHelper.&&op_Implicit(
+  const value: string): ReadOnlySpan<Char>;
+begin
+  Result.fLength := System.Length(value);
+  if Result.fLength > 0 then
+    Result.fData := Pointer(value)
+  else
+    Result.fData := nil;
+end;
+{$ENDIF}
+
+{$ENDREGION}
+
+
 end.
Updated by Stefan Glienke

File Spring.Span.pas Modified

  • Ignore whitespace
  • Hide word diff
 {***************************************************************************}
 
 {$I Spring.inc}
-{$O+}
+{$O+,W-}
 
 unit Spring.Span;
 
     fLength: Integer;
     function GetIsEmpty: Boolean; inline;
     function GetItem(index: Integer): T; inline;
+    procedure SetItem(index: Integer; const value: T); inline;
   public
     class function Create(const arr: TArray<T>): Span<T>; overload; static; inline;
     class function Create(const arr: TArray<T>; startIndex: Integer): Span<T>; overload; static; inline;
     function ToArray: TArray<T>;
 
     property IsEmpty: Boolean read GetIsEmpty;
-    property Items[index: Integer]: T read GetItem; default;
+    property Items[index: Integer]: T read GetItem write SetItem; default;
     property Length: Integer read fLength;
 
     class operator Implicit(const arr: TArray<T>): Span<T>; inline;
   startIndex: Integer): Span<T>;
 begin
 {$IFOPT R+}
-  Guard.CheckRange(System.Length(arr), startIndex, length);
+  Guard.CheckIndex(System.Length(arr), startIndex);
 {$ENDIF}
   Result.fData := @arr[startIndex];
   Result.fLength := System.Length(arr) - startIndex;
   Result.fLength := fLength - startIndex;
 end;
 
+procedure Span<T>.SetItem(index: Integer; const value: T);
+begin
+{$IFOPT R+}
+  Guard.CheckIndex(fLength, index);
+{$ENDIF}
+  fData[index] := value;
+end;
+
 function Span<T>.Slice(startIndex, length: Integer): Span<T>;
 begin
 {$IFOPT R+}
   startIndex: Integer): ReadOnlySpan<T>;
 begin
 {$IFOPT R+}
-  Guard.CheckRange(System.Length(arr), startIndex, length);
+  Guard.CheckIndex(System.Length(arr), startIndex);
 {$ENDIF}
   Result.fData := @arr[startIndex];
   Result.fLength := System.Length(arr) - startIndex;
 
 class operator ReadOnlySpan<T>.Implicit(const span: Span<T>): ReadOnlySpan<T>;
 begin
-  Result.fData := span.fData;
+  Result.fData := PT(span.fData);
   Result.fLength := span.fLength;
 end;
 
Created by Stefan Glienke

File Spring.Span.pas Added

  • Ignore whitespace
  • Hide word diff
+{***************************************************************************}
+{                                                                           }
+{           Spring Framework for Delphi                                     }
+{                                                                           }
+{           Copyright (c) 2009-2018 Spring4D Team                           }
+{                                                                           }
+{           http://www.spring4d.org                                         }
+{                                                                           }
+{***************************************************************************}
+{                                                                           }
+{  Licensed under the Apache License, Version 2.0 (the "License");          }
+{  you may not use this file except in compliance with the License.         }
+{  You may obtain a copy of the License at                                  }
+{                                                                           }
+{      http://www.apache.org/licenses/LICENSE-2.0                           }
+{                                                                           }
+{  Unless required by applicable law or agreed to in writing, software      }
+{  distributed under the License is distributed on an "AS IS" BASIS,        }
+{  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
+{  See the License for the specific language governing permissions and      }
+{  limitations under the License.                                           }
+{                                                                           }
+{***************************************************************************}
+
+{$I Spring.inc}
+{$O+}
+
+unit Spring.Span;
+
+interface
+
+uses
+  Spring;
+
+type
+  Span<T> = record
+  private type
+  {$POINTERMATH ON}
+    PT = ^T;
+  {$POINTERMATH OFF}
+    TEnumerator = record
+    private
+      fSpan: ^Span<T>;
+      fIndex: Integer;
+      function GetCurrent: T; inline;
+    public
+      function MoveNext: Boolean; inline;
+      property Current: T read GetCurrent;
+    end;
+  private
+    fData: PT;
+    fLength: Integer;
+    function GetIsEmpty: Boolean; inline;
+    function GetItem(index: Integer): T; inline;
+  public
+    class function Create(const arr: TArray<T>): Span<T>; overload; static; inline;
+    class function Create(const arr: TArray<T>; startIndex: Integer): Span<T>; overload; static; inline;
+    class function Create(const arr: TArray<T>; startIndex, length: Integer): Span<T>; overload; static; inline;
+    class function Create(const p: Pointer; length: Integer): Span<T>; overload; static; inline;
+
+    function GetEnumerator: TEnumerator; inline;
+
+    function Slice(startIndex: Integer): Span<T>; overload; inline;
+    function Slice(startIndex, length: Integer): Span<T>; overload; inline;
+
+    function ToArray: TArray<T>;
+
+    property IsEmpty: Boolean read GetIsEmpty;
+    property Items[index: Integer]: T read GetItem; default;
+    property Length: Integer read fLength;
+
+    class operator Implicit(const arr: TArray<T>): Span<T>; inline;
+    class operator Equal(const left, right: Span<T>): Boolean; inline;
+    class operator NotEqual(const left, right: Span<T>): Boolean; inline;
+  end;
+
+  ReadOnlySpan<T> = record
+  private type
+  {$POINTERMATH ON}
+    PT = ^T;
+  {$POINTERMATH OFF}
+    TEnumerator = record
+    private
+      fSpan: ^ReadOnlySpan<T>;
+      fIndex: Integer;
+      function GetCurrent: T; inline;
+    public
+      function MoveNext: Boolean; inline;
+      property Current: T read GetCurrent;
+    end;
+  private
+    fData: PT;
+    fLength: Integer;
+    function GetIsEmpty: Boolean; inline;
+    function GetItem(index: Integer): T; inline;
+  public
+    class function Create(const arr: TArray<T>): ReadOnlySpan<T>; overload; static; inline;
+    class function Create(const arr: TArray<T>; startIndex: Integer): ReadOnlySpan<T>; overload; static; inline;
+    class function Create(const arr: TArray<T>; startIndex, length: Integer): ReadOnlySpan<T>; overload; static; inline;
+    class function Create(const p: Pointer; length: Integer): ReadOnlySpan<T>; overload; static; inline;
+
+    function GetEnumerator: TEnumerator; inline;
+
+    function Slice(startIndex: Integer): ReadOnlySpan<T>; overload; inline;
+    function Slice(startIndex, length: Integer): ReadOnlySpan<T>; overload; inline;
+
+    function ToArray: TArray<T>;
+
+    property IsEmpty: Boolean read GetIsEmpty;
+    property Items[index: Integer]: T read GetItem; default;
+    property Length: Integer read fLength;
+
+    class operator Implicit(const arr: TArray<T>): ReadOnlySpan<T>; inline;
+    class operator Implicit(const span: Span<T>): ReadOnlySpan<T>; inline;
+    class operator Equal(const left, right: ReadOnlySpan<T>): Boolean; inline;
+    class operator NotEqual(const left, right: ReadOnlySpan<T>): Boolean; inline;
+  end;
+
+function AsReadOnlySpan(const s: string): ReadOnlySpan<Char>; inline;
+
+implementation
+
+function AsReadOnlySpan(const s: string): ReadOnlySpan<Char>;
+begin
+  Result.fLength := Length(s);
+  if Result.fLength > 0 then
+    Result.fData := Pointer(s)
+  else
+    Result.fData := nil;
+end;
+
+
+{$REGION 'Span<T>'}
+
+class function Span<T>.Create(const arr: TArray<T>): Span<T>;
+begin
+  Result.fData := @arr[0];
+  Result.fLength := System.Length(arr);
+end;
+
+class function Span<T>.Create(const arr: TArray<T>;
+  startIndex: Integer): Span<T>;
+begin
+{$IFOPT R+}
+  Guard.CheckRange(System.Length(arr), startIndex, length);
+{$ENDIF}
+  Result.fData := @arr[startIndex];
+  Result.fLength := System.Length(arr) - startIndex;
+end;
+
+class function Span<T>.Create(const arr: TArray<T>; startIndex,
+  length: Integer): Span<T>;
+begin
+{$IFOPT R+}
+  Guard.CheckRange(System.Length(arr), startIndex, length);
+{$ENDIF}
+  Result.fData := @arr[startIndex];
+  Result.fLength := length;
+end;
+
+class function Span<T>.Create(const p: Pointer; length: Integer): Span<T>;
+begin
+  Pointer(Result.fData) := p;
+  Result.fLength := length;
+end;
+
+function Span<T>.GetEnumerator: TEnumerator;
+begin
+  Result.fSpan := @Self;
+  Result.fIndex := -1;
+end;
+
+function Span<T>.GetIsEmpty: Boolean;
+begin
+  Result := fLength = 0;
+end;
+
+function Span<T>.GetItem(index: Integer): T;
+begin
+{$IFOPT R+}
+  Guard.CheckIndex(fLength, index);
+{$ENDIF}
+  Result := fData[index];
+end;
+
+function Span<T>.Slice(startIndex: Integer): Span<T>;
+begin
+{$IFOPT R+}
+  Guard.CheckIndex(fLength, startIndex);
+{$ENDIF}
+  Result.fData := @fData[startIndex];
+  Result.fLength := fLength - startIndex;
+end;
+
+function Span<T>.Slice(startIndex, length: Integer): Span<T>;
+begin
+{$IFOPT R+}
+  Guard.CheckRange(fLength, startIndex, length);
+{$ENDIF}
+  Result.fData := @fData[startIndex];
+  Result.fLength := length;
+end;
+
+function Span<T>.ToArray: TArray<T>;
+begin
+  SetLength(Result, fLength);
+  if TType.IsManaged<T> then
+    CopyArray(@Result[0], fData, TypeInfo(T), fLength)
+  else
+    Move(fData^, Result[0], fLength * SizeOf(T));
+end;
+
+class operator Span<T>.Implicit(const arr: TArray<T>): Span<T>;
+begin
+  Result.fData := @arr[0];
+  Result.fLength := System.Length(arr);
+end;
+
+class operator Span<T>.Equal(const left, right: Span<T>): Boolean;
+begin
+  Result := (left.fLength = right.fLength) and (left.fData = right.fData);
+end;
+
+class operator Span<T>.NotEqual(const left, right: Span<T>): Boolean;
+begin
+  Result := (left.fLength <> right.fLength) or (left.fData <> right.fData);
+end;
+
+{$ENDREGION}
+
+
+{$REGION 'Span<T>.TEnumerator'}
+
+function Span<T>.TEnumerator.GetCurrent: T;
+begin
+  Result := fSpan.fData[fIndex];
+end;
+
+function Span<T>.TEnumerator.MoveNext: Boolean;
+begin
+  Inc(fIndex);
+  Result := fIndex < fSpan.fLength;
+end;
+
+{$ENDREGION}
+
+
+{$REGION 'ReadOnlySpan<T>'}
+
+class function ReadOnlySpan<T>.Create(const arr: TArray<T>): ReadOnlySpan<T>;
+begin
+  Result.fData := @arr[0];
+  Result.fLength := System.Length(arr);
+end;
+
+class function ReadOnlySpan<T>.Create(const arr: TArray<T>;
+  startIndex: Integer): ReadOnlySpan<T>;
+begin
+{$IFOPT R+}
+  Guard.CheckRange(System.Length(arr), startIndex, length);
+{$ENDIF}
+  Result.fData := @arr[startIndex];
+  Result.fLength := System.Length(arr) - startIndex;
+end;
+
+class function ReadOnlySpan<T>.Create(const arr: TArray<T>; startIndex,
+  length: Integer): ReadOnlySpan<T>;
+begin
+{$IFOPT R+}
+  Guard.CheckRange(System.Length(arr), startIndex, length);
+{$ENDIF}
+  Result.fData := @arr[startIndex];
+  Result.fLength := length;
+end;
+
+class function ReadOnlySpan<T>.Create(const p: Pointer;
+  length: Integer): ReadOnlySpan<T>;
+begin
+  Pointer(Result.fData) := @p;
+  Result.fLength := length;
+end;
+
+function ReadOnlySpan<T>.GetEnumerator: TEnumerator;
+begin
+  Result.fSpan := @Self;
+  Result.fIndex := -1;
+end;
+
+function ReadOnlySpan<T>.GetIsEmpty: Boolean;
+begin
+  Result := fLength = 0;
+end;
+
+function ReadOnlySpan<T>.GetItem(index: Integer): T;
+begin
+{$IFOPT R+}
+  Guard.CheckIndex(fLength, index);
+{$ENDIF}
+  Result := fData[index];
+end;
+
+function ReadOnlySpan<T>.Slice(startIndex: Integer): ReadOnlySpan<T>;
+begin
+{$IFOPT R+}
+  Guard.CheckIndex(fLength, startIndex);
+{$ENDIF}
+  Result.fData := @fData[startIndex];
+  Result.fLength := fLength - startIndex;
+end;
+
+function ReadOnlySpan<T>.Slice(startIndex, length: Integer): ReadOnlySpan<T>;
+begin
+{$IFOPT R+}
+  Guard.CheckRange(fLength, startIndex, length);
+{$ENDIF}
+  Result.fData := @fData[startIndex];
+  Result.fLength := length;
+end;
+
+function ReadOnlySpan<T>.ToArray: TArray<T>;
+begin
+  SetLength(Result, fLength);
+  if TType.IsManaged<T> then
+    CopyArray(@Result[0], fData, TypeInfo(T), fLength)
+  else
+    Move(fData^, Result[0], fLength * SizeOf(T));
+end;
+
+class operator ReadOnlySpan<T>.Implicit(const arr: TArray<T>): ReadOnlySpan<T>;
+begin
+  Result.fData := @arr[0];
+  Result.fLength := System.Length(arr);
+end;
+
+class operator ReadOnlySpan<T>.Implicit(const span: Span<T>): ReadOnlySpan<T>;
+begin
+  Result.fData := span.fData;
+  Result.fLength := span.fLength;
+end;
+
+class operator ReadOnlySpan<T>.Equal(const left,
+  right: ReadOnlySpan<T>): Boolean;
+begin
+  Result := (left.fLength = right.fLength) and (left.fData = right.fData);
+end;
+
+class operator ReadOnlySpan<T>.NotEqual(const left,
+  right: ReadOnlySpan<T>): Boolean;
+begin
+  Result := (left.fLength <> right.fLength) or (left.fData <> right.fData);
+end;
+
+{$ENDREGION}
+
+
+{$REGION 'ReadOnlySpan<T>.TEnumerator'}
+
+function ReadOnlySpan<T>.TEnumerator.GetCurrent: T;
+begin
+  Result := fSpan.fData[fIndex];
+end;
+
+function ReadOnlySpan<T>.TEnumerator.MoveNext: Boolean;
+begin
+  Inc(fIndex);
+  Result := fIndex < fSpan.fLength;
+end;
+
+{$ENDREGION}
+
+
+end.
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.