Skip to content

Commit

Permalink
Add platform/Span documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
pan- committed Aug 24, 2018
1 parent 295302e commit b2bf6b3
Showing 1 changed file with 104 additions and 0 deletions.
104 changes: 104 additions & 0 deletions docs/reference/api/platform/Span.md
@@ -0,0 +1,104 @@
## Span

A Span is a nonowning view to a sequence of contiguous elements.

It can replace the traditional pair of pointer and size arguments passed as
array definitions in function calls.

### Construction

Span objects can be constructed from a reference to a C++ array, a pointer to the
sequence viewed and its size or the range of the sequence viewed:

```
const uint8_t str[] = "Hello mbed!";
Span<const uint8_t> span_from_array(str);
Span<const uint8_t> span_from_ptr_and_size(str, sizeof(str));
Span<const uint8_t> span_from_range(str, str + sizeof(str));
```

### Operations

Span objects can be copied and assigned like regular value types with the help
of the copy constructor or the copy assignment (=) operator.

```
const uint8_t str[] = "Hello mbed!";
Span<uint8_t> str_span(hello_mbed);
Span<uint8_t> copy_constructed_span(str_span);
Span<uint8_t> copy_assigned_span;
copy_assigned_span = str_span;
```

You can retrieve elements of the object with the subscript ([]) operator. You
can access the pointer to the first element of the sequence viewed with `data()`.
The function `size()` returns the number of elements in the sequence, and
`empty()` informs whether there is any element in the sequence.

```
void process_unit(uint8_t);
void process(const Span<uint8_t> &data)
{
if (data.empty()) {
// nothing to process
return;
}
for (ptrdiff_t i = 0; i < data.size(); ++i) {
process_unit(data[i]);
}
}
```

You can slice Span from the beginning of the sequence (`first()`), from the end
of the sequence (`last()`) or from an arbitrary point in the sequence (`subspan()`).

```
const uint8_t str[] = "Hello mbed!";
Span<uint8_t> str_span(hello_mbed);
ptrdiff_t half_size = str_span.size() / 2;
Span<uint8_t> first_half = str_span.first(half_size);
Span<uint8_t> second_half = str_span.last(half_size);
Span<uint8_t> middle_half = str_span.subspan(/* offset */ half_size / 2, half_size);
```

### Size encoding

The size of the sequence can be encoded in the type itself or in the value of
the instance with the help of the template parameter Extent:
- `Span<uint8_t, 6>`: Span over a sequence of 6 `uint8_t`.
- `Span<uint8_t>`: Span over an arbitrary long sequence of `uint8_t`.

When the size is encoded in the type itself, it is guaranteed that the Span
view is a valid sequence (not `empty()` and not NULL) - unless `Extent` equals 0.
The type system also prevents automatic conversion from Span of different
sizes. Finally, the Span object is internally represented as a single pointer.

```
Span<uint8_t> long_span;
// illegal
Span<uint8_t, 6> span_mac_address;
Span<uint8_t, 6> from_long_span(long_span);
// legal
uint8_t mac_address[6] = { };
Span<uint8_t, 6> span_mac_address(mac_address);
long_span = span_mac_address;
```

When the size of the sequence viewed is encoded in the Span value, Span
instances can view an empty sequence. The function `empty()` helps client code
decide whether Span is viewing valid content or not.

### Span class reference

[![View code](https://www.mbed.com/embed/?type=library)](https://os-doc-builder.test.mbed.com/docs/development/mbed-os-api-doxy/class_span.html)

0 comments on commit b2bf6b3

Please sign in to comment.