From 0eaee02da911dfe27e514c430e5ed59d9a166584 Mon Sep 17 00:00:00 2001 From: Neil MacIntosh Date: Wed, 4 Nov 2015 13:53:09 -0800 Subject: [PATCH 1/4] Rename: array_view=>span, string_view=>string_span. --- CppCoreGuidelines.md | 122 +++++++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 9f5484f..5bda590 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -488,7 +488,7 @@ If two `int`s are meant to be the coordinates of a 2D point, say so: Look for common patterns for which there are better alternatives * simple `for` loops vs. range-`for` loops -* `f(T*, int)` interfaces vs. `f(array_view)` interfaces +* `f(T*, int)` interfaces vs. `f(span)` interfaces * loop variables in too large a scope * naked `new` and `delete` * functions with many arguments of built-in types @@ -521,8 +521,8 @@ For example: * unions - use `variant` * casts - minimize their use; templates can help -* array decay - use `array_view` -* range errors - use `array_view` +* array decay - use `span` +* range errors - use `span` * narrowing conversions - minimize their use and use `narrow` or `narrow_cast` where they are necessary ### P.5: Prefer compile-time checking to run-time checking @@ -553,7 +553,7 @@ Code clarity and performance. You don't need to write error handlers for errors ##### Example - void read(array_view r); // read into the range of integers r + void read(span r); // read into the range of integers r **Alternative formulation**: Don't postpone to run time what can be done well at compile time. @@ -614,13 +614,13 @@ The standard library resource management pointers fail to pass the size when the We need to pass the pointer and the number of elements as an integral object: extern void f4(vector&); // separately compiled, possibly dynamically loaded - extern void f4(array_view); // separately compiled, possibly dynamically loaded + extern void f4(span); // separately compiled, possibly dynamically loaded void g3(int n) { vector v(n); f4(v); // pass a reference, retain ownership - f4(array_view{v}); // pass a view, retain ownership + f4(span{v}); // pass a view, retain ownership } This design carries the number of elements along as an integral part of an object, so that errors are unlikely and dynamic (run-time) checking is always feasible, if not always affordable. @@ -690,7 +690,7 @@ The (pointer, count)-style interface leaves `increment1()` with no realistic way Assuming that we could check subscripts for out of range access, the error would not be discovered until `p[10]` was accessed. We could check earlier and improve the code: - void increment2(array_view p) + void increment2(span p) { for (int& x : p) ++x; } @@ -1522,7 +1522,7 @@ Either is undefined behavior and a potentially very nasty bug. Consider using explicit ranges: - void copy(array_view r, array_view r2); // copy r to r2 + void copy(span r, span r2); // copy r to r2 ##### Example, bad @@ -1537,14 +1537,14 @@ Passing `10` as the `n` argument may be a mistake: the most common convention is **Alternative**: Use a support class that ensures that the number of elements is correct and prevents dangerous implicit conversions. For example: - void draw2(array_view); + void draw2(span); Circle arr[10]; // ... - draw2(array_view(arr)); // deduce the number of elements + draw2(span(arr)); // deduce the number of elements draw2(arr); // deduce the element type and array size - void draw3(array_view); - draw3(arr); // error: cannot convert Circle[10] to array_view + void draw3(span); + draw3(arr); // error: cannot convert Circle[10] to span This `draw2()` passes the same amount of information to `draw()`, but makes the fact that it is supposed to be a range of `Circle`s explicit. See ???. @@ -1661,9 +1661,9 @@ If the order of the parameters is not important, there is no problem: ##### Alternative -Don't pass arrays as pointers, pass an object representing a range (e.g., an `array_view`): +Don't pass arrays as pointers, pass an object representing a range (e.g., an `span`): - void copy_n(array_view p, array_view q); // copy from p to q + void copy_n(span p, span q); // copy from p to q ##### Enforcement @@ -1749,7 +1749,7 @@ Argument passing rules: * [F.15: Prefer simple and conventional ways of passing information](#Rf-conventional) * [F.16: Use `T*` or `owner` or a smart pointer to designate a single object](#Rf-ptr) * [F.17: Use a `not_null` to indicate "null" is not a valid value](#Rf-nullptr) -* [F.18: Use an `array_view` or an `array_view_p` to designate a half-open sequence](#Rf-range) +* [F.18: Use an `span` or an `span_p` to designate a half-open sequence](#Rf-range) * [F.19: Use a `zstring` or a `not_null` to designate a C-style string](#Rf-string) * [F.20: Use a `const T&` parameter for a large object](#Rf-const-T-ref) * [F.21: Use a `T` parameter for a small object](#Rf-T) @@ -2288,7 +2288,7 @@ Clarity. Making it clear that a test for null isn't needed. not_null check(T* p) { if (p) return not_null{p}; throw Unexpected_nullptr{}; } - void computer(not_null> p) + void computer(not_null> p) { if (0 < p.size()) { // bad: redundant test // ... @@ -2297,7 +2297,7 @@ Clarity. Making it clear that a test for null isn't needed. ##### Note -`not_null` is not just for built-in pointers. It works for `array_view`, `string_view`, `unique_ptr`, `shared_ptr`, and other pointer-like types. +`not_null` is not just for built-in pointers. It works for `span`, `string_span`, `unique_ptr`, `shared_ptr`, and other pointer-like types. ##### Enforcement @@ -2305,7 +2305,7 @@ Clarity. Making it clear that a test for null isn't needed. * (Simple) Error if a raw pointer is sometimes dereferenced after first being tested against `nullptr` (or equivalent) within the function and sometimes is not. * (Simple) Warn if a `not_null` pointer is tested against `nullptr` within a function. -### F.18: Use an `array_view` or an `array_view_p` to designate a half-open sequence +### F.18: Use an `span` or an `span_p` to designate a half-open sequence ##### Reason @@ -2313,7 +2313,7 @@ Informal/non-explicit ranges are a source of errors. ##### Example - X* find(array_view r, const X& v); // find v in r + X* find(span r, const X& v); // find v in r vector vec; // ... @@ -2321,21 +2321,21 @@ Informal/non-explicit ranges are a source of errors. ##### Note -Ranges are extremely common in C++ code. Typically, they are implicit and their correct use is very hard to ensure. In particular, given a pair of arguments `(p, n)` designating an array [`p`:`p+n`), it is in general impossible to know if there really are n elements to access following `*p`. `array_view` and `array_view_p` are simple helper classes designating a [p:q) range and a range starting with p and ending with the first element for which a predicate is true, respectively. +Ranges are extremely common in C++ code. Typically, they are implicit and their correct use is very hard to ensure. In particular, given a pair of arguments `(p, n)` designating an array [`p`:`p+n`), it is in general impossible to know if there really are n elements to access following `*p`. `span` and `span_p` are simple helper classes designating a [p:q) range and a range starting with p and ending with the first element for which a predicate is true, respectively. ##### Note -An `array_view` object does not own its elements and is so small that it can be passed by value. +An `span` object does not own its elements and is so small that it can be passed by value. ##### Note -Passing an `array_view` object as an argument is exactly as efficient as passing a pair of pointer arguments or passing a pointer and an integer count. +Passing an `span` object as an argument is exactly as efficient as passing a pair of pointer arguments or passing a pointer and an integer count. **See also**: [Support library](#S-gsl). ##### Enforcement -(Complex) Warn where accesses to pointer parameters are bounded by other parameters that are integral types and suggest they could use `array_view` instead. +(Complex) Warn where accesses to pointer parameters are bounded by other parameters that are integral types and suggest they could use `span` instead. ### F.19: Use a `zstring` or a `not_null` to designate a C-style string @@ -5904,7 +5904,7 @@ Subscripting the resulting base pointer will lead to invalid object access and p ##### Enforcement * Flag all combinations of array decay and base to derived conversions. -* Pass an array as an `array_view` rather than as a pointer, and don't let the array name suffer a derived-to-base conversion before getting into the `array_view` +* Pass an array as an `span` rather than as a pointer, and don't let the array name suffer a derived-to-base conversion before getting into the `span` # C.over: Overloading and overloaded operators @@ -6366,7 +6366,7 @@ Whenever you deal with a resource that needs paired acquire/release function cal Consider: - void send(X* x, cstring_view destination) + void send(X* x, cstring_span destination) { auto port = OpenPort(destination); my_mutex.lock(); @@ -6385,7 +6385,7 @@ Further, if any of the code marked `...` throws an exception, then `x` is leaked Consider: - void send(unique_ptr x, cstring_view destination) // x owns the X + void send(unique_ptr x, cstring_span destination) // x owns the X { Port port{destination}; // port owns the PortHandle lock_guard guard{my_mutex}; // guard owns the lock @@ -6401,7 +6401,7 @@ What is `Port`? A handy wrapper that encapsulates the resource: class Port { PortHandle port; public: - Port(cstring_view destination) : port{OpenPort(destination)} { } + Port(cstring_span destination) : port{OpenPort(destination)} { } ~Port() { ClosePort(port); } operator PortHandle() { return port; } @@ -6420,7 +6420,7 @@ Where a resource is "ill-behaved" in that it isn't represented as a class with a ##### Reason -Arrays are best represented by a container type (e.g., `vector` (owning)) or an `array_view` (non-owning). +Arrays are best represented by a container type (e.g., `vector` (owning)) or an `span` (non-owning). Such containers and views hold sufficient information to do range checking. ##### Example, bad @@ -6433,7 +6433,7 @@ Such containers and views hold sufficient information to do range checking. } The compiler does not read comments, and without reading other code you do not know whether `p` really points to `n` elements. -Use an `array_view` instead. +Use an `span` instead. ##### Example @@ -6767,7 +6767,7 @@ An array decays to a pointer, thereby losing its size, opening the opportunity f ??? what do we recommend: f(int*[]) or f(int**) ??? -**Alternative**: Use `array_view` to preserve size information. +**Alternative**: Use `span` to preserve size information. ##### Enforcement @@ -8540,7 +8540,7 @@ You should know enough not to need parentheses for: Complicated pointer manipulation is a major source of errors. -* Do all pointer arithmetic on an `array_view` (exception ++p in simple loop???) +* Do all pointer arithmetic on an `span` (exception ++p in simple loop???) * Avoid pointers to pointers * ??? @@ -12438,11 +12438,11 @@ The following are under consideration but not yet in the rules below, and may be An implementation of this profile shall recognize the following patterns in source code as non-conforming and issue a diagnostic. -### Bounds.1: Don't use pointer arithmetic. Use `array_view` instead. +### Bounds.1: Don't use pointer arithmetic. Use `span` instead. ##### Reason -Pointers should only refer to single objects, and pointer arithmetic is fragile and easy to get wrong. `array_view` is a bounds-checked, safe type for accessing arrays of data. +Pointers should only refer to single objects, and pointer arithmetic is fragile and easy to get wrong. `span` is a bounds-checked, safe type for accessing arrays of data. ##### Example, bad @@ -12470,13 +12470,13 @@ Pointers should only refer to single objects, and pointer arithmetic is fragile ##### Example, good - void f(array_view a) // BETTER: use array_view in the function declaration + void f(span a) // BETTER: use span in the function declaration { if (a.length() < 2) return; int n = *a++; // OK - array_view q = a + 1; // OK + span q = a + 1; // OK if (a.length() < 6) return; @@ -12495,7 +12495,7 @@ Issue a diagnostic for any arithmetic operation on an expression of pointer type ##### Reason -Dynamic accesses into arrays are difficult for both tools and humans to validate as safe. `array_view` is a bounds-checked, safe type for accessing arrays of data. `at()` is another alternative that ensures single accesses are bounds-checked. If iterators are needed to access an array, use the iterators from an `array_view` constructed over the array. +Dynamic accesses into arrays are difficult for both tools and humans to validate as safe. `span` is a bounds-checked, safe type for accessing arrays of data. `at()` is another alternative that ensures single accesses are bounds-checked. If iterators are needed to access an array, use the iterators from an `span` constructed over the array. ##### Example, bad @@ -12509,19 +12509,19 @@ Dynamic accesses into arrays are difficult for both tools and humans to validate ##### Example, good - // ALTERNATIVE A: Use an array_view + // ALTERNATIVE A: Use an span - // A1: Change parameter type to use array_view - void f(array_view a, int pos) + // A1: Change parameter type to use span + void f(span a, int pos) { a[pos / 2] = 1; // OK a[pos - 1] = 2; // OK } - // A2: Add local array_view and use that + // A2: Add local span and use that void f(array arr, int pos) { - array_view a = {arr, pos} + span a = {arr, pos} a[pos / 2] = 1; // OK a[pos - 1] = 2; // OK } @@ -12544,11 +12544,11 @@ Dynamic accesses into arrays are difficult for both tools and humans to validate ##### Example, good - // ALTERNATIVE A: Use an array_view + // ALTERNATIVE A: Use an span void f1() { int arr[COUNT]; - array_view av = arr; + span av = arr; for (int i = 0; i < COUNT; ++i) av[i] = i; } @@ -12581,7 +12581,7 @@ Issue a diagnostic for any indexing expression on an expression or variable of a ##### Reason -Pointers should not be used as arrays. `array_view` is a bounds-checked, safe alternative to using pointers to access arrays. +Pointers should not be used as arrays. `span` is a bounds-checked, safe alternative to using pointers to access arrays. ##### Example, bad @@ -12597,15 +12597,15 @@ Pointers should not be used as arrays. `array_view` is a bounds-checked, safe al ##### Example, good void g(int* p, size_t length); - void g1(array_view av); // BETTER: get g() changed. + void g1(span av); // BETTER: get g() changed. void f() { int a[5]; - array_view av = a; + span av = a; g(a.data(), a.length()); // OK, if you have no choice - g1(a); // OK - no decay here, instead use implicit array_view ctor + g1(a); // OK - no decay here, instead use implicit span ctor } ##### Enforcement @@ -12616,7 +12616,7 @@ Issue a diagnostic for any expression that would rely on implicit conversion of ##### Reason -These functions all have bounds-safe overloads that take `array_view`. Standard types such as `vector` can be modified to perform bounds-checks under the bounds profile (in a compatible way, such as by adding contracts), or used with `at()`. +These functions all have bounds-safe overloads that take `span`. Standard types such as `vector` can be modified to perform bounds-checks under the bounds profile (in a compatible way, such as by adding contracts), or used with `at()`. ##### Example, bad @@ -12712,16 +12712,16 @@ If something is not supposed to be `nullptr`, say so: * `not_null` // `T` is usually a pointer type (e.g., `not_null` and `not_null>`) that may not be `nullptr`. `T` can be any type for which `==nullptr` is meaningful. -* `array_view` // [`p`:`p+n`), constructor from `{p, q}` and `{p, n}`; `T` is the pointer type -* `array_view_p` // `{p, predicate}` [`p`:`q`) where `q` is the first element for which `predicate(*p)` is true -* `string_view` // `array_view` -* `cstring_view` // `array_view` +* `span` // [`p`:`p+n`), constructor from `{p, q}` and `{p, n}`; `T` is the pointer type +* `span_p` // `{p, predicate}` [`p`:`q`) where `q` is the first element for which `predicate(*p)` is true +* `string_span` // `span` +* `cstring_span` // `span` A `*_view` refers to zero or more mutable `T`s unless `T` is a `const` type. -"Pointer arithmetic" is best done within `array_view`s. -A `char*` that points to something that is not a C-style string (e.g., a pointer into an input buffer) should be represented by an `array_view`. -There is no really good way to say "pointer to a single `char`" (`string_view{p, 1}` can do that, and `T*` where `T` is a `char` in a template that has not been specialized for C-style strings). +"Pointer arithmetic" is best done within `span`s. +A `char*` that points to something that is not a C-style string (e.g., a pointer into an input buffer) should be represented by an `span`. +There is no really good way to say "pointer to a single `char`" (`string_span{p, 1}` can do that, and `T*` where `T` is a `char` in a template that has not been specialized for C-style strings). * `zstring` // a `char*` supposed to be a C-style string; that is, a zero-terminated sequence of `char` or `null_ptr` * `czstring` // a `const char*` supposed to be a C-style string; that is, a zero-terminated sequence of `const` `char` or `null_ptr` @@ -12738,7 +12738,7 @@ Use `not_null` for C-style strings that cannot be `nullptr`. ??? Do we * `shared_ptr` // shared ownership: `std::shared_ptr` (a counted pointer) * `stack_array` // A stack-allocated array. The number of elements are determined at construction and fixed thereafter. The elements are mutable unless `T` is a `const` type. * `dyn_array` // ??? needed ??? A heap-allocated array. The number of elements are determined at construction and fixed thereafter. - The elements are mutable unless `T` is a `const` type. Basically an `array_view` that allocates and owns its elements. + The elements are mutable unless `T` is a `const` type. Basically an `span` that allocates and owns its elements. ## GSL.assert: Assertions @@ -13260,9 +13260,9 @@ Because we want to use them immediately, and because they are temporary in that No. The GSL exists only to supply a few types and aliases that are not currently in the standard library. If the committee decides on standardized versions (of these or other types that fill the same need) then they can be removed from the GSL. -### FAQ.55: If you’re using the standard types where available, why is the GSL `string_view` different from the `string_view` in the Library Fundamentals 1 Technical Specification? Why not just use the committee-approved `string_view`? +### FAQ.55: If you’re using the standard types where available, why is the GSL `string_span` different from the `string_span` in the Library Fundamentals 1 Technical Specification? Why not just use the committee-approved `string_span`? -Because `string_view` is still undergoing standardization, and is in a state for public review input to improve it. Types that appear in Technical Specifications (TSes) are not yet part of the International Standard (IS), and one reason they are put in TSes first is to gain experience with the feature before they are cast in a final form to become part of the standard. Some of the GSL authors are contributing what we have learned about `string_view` in the process of developing these guidelines, and a discussion of the differences, as a paper for the next ISO meeting for consideration along with all the other similar papers for the committee to consider as it decides on the final form of this feature. +Because `string_span` is still undergoing standardization, and is in a state for public review input to improve it. Types that appear in Technical Specifications (TSes) are not yet part of the International Standard (IS), and one reason they are put in TSes first is to gain experience with the feature before they are cast in a final form to become part of the standard. Some of the GSL authors are contributing what we have learned about `string_span` in the process of developing these guidelines, and a discussion of the differences, as a paper for the next ISO meeting for consideration along with all the other similar papers for the committee to consider as it decides on the final form of this feature. ### FAQ.56: Is `owner` the same as the proposed `observer_ptr`? @@ -13322,7 +13322,7 @@ Here are some (very general) ideas: * The ideal is "just upgrade everything." That gives the most benefits for the shortest total time. In most circumstances, it is also impossible. -* We could convert a code base module for module, but any rules that affects interfaces (especially ABIs), such as [use `array_view`](#SS-views), cannot be done on a per-module basis. +* We could convert a code base module for module, but any rules that affects interfaces (especially ABIs), such as [use `span`](#SS-views), cannot be done on a per-module basis. * We could convert code "bottom up" starting with the rules we estimate will give the greatest benefits and/or the least trouble in a given code base. * We could start by focusing on the interfaces, e.g., make sure that no resources are lost and no pointer is misused. This would be a set of changes across the whole code base, but would most likely have huge benefits. @@ -13744,7 +13744,7 @@ The code is simpler as well as correct. A checker must consider all "naked pointers" suspicious. A checker probably must rely on a human-provided list of resources. For starters, we know about the standard-library containers, `string`, and smart pointers. -The use of `array_view` and `string_view` should help a lot (they are not resource handles). +The use of `span` and `string_span` should help a lot (they are not resource handles). ### A "raw" pointer or reference is never a resource handle @@ -13782,7 +13782,7 @@ The `string`s of `v` are destroyed upon exit from `bad()` and so is `v` itself. ##### Enforcement -Most compilers already warn about simple cases and has the information to do more. Consider any pointer returned from a function suspect. Use containers, resource handles, and views (e.g., `array_view` known not to be resource handles) to lower the number of cases to be examined. For starters, consider every class with a destructor a resource handle. +Most compilers already warn about simple cases and has the information to do more. Consider any pointer returned from a function suspect. Use containers, resource handles, and views (e.g., `span` known not to be resource handles) to lower the number of cases to be examined. For starters, consider every class with a destructor a resource handle. ### Use templates to express containers (and other resource handles) From 0a9cdd34b65f96462ef268d317a2724abed012eb Mon Sep 17 00:00:00 2001 From: Neil MacIntosh Date: Wed, 4 Nov 2015 14:11:47 -0800 Subject: [PATCH 2/4] Grammar fixes after span rename. --- CppCoreGuidelines.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 5bda590..6b3bc6b 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -1661,7 +1661,7 @@ If the order of the parameters is not important, there is no problem: ##### Alternative -Don't pass arrays as pointers, pass an object representing a range (e.g., an `span`): +Don't pass arrays as pointers, pass an object representing a range (e.g., a `span`): void copy_n(span p, span q); // copy from p to q @@ -1749,7 +1749,7 @@ Argument passing rules: * [F.15: Prefer simple and conventional ways of passing information](#Rf-conventional) * [F.16: Use `T*` or `owner` or a smart pointer to designate a single object](#Rf-ptr) * [F.17: Use a `not_null` to indicate "null" is not a valid value](#Rf-nullptr) -* [F.18: Use an `span` or an `span_p` to designate a half-open sequence](#Rf-range) +* [F.18: Use a `span` or a `span_p` to designate a half-open sequence](#Rf-range) * [F.19: Use a `zstring` or a `not_null` to designate a C-style string](#Rf-string) * [F.20: Use a `const T&` parameter for a large object](#Rf-const-T-ref) * [F.21: Use a `T` parameter for a small object](#Rf-T) @@ -2305,7 +2305,7 @@ Clarity. Making it clear that a test for null isn't needed. * (Simple) Error if a raw pointer is sometimes dereferenced after first being tested against `nullptr` (or equivalent) within the function and sometimes is not. * (Simple) Warn if a `not_null` pointer is tested against `nullptr` within a function. -### F.18: Use an `span` or an `span_p` to designate a half-open sequence +### F.18: Use a `span` or a `span_p` to designate a half-open sequence ##### Reason @@ -2325,11 +2325,11 @@ Ranges are extremely common in C++ code. Typically, they are implicit and their ##### Note -An `span` object does not own its elements and is so small that it can be passed by value. +A `span` object does not own its elements and is so small that it can be passed by value. ##### Note -Passing an `span` object as an argument is exactly as efficient as passing a pair of pointer arguments or passing a pointer and an integer count. +Passing a `span` object as an argument is exactly as efficient as passing a pair of pointer arguments or passing a pointer and an integer count. **See also**: [Support library](#S-gsl). @@ -5904,7 +5904,7 @@ Subscripting the resulting base pointer will lead to invalid object access and p ##### Enforcement * Flag all combinations of array decay and base to derived conversions. -* Pass an array as an `span` rather than as a pointer, and don't let the array name suffer a derived-to-base conversion before getting into the `span` +* Pass an array as a `span` rather than as a pointer, and don't let the array name suffer a derived-to-base conversion before getting into the `span` # C.over: Overloading and overloaded operators @@ -6420,7 +6420,7 @@ Where a resource is "ill-behaved" in that it isn't represented as a class with a ##### Reason -Arrays are best represented by a container type (e.g., `vector` (owning)) or an `span` (non-owning). +Arrays are best represented by a container type (e.g., `vector` (owning)) or a `span` (non-owning). Such containers and views hold sufficient information to do range checking. ##### Example, bad @@ -6433,7 +6433,7 @@ Such containers and views hold sufficient information to do range checking. } The compiler does not read comments, and without reading other code you do not know whether `p` really points to `n` elements. -Use an `span` instead. +Use a `span` instead. ##### Example @@ -8540,7 +8540,7 @@ You should know enough not to need parentheses for: Complicated pointer manipulation is a major source of errors. -* Do all pointer arithmetic on an `span` (exception ++p in simple loop???) +* Do all pointer arithmetic on a `span` (exception ++p in simple loop???) * Avoid pointers to pointers * ??? @@ -12495,7 +12495,7 @@ Issue a diagnostic for any arithmetic operation on an expression of pointer type ##### Reason -Dynamic accesses into arrays are difficult for both tools and humans to validate as safe. `span` is a bounds-checked, safe type for accessing arrays of data. `at()` is another alternative that ensures single accesses are bounds-checked. If iterators are needed to access an array, use the iterators from an `span` constructed over the array. +Dynamic accesses into arrays are difficult for both tools and humans to validate as safe. `span` is a bounds-checked, safe type for accessing arrays of data. `at()` is another alternative that ensures single accesses are bounds-checked. If iterators are needed to access an array, use the iterators from a `span` constructed over the array. ##### Example, bad @@ -12509,7 +12509,7 @@ Dynamic accesses into arrays are difficult for both tools and humans to validate ##### Example, good - // ALTERNATIVE A: Use an span + // ALTERNATIVE A: Use a span // A1: Change parameter type to use span void f(span a, int pos) @@ -12544,7 +12544,7 @@ Dynamic accesses into arrays are difficult for both tools and humans to validate ##### Example, good - // ALTERNATIVE A: Use an span + // ALTERNATIVE A: Use a span void f1() { int arr[COUNT]; @@ -12720,7 +12720,7 @@ If something is not supposed to be `nullptr`, say so: A `*_view` refers to zero or more mutable `T`s unless `T` is a `const` type. "Pointer arithmetic" is best done within `span`s. -A `char*` that points to something that is not a C-style string (e.g., a pointer into an input buffer) should be represented by an `span`. +A `char*` that points to something that is not a C-style string (e.g., a pointer into an input buffer) should be represented by a `span`. There is no really good way to say "pointer to a single `char`" (`string_span{p, 1}` can do that, and `T*` where `T` is a `char` in a template that has not been specialized for C-style strings). * `zstring` // a `char*` supposed to be a C-style string; that is, a zero-terminated sequence of `char` or `null_ptr` @@ -12738,7 +12738,7 @@ Use `not_null` for C-style strings that cannot be `nullptr`. ??? Do we * `shared_ptr` // shared ownership: `std::shared_ptr` (a counted pointer) * `stack_array` // A stack-allocated array. The number of elements are determined at construction and fixed thereafter. The elements are mutable unless `T` is a `const` type. * `dyn_array` // ??? needed ??? A heap-allocated array. The number of elements are determined at construction and fixed thereafter. - The elements are mutable unless `T` is a `const` type. Basically an `span` that allocates and owns its elements. + The elements are mutable unless `T` is a `const` type. Basically a `span` that allocates and owns its elements. ## GSL.assert: Assertions From af48243d0ad1ec75a021c1b868b901ae57eadfed Mon Sep 17 00:00:00 2001 From: Neil MacIntosh Date: Wed, 4 Nov 2015 14:13:01 -0800 Subject: [PATCH 3/4] Updated FAQ entry about string_span/string_view. --- CppCoreGuidelines.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 6b3bc6b..d05c5e1 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -13260,9 +13260,9 @@ Because we want to use them immediately, and because they are temporary in that No. The GSL exists only to supply a few types and aliases that are not currently in the standard library. If the committee decides on standardized versions (of these or other types that fill the same need) then they can be removed from the GSL. -### FAQ.55: If you’re using the standard types where available, why is the GSL `string_span` different from the `string_span` in the Library Fundamentals 1 Technical Specification? Why not just use the committee-approved `string_span`? +### FAQ.55: If you’re using the standard types where available, why is the GSL `string_span` different from the `string_view` in the Library Fundamentals 1 Technical Specification? Why not just use the committee-approved `string_view`? -Because `string_span` is still undergoing standardization, and is in a state for public review input to improve it. Types that appear in Technical Specifications (TSes) are not yet part of the International Standard (IS), and one reason they are put in TSes first is to gain experience with the feature before they are cast in a final form to become part of the standard. Some of the GSL authors are contributing what we have learned about `string_span` in the process of developing these guidelines, and a discussion of the differences, as a paper for the next ISO meeting for consideration along with all the other similar papers for the committee to consider as it decides on the final form of this feature. +Because `string_view` is still undergoing standardization, and is in a state for public review input to improve it. Types that appear in Technical Specifications (TSes) are not yet part of the International Standard (IS), and one reason they are put in TSes first is to gain experience with the feature before they are cast in a final form to become part of the standard. Some of the GSL authors are contributing what we have learned about `string_span` in the process of developing these guidelines, and a discussion of the differences between `string_view` and `string_span`, as a paper for the next ISO meeting for consideration along with all the other similar papers for the committee to consider as it decides on the final form of this feature. ### FAQ.56: Is `owner` the same as the proposed `observer_ptr`? From 5bb3b3f732fcc5db114138a9fc02a11e2ffc4d8c Mon Sep 17 00:00:00 2001 From: Neil MacIntosh Date: Wed, 4 Nov 2015 14:17:24 -0800 Subject: [PATCH 4/4] Updated description of *_view to reference span. --- CppCoreGuidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index d05c5e1..b2d0cdb 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -12717,7 +12717,7 @@ If something is not supposed to be `nullptr`, say so: * `string_span` // `span` * `cstring_span` // `span` -A `*_view` refers to zero or more mutable `T`s unless `T` is a `const` type. +A `span` refers to zero or more mutable `T`s unless `T` is a `const` type. "Pointer arithmetic" is best done within `span`s. A `char*` that points to something that is not a C-style string (e.g., a pointer into an input buffer) should be represented by a `span`.