-
-
Notifications
You must be signed in to change notification settings - Fork 753
Restrict length #4827
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Restrict length #4827
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| `hasLength` now enforces that `length` has type `size_t` | ||
|
|
||
| Historically `hasLength!R` yielded `true` for types whereby | ||
| `R.length` returns other types convertible to `ulong`, such as `int`, `ushort`, | ||
| `const(size_t)`, user-defined types using `alias this`, or notably `ulong` on | ||
| 32-bit systems. This behavior has been deprecated. After December 2017, | ||
| $(REF hasLength, std, range, primitives) will yield `true` only if `R.length` | ||
| yields the exact type `size_t`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1390,28 +1390,56 @@ template hasLvalueElements(R) | |
| } | ||
|
|
||
| /** | ||
| Returns $(D true) if $(D R) has a $(D length) member that returns an | ||
| integral type. $(D R) does not have to be a range. Note that $(D | ||
| length) is an optional primitive as no range must implement it. Some | ||
| ranges do not store their length explicitly, some cannot compute it | ||
| without actually exhausting the range (e.g. socket streams), and some | ||
| other ranges may be infinite. | ||
|
|
||
| Although narrow string types ($(D char[]), $(D wchar[]), and their | ||
| qualified derivatives) do define a $(D length) property, $(D | ||
| hasLength) yields $(D false) for them. This is because a narrow | ||
| string's length does not reflect the number of characters, but instead | ||
| the number of encoding units, and as such is not useful with | ||
| range-oriented algorithms. | ||
| */ | ||
| Yields `true` if `R` has a `length` member that returns a value of `size_t` | ||
| type. `R` does not have to be a range. If `R` is a range, algorithms in the | ||
| standard library are only guaranteed to support `length` with type `size_t`. | ||
|
|
||
| Note that `length` is an optional primitive as no range must implement it. Some | ||
| ranges do not store their length explicitly, some cannot compute it without | ||
| actually exhausting the range (e.g. socket streams), and some other ranges may | ||
| be infinite. | ||
|
|
||
| Although narrow string types (`char[]`, `wchar[]`, and their qualified | ||
| derivatives) do define a `length` property, `hasLength` yields `false` for them. | ||
| This is because a narrow string's length does not reflect the number of | ||
| characters, but instead the number of encoding units, and as such is not useful | ||
| with range-oriented algorithms. To use strings as random-access ranges with | ||
| length, use $(REF representation, std, string) or $(REF byCodeUnit, std, utf). | ||
|
|
||
| Deprecation: Historically `hasLength!R` yielded `true` for types whereby | ||
| `R.length` returns other types convertible to `ulong`, such as `int`, `ushort`, | ||
| `const(size_t)`, user-defined types using `alias this`, or notably `ulong` on | ||
| 32-bit systems. This behavior has been deprecated. After December 2017, | ||
| `hasLength` will yield `true` only if `R.length` yields the exact type `size_t`. | ||
| */ | ||
| template hasLength(R) | ||
| { | ||
| enum bool hasLength = !isNarrowString!R && is(typeof( | ||
| (inout int = 0) | ||
| static if (is(typeof(((R* r) => r.length)(null)) Length)) | ||
| { | ||
| R r = R.init; | ||
| ulong l = r.length; | ||
| })); | ||
| static if (is(Length == size_t)) | ||
| { | ||
| enum bool hasLength = !isNarrowString!R; | ||
| } | ||
| else static if (is(Length : ulong)) | ||
| { | ||
| // @@@DEPRECATED_2017-12@@@ | ||
| // Uncomment the deprecated(...) message and take the pragma(msg) | ||
| // out once https://issues.dlang.org/show_bug.cgi?id=10181 is fixed. | ||
| pragma(msg, __FILE__ ~ "(" ~ __LINE__.stringof ~ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is the FILE and LINE of std.range.primitives interesting here? You'd need to pass them as defaults for template arguments to get the instantiating side.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They emulate what the |
||
| "): Note: length must have type size_t on all systems" ~ | ||
| ", please update your code by December 2017."); | ||
| //deprecated("length must have type size_t on all systems") | ||
| enum bool hasLength = true; | ||
| } | ||
| else | ||
| { | ||
| enum bool hasLength = false; | ||
| } | ||
| } | ||
| else | ||
| { | ||
| enum bool hasLength = false; | ||
| } | ||
| } | ||
|
|
||
| /// | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason why you mix the
Length == size_tandLength : ulongstyles?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These aren't styles.
==checks for exact match,:is convertibility.