Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2705dc8

Browse files
committed
Merge branch 'release/2.3.0'
Release v2.3.0
2 parents94c1c4d +3c2d428 commit2705dc8

38 files changed

+3355
-70
lines changed

‎CHANGELOG.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,26 @@ From v2.0.0 all notable changes to this project will be documented in this file.
88
99
The format is based on[Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
1010

11+
##v2.3.0 of 2025/09/13
12+
13+
* Updated the collection specification:
14+
* Added snippet properties to enable recording of compilation results with Delphi 13 (issue[62](https://github.com/delphidabbler/code-snippets/issues/62)).
15+
* Deprecated compiler results with value`W` (issue[63](https://github.com/delphidabbler/code-snippets/issues/63)).
16+
* Changes were made to the_Structures_ category:
17+
* Added a new`TIntegerRange` advanced record (issue[56](https://github.com/delphidabbler/code-snippets/issues/56)).
18+
* Fixed an error in the description of the`Range` snippet.
19+
* Added a warning to the`TRangeEx` advanced record to note potentially buggy behaviour if the range lower bound is greater than the upper bound.
20+
* Added new`RandomString` routine to the_String Management_ category (issue[28](https://github.com/delphidabbler/code-snippets/issues/28)).
21+
* Added results of compiling every snippet with Delphi 13 (issue[60](https://github.com/delphidabbler/code-snippets/issues/60)).
22+
* Fixed bug that was preventing the`Softmax` routine in the_Mathematics_ category from compiling due to a missing unit declaration (issue[61](https://github.com/delphidabbler/code-snippets/issues/61)).
23+
* Changes to unit tests:
24+
* Added a new DUnit test project for the_Structures_ category and added it to the_CodeSnippetsTestsXE_ project group. Unit tests for all snippets in the_Structures_ category were created (issue[58](https://github.com/delphidabbler/code-snippets/issues/58)).
25+
* Added further unit tests for all snippets in the_Arrays_ category that did not already have them (issue[38](https://github.com/delphidabbler/code-snippets/issues/38)).
26+
* Added unit tests for the new`RandomString` routine.
27+
* Documentation:
28+
* Updated`tests/README.md` re the unit test changes in this release and other minor revisions.
29+
* Fixed typo in`README.md`.
30+
1131
##v2.2.3 of 2025/04/03
1232

1333
* Added results of compiling with Delphi 12 for all snippets with no pre-existing compile results for that compiler (issue[#27](https://github.com/delphidabbler/code-snippets/issues/27)).

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ See the `README.md` file in the `tests` directory for full details.
3636

3737
Releases can be found on the`releases` tab on the GitHub project page.
3838

39-
Each release[^1] comprises three zip files, as follows (replace`X.Y.X` in the file names with the release version number):
39+
Each release[^1] comprises three zip files, as follows (replace`X.Y.Z` in the file names with the release version number):
4040

4141
*`csdb-vX.Y.Z-data.zip` - Contains all the data in the collection. Required by applications that access the collection.
4242
*`csdb-vX.Y.Z-docs.zip` - Contains the documentation developers need to understand the structure of the data.

‎collection/706.dat‎

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
type
2+
TIntegerRange = record
3+
strict private
4+
var
5+
fLowerBound: Integer;
6+
fUpperBound: Integer;
7+
function GetLowerBound: Integer;
8+
function GetUpperBound: Integer;
9+
function IsSubrangeOf(const ARange: TIntegerRange): Boolean;
10+
public
11+
// Constructs a range whose bounds are A and B. The lowest of the two
12+
// parameters is taken as the lower bound of the range with the other
13+
// parameter taken as the upper bound.
14+
// Valid bounds must fall in the range -MaxInt..MaxInt. An
15+
// EArgumentException exception is raised otherwise.
16+
constructor Create(const A, B: Integer);
17+
18+
// Constructs an empty range.
19+
class function CreateEmpty: TIntegerRange; static;
20+
21+
// Checks if the range is empty.
22+
function IsEmpty: Boolean;
23+
24+
// Returns the length of the range, i.e. the number of integers in the range.
25+
function Length: Cardinal;
26+
27+
// Constrains AValue to fall within this range. If the value lies within the
28+
// range it is returned unchanged. If it is outside the range then either
29+
// LowerBound or UpperBound is returned, depending on whether the value
30+
// falls below or above the range, respectively.
31+
// An EInvalidOpException exception is raised if the range is empty.
32+
function Constrain(const AValue: Integer): Integer;
33+
34+
// Checks if this range overlaps with ARange, i.e. the interection of the
35+
// ranges is non empty. Empty ranges cannot overlap with any range.
36+
function OverlapsWith(const ARange: TIntegerRange): Boolean;
37+
38+
// Checks if this range is immediately adjacent to ARange, with no overlap.
39+
// Empty ranges are never contiguous with other ranges or themselves.
40+
function IsContiguousWith(const ARange: TIntegerRange): Boolean;
41+
42+
// Checks if the set of all values in this range and ARange form a
43+
// continuous sequence. This implies that a range is continuous with itself.
44+
// Since adding an empty range to a non-empty range doesn't change the
45+
// non-empty range we define empty ranges to be continuous with any range.
46+
function IsContinuousWith(const ARange: TIntegerRange): Boolean;
47+
48+
// Checks if ranges A and B are the same
49+
class operator Equal(const A, B: TIntegerRange): Boolean;
50+
51+
// Checks if ranges A and B are not the same
52+
class operator NotEqual(const A, B: TIntegerRange): Boolean;
53+
54+
// Checks if range A is contained in, or is the same as, range B.
55+
// An empty range is deemed to be contained in any other range.
56+
class operator LessThanOrEqual(const A, B: TIntegerRange): Boolean;
57+
58+
// Checks if range A is contains, or is the same as, range B.
59+
// A non-empty range is never contained in an empty range.
60+
class operator GreaterThanOrEqual(const A, B: TIntegerRange): Boolean;
61+
62+
// Combine two ranges, A and B. The result is the smallest range that
63+
// contains both A and B.
64+
// If A and B are not continuous the resulting range will contain values
65+
// that were not in either A or B.
66+
// Combining any range either with itself or with an empty range is a no-op.
67+
class operator Add(const A, B: TIntegerRange): TIntegerRange;
68+
69+
// Returns a range that is the intersection of ranges A and B.
70+
// Returns an empty range if A and B do not overlap.
71+
class operator Multiply(const A, B: TIntegerRange): TIntegerRange;
72+
73+
// Checks if integer AValue is contained within range ARange.
74+
class operator In(const AValue: Integer; const ARange: TIntegerRange):
75+
Boolean;
76+
77+
// Implicitly casts ARange to a string. If ARange is non-empty the string
78+
// has format [X..Y], where X and Y are the lower and upper bounds of
79+
// ARange respectively. If ARange is empty then [] is returned.
80+
// This means that ARange can be assigned directly to a string.
81+
class operator Implicit(const ARange: TIntegerRange): string;
82+
83+
// Explicitly casts ARange to a string. If ARange is non-empty the string
84+
// has format [X..Y], where X and Y are the lower and upper bounds of
85+
// ARange respectively. If ARange is empty then [] is returned.
86+
// This means that ARange can be explicitly cast to a string using
87+
// string(ARange).
88+
class operator Explicit(const ARange: TIntegerRange): string;
89+
90+
// The lower bound of a non-empty range.
91+
// EInvalidOpException is raised if the property is read when the range is
92+
// empty.
93+
property LowerBound: Integer read GetLowerBound;
94+
95+
// The upper bound of a non-empty range.
96+
// EInvalidOpException is raised if the property is read when the range is
97+
// empty.
98+
property UpperBound: Integer read GetUpperBound;
99+
end;
100+
101+
class operator TIntegerRange.Add(const A, B: TIntegerRange): TIntegerRange;
102+
begin
103+
if A.IsEmpty then
104+
Exit(B);
105+
if B.IsEmpty then
106+
Exit(A);
107+
Result := TIntegerRange.Create(
108+
Math.Min(A.fLowerBound, B.fLowerBound),
109+
Math.Max(A.fUpperBound, B.fUpperBound)
110+
);
111+
end;
112+
113+
function TIntegerRange.Constrain(const AValue: Integer): Integer;
114+
begin
115+
if IsEmpty then
116+
raise Sysutils.EInvalidOpException.Create(
117+
'TIntegerRange.Constrain not valid for an empty range.'
118+
);
119+
Result := Math.EnsureRange(AValue, fLowerBound, fUpperBound);
120+
end;
121+
122+
constructor TIntegerRange.Create(const A, B: Integer);
123+
begin
124+
// Normalise range so that smallest parameter is the lower bound
125+
fLowerBound := Math.Min(A, B);
126+
fUpperBound := Math.Max(A, B);
127+
if fLowerBound = Low(Integer) then
128+
// This restriction is required to prevent the Length method's Cardinal
129+
// return value from wrapping around / overflowing
130+
raise SysUtils.EArgumentException.CreateFmt(
131+
'TIntegerRange.Create: Arguments must be greater than %d', [Low(Integer)]
132+
);
133+
end;
134+
135+
class function TIntegerRange.CreateEmpty: TIntegerRange;
136+
begin
137+
Result.fLowerBound := High(Integer);
138+
Result.fUpperBound := Low(Integer);
139+
end;
140+
141+
class operator TIntegerRange.Equal(const A, B: TIntegerRange): Boolean;
142+
begin
143+
if A.IsEmpty or B.IsEmpty then
144+
Exit(A.IsEmpty and B.IsEmpty);
145+
Result := (A.fLowerBound = B.fLowerBound) and (A.fUpperBound = B.fUpperBound);
146+
end;
147+
148+
class operator TIntegerRange.Explicit(const ARange: TIntegerRange): string;
149+
begin
150+
if ARange.IsEmpty then
151+
Exit('[]');
152+
Result := SysUtils.Format(
153+
'[%d..%d]', [ARange.fLowerBound, ARange.fUpperBound]
154+
);
155+
end;
156+
157+
function TIntegerRange.GetLowerBound: Integer;
158+
begin
159+
if IsEmpty then
160+
raise Sysutils.EInvalidOpException.Create(
161+
'TIntegerRange.LowerBound not valid for an empty range.'
162+
);
163+
Result := fLowerBound;
164+
end;
165+
166+
function TIntegerRange.GetUpperBound: Integer;
167+
begin
168+
if IsEmpty then
169+
raise Sysutils.EInvalidOpException.Create(
170+
'TIntegerRange.LowerBound not valid for an empty range.'
171+
);
172+
Result := fUpperBound;
173+
end;
174+
175+
class operator TIntegerRange.GreaterThanOrEqual(const A, B: TIntegerRange):
176+
Boolean;
177+
begin
178+
Result := B.IsSubrangeOf(A);
179+
end;
180+
181+
class operator TIntegerRange.Implicit(const ARange: TIntegerRange): string;
182+
begin
183+
Result := string(ARange); // calls Explicit cast operator
184+
end;
185+
186+
class operator TIntegerRange.In(const AValue: Integer;
187+
const ARange: TIntegerRange): Boolean;
188+
begin
189+
if ARange.IsEmpty then
190+
Exit(False);
191+
Result := (AValue >= ARange.fLowerBound) and (AValue <= ARange.fUpperBound);
192+
end;
193+
194+
function TIntegerRange.IsContiguousWith(const ARange: TIntegerRange): Boolean;
195+
begin
196+
if Self.IsEmpty or ARange.IsEmpty then
197+
Exit(False);
198+
Result := (Self + ARange).Length = (Self.Length + ARange.Length);
199+
end;
200+
201+
function TIntegerRange.IsContinuousWith(const ARange: TIntegerRange): Boolean;
202+
begin
203+
if Self.IsEmpty or ARange.IsEmpty then
204+
// Empty ranges are only continuous with other empty ranges
205+
Exit(True);
206+
Result := IsContiguousWith(ARange) or OverlapsWith(ARange);
207+
end;
208+
209+
function TIntegerRange.IsEmpty: Boolean;
210+
begin
211+
Result := fLowerBound > fUpperBound;
212+
end;
213+
214+
function TIntegerRange.IsSubrangeOf(const ARange: TIntegerRange): Boolean;
215+
begin
216+
if ARange.IsEmpty then
217+
Exit(Self.IsEmpty);
218+
Result := (Self.fLowerBound >= ARange.fLowerBound)
219+
and (Self.fUpperBound <= ARange.fUpperBound)
220+
or Self.IsEmpty
221+
end;
222+
223+
function TIntegerRange.Length: Cardinal;
224+
begin
225+
if IsEmpty then
226+
Exit(0);
227+
Result := fUpperBound - fLowerBound + 1
228+
end;
229+
230+
class operator TIntegerRange.LessThanOrEqual(const A, B: TIntegerRange):
231+
Boolean;
232+
begin
233+
Result := A.IsSubrangeOf(B);
234+
end;
235+
236+
class operator TIntegerRange.Multiply(const A, B: TIntegerRange): TIntegerRange;
237+
var
238+
Up, Lo: Integer;
239+
begin
240+
if A.IsEmpty or B.IsEmpty then
241+
Exit(TIntegerRange.CreateEmpty);
242+
Lo := Math.Max(A.fLowerBound, B.fLowerBound);
243+
Up := Math.Min(A.fUpperBound, B.fUpperBound);
244+
if Lo <= Up then
245+
Result := TIntegerRange.Create(Lo, Up)
246+
else
247+
Result := TIntegerRange.CreateEmpty;
248+
end;
249+
250+
class operator TIntegerRange.NotEqual(const A, B: TIntegerRange): Boolean;
251+
begin
252+
if A.IsEmpty or B.IsEmpty then
253+
Exit(A.IsEmpty <> B.IsEmpty);
254+
Result := (A.fLowerBound <> B.fLowerBound)
255+
or (A.fUpperBound <> B.fUpperBound);
256+
end;
257+
258+
function TIntegerRange.OverlapsWith(const ARange: TIntegerRange): Boolean;
259+
begin
260+
Result := not (Self * ARange).IsEmpty;
261+
end;

‎collection/707.dat‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
function RandomString(const SL: Classes.TStrings): string; overload;
2+
begin
3+
if SL.Count = 0 then
4+
raise SysUtils.EArgumentException.Create(
5+
'RandomString called with empty string list'
6+
);
7+
Result := SL[Random(SL.Count)];
8+
end;

‎collection/VERSION‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.2.3
1+
2.3.0

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp