Issue/add hugo support for documentation (#1449)

* Add ranges

* Initial Hugo setup

* Work in progress

* Added selection for local or remote site

* Updated to 'light' theme

* Changed to using Hextra Hugo theme

* Changed to using Hextra Hugo theme

* Changed to Hextra Hugo theme

* Change to Hextra Hugo theme

* Updated Hugo setup.

* Updated Hugo setup.

# Conflicts:
#	docs/releases/_index.md

* Work in progress

* Added new fonts

Added new documentation

* Latest documentation updates

* Latest documentation updates

# Conflicts:
#	docs/containers/array.md
#	docs/containers/array_view.md
#	docs/containers/array_wrapper.md
#	docs/containers/bip_buffer_spsc_atomic.md
#	docs/containers/bitset.md
#	docs/containers/indirect_vector.md
#	docs/containers/vector.md
#	docs/getting-started/compilers.md

* Added bloom_filter markdown doc

* Added more documentation

Updated CSS for light and dark modes

* Fixed some menus

Added mode documentation files

* Updated CSS rules

Added badges to home page
Added uniqur_ptr + pool tutorial

* Fixed formatting on the home page markdown

Modified light amd dark code formatting

* Updated unique_ptr-with-pool

* Added container and shared message tutorials

* Updates to documentation

* Added const_multimap

* Updated source-formatting.md

* Added initial raw text files form Web site editor

* Innore coverage build directory

* Exported raw text documentation files from the web site editor

* Hugo updates

* Added Hugo intalation and markdown descriptions

* More addition to the documentation

* Added closure.md and updates to delegate.md

* Added format.md

* Added documentation for etl::delegate_observable, etl::function, Base64 codec

* Added io_port documentation

* Added basic_format_spec

* Added documentation for string_stream and string utilities.

* Added more documentation

Updated the documentation CSS

* Added documentation for clocks, day, duration

* Added more documentation for chrono classes

Updated callouts

* More chrono documentation

* Completed chrono documentation

* Maths functions documentation

* Completed maths documentation

* Completed maths documentation

* Completed maths documentation

* Completed maths documentation

* Added multiple documentation files

* Added iterator.md

* Added debug_count.md and versions.md

* Added debug_count.md and versions.md

* Added more documentation

* More documentation

* Added some design pattern documentation

Modified some of the layout files
Modified the About documentation

* Converted more documentation pages

Modified the site CSS

* Added more documentation

Moced some documentation files to new directories

* Added more documentation

Tweaks to CSS

* Added callback_timer_deferred_locked documentation

* Added callback_timer_locked documentation

* More documentation updates

* More documentation updates

* More documentation updates

* New documentation files.

Harmonised file name format

* New documentation files.

* Multiple document updates

* Multiple document updates

* Final conversion of web pages

* Updates before PR

* Updates before PR

* Updates before PR

# Conflicts:
#	docs/blog/_index.md

* Final pre PR updates

* Updates to message framework documentation

* Renamed directory

* Fix spelling

* Added author and date to blog files

Moved documentation files merged from development

* Fixed 'Description' typo

* Fix typos

# Conflicts:
#	docs/IO/io_port.md
#	docs/containers/sets/const-multiset.md
#	docs/containers/sets/const-set.md
#	docs/maths/correlation.md
#	docs/maths/gamma.md

* Renamed two files to lower case

* Minor renaming

* Added author and date

* Updated callout on bresenham_line.md

Added support for showing the ETL version on the documentation first page, by copying the version.txt file as a hugo asset.
Updated the Python 'update_release.py' to copy 'version.txt'

* Replace space in filename with hyphen.

Added more information to hugo-commands.md

* Replace space in filename with hyphen.

Added more information to hugo-commands.md

# Conflicts:
#	docs/getting-started/view-the-docs-locally/hugo-commands.md

* Added a link to pseudo_moving_average.md

* Updated title pages for groups

* Fixed missing 404 for non-existent pages

* Fixed coordinate variable names in the 'Calculating the intersection' example

---------

Co-authored-by: Roland Reichwein <Roland.Reichwein@bmw.de>
Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com>
Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.co.uk>
This commit is contained in:
John Wellbelove 2026-06-06 13:12:44 +01:00 committed by GitHub
parent 42a21a92e8
commit 4a88884b39
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
354 changed files with 59334 additions and 138 deletions

View File

@ -5,6 +5,8 @@ on:
branches:
- master
workflow_dispatch:
jobs:
build_deploy:
name: build and deploy
@ -28,7 +30,7 @@ jobs:
# Deploys the site via the deploy script in the ci directory
- name: Deploy
run: source $GITHUB_WORKSPACE/ci/deploy.sh
run: source $GITHUB_WORKSPACE/scripts/deploy_documentation.sh
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.DOCS_BDEPLOY_KEY }}
SSH_USERNAME: ${{ secrets.DOCS_SSH_USER }}

2
.gitignore vendored
View File

@ -419,3 +419,5 @@ hugo/resources
hugo/.hugo_build.lock
docs/*.html
test/build-coverage
include/etl/iterator.h~RFfd5eda.TMP
test/vs2022/Build

0
.gitmodules vendored Normal file
View File

144
DOCUMENTATION.md Normal file
View File

@ -0,0 +1,144 @@
# Viewing the documentation locally
The documentation for this project is built using [Hugo](https://gohugo.io/), a static site generator.
This guide will walk you through installing Hugo and running the documentation site on your machine.
---
## Prerequisites
- You must have already cloned this repository, including its submodules (the Hugo themes are stored as submodules).
- If you cloned without submodules, run this first:
```bash
git submodule update --init --recursive
```
---
## Step 1: Install Hugo Extended
This project requires the **extended** version of Hugo, which includes support for additional features such as SCSS/Sass processing.
Make sure you install the extended version, not the standard one.
### Windows
1. The easiest way to install Hugo on Windows is via [Chocolatey](https://chocolatey.org/). If you have it installed, open a command prompt as Administrator and run:
```bash
choco install hugo-extended -y
```
2. If you don't have Chocolatey, you can download Hugo Extended directly from the [Hugo releases page](https://github.com/gohugoio/hugo/releases).
Download the file named `hugo_extended_x.x.x_windows-amd64.zip`, extract it, and add the folder to your system PATH.
3. Verify the installation by opening a new command prompt and running:
```bash
hugo version
```
You should see the word **extended** in the output, for example: `hugo v0.x.x+extended`.
### macOS
1. The easiest way to install Hugo Extended on macOS is via [Homebrew](https://brew.sh/). Homebrew installs the extended version by default. If you have it installed, open a terminal and run:
```bash
brew install hugo
```
2. If you don't have Homebrew, you can install it first by following the instructions at [brew.sh](https://brew.sh/), then run the command above.
3. Verify the installation by running:
```bash
hugo version
```
You should see the word **extended** in the output, for example: `hugo v0.x.x+extended`.
### Linux
1. Package managers often provide an older or non-extended version of Hugo, so the recommended approach is to download the latest extended release directly from the [Hugo releases page](https://github.com/gohugoio/hugo/releases).
Download the file named `hugo_extended_x.x.x_linux-amd64.tar.gz`, then run:
```bash
tar -xzf hugo_extended_x.x.x_linux-amd64.tar.gz
sudo mv hugo /usr/local/bin/
```
2. Verify the installation by running:
```bash
hugo version
```
You should see the word **extended** in the output, for example: `hugo v0.x.x+extended`.
---
## Step 2: Run the documentation site
1. Open a terminal (or command prompt on Windows) and navigate to the `hugo` directory inside the project:
```bash
cd hugo
```
2. Start the Hugo development server:
```bash
hugo server
```
3. Hugo will start a local web server. You will see output similar to:
```
Web Server is available at http://localhost:1313/
```
4. Open your browser and go to **http://localhost:1313/** to view the documentation.
---
## Stopping the server
To stop the Hugo server, go back to your terminal and press **Ctrl+C**.
---
## Editing the Documentation
The documentation source files are located in the `/docs` directory at the root of the repository —
**not** inside the `hugo` directory. Hugo is configured to mount this directory automatically via
`hugo.toml`, so any changes you make to files in `/docs` will be picked up by the Hugo development
server straight away.
Here is a quick overview of where things live:
```
hugo/
├── layouts/ # HTML templates (you probably won't need to touch these)
├── themes/ # The Hugo theme (managed as a git submodule)
└── hugo.toml # Hugo configuration file (includes the /docs content mount)
docs/
└── section-name/ # Each subdirectory becomes a section in the documentation
├── _index.md # The landing page for that section
└── my-page.md # Individual pages within the section
```
### Adding or Editing a Page
All documentation pages are written in **Markdown** (`.md` files). To edit an existing page, open
the relevant `.md` file in the `/docs` directory and make your changes.
The documentation is written in [Goldmark](https://github.com/teekennedy/goldmark-markdown) markdown.
Hugo uses [Goldmark](https://github.com/teekennedy/goldmark-markdown) as its default Markdown processor for versions 0.60.0 and newer.
It is built into Hugo, providing high-performance and fully [CommonMark](https://commonmark.org/)-compliant rendering, along with support for [GitHub](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax) Markdown.
### Starting a New Page
A template file is provided at `docs/page-template.md` to use as a starting point. Copy it to the
appropriate section directory, rename it, and edit the front matter, in particular, change the
`title` and remove the `draft: true` line, otherwise Hugo will not include your page in the
documentation.
### Previewing Your Changes
If you have the Hugo development server running (see [Step 2](#step-2--run-the-documentation-site)),
your changes will appear in the browser automatically as soon as you save the file. There is no need
to restart the server.
### Images and Other Assets
If you need to include images in your documentation, place them in the `hugo/static/` directory and
reference them in your Markdown like so:
```markdown
![Alt text](/my-image.png)
```
The site will automatically refresh in your browser whenever you save changes to the documentation files.

6
docs/IO/_index.md Normal file
View File

@ -0,0 +1,6 @@
---
title: "IO"
weight: 100
---
Classes that address access to hardware.

View File

@ -0,0 +1,152 @@
---
title: "bip_buffer_spsc_atomic"
---
{{< callout >}}
Header: `bip_buffer_spsc_atomic.h`
Since: tbc
{{< /callout >}}
A fixed capacity bipartite buffer.
A bipartite buffer is a memory buffer design that uses two contiguous halves of the same underlying memory block to create a seamless, wraparound-free view of a circular/ring buffer's contents.
**The Problem It Solves**
Ring buffers are efficient for streaming data, but when data wraps around the end of the buffer back to the beginning, reading a contiguous chunk across that boundary normally requires two separate reads or a temporary copy.
**How It Works**
A bipartite buffer allocates a backing array that is twice the needed capacity. The two halves (the "bipartite" part) are mapped to the same physical memory, so:
The first region covers indices 0 to N-1
The second region covers indices N to 2N-1, but maps to the same memory as the first
This means any contiguous slice of up to N bytes can always be read as a single, linear pointer — no wraparound, no copying, no splitting.
```cpp
etl::bip_buffer_spsc_atomic<typename T,
size_t SIZE,
size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
```
Inherits from `etl::ibip_buffer_spsc_atomic<T>`.
`etl::ibip_buffer_spsc_atomic` may be used as a size independent pointer or reference type for any `etl::bip_buffer_spsc_atomic instance`.
## Member types
`value_type`
`size_type`
`reference`
`const_reference`
`rvalue_reference`
## Static Constants
`MAX_SIZE` The maximum size of the circular_buffer.
## Constructor
```cpp
etl::bip_buffer_spsc_atomic<typename T,
size_t SIZE,
size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>();
```
## Capacity
```cpp
bool empty() const
```
**Description**
Returns `true` if the size of the circular buffer is zero, otherwise `false`.
---
```cpp
bool full() const
```
**Description**
Returns `true` if the size of the circular buffer is `SIZE`, otherwise `false`.
---
```cpp
size_t size() const
```
**Description**
Returns the size of the circular buffer.
---
```cpp
size_t max_size() const
```
**Description**
Returns the maximum possible size of the circular buffer.
---
```cpp
size_t capacity() const
```
**Description**
Returns the maximum possible size of the circular buffer.
---
```cpp
size_t available() const
```
**Description**
Returns the remaining available capacity in the circular buffer.
## Modifiers
```cpp
etl::span<T> read_reserve(size_type max_reserve_size = numeric_limits<size_type>::max())
```
**Description**
Reserves a memory area for reading (up to the `max_reserve_size`).
```cpp
void read_commit(const etl::span<T> &reserve)
```
**Description**
Commits the previously reserved read memory area
the reserve can be trimmed at the end before committing.
Throws `bip_buffer_reserve_invalid`.
---
```cpp
etl::span<T> write_reserve(size_type max_reserve_size)
```
**Description**
Reserves a memory area for writing up to the `max_reserve_size`.
---
```cpp
etl::span<T> write_reserve_optimal(size_type min_reserve_size = 1U)
```
**Description**
Reserves an optimal memory area for writing. The buffer will only wrap
around if the available forward space is less than `min_reserve_size`.
---
```cpp
void write_commit(const etl::span<T> &reserve)
```
**Description**
Commits the previously reserved write memory area
the reserve can be trimmed at the end before committing.
Throws `bip_buffer_reserve_invalid`
---
```cpp
void clear()
```
**Description**
Clears the buffer, destructing any elements that haven't been read.

View File

@ -0,0 +1,277 @@
---
title: "buffer_descriptors"
---
{{< callout >}}
Header: `buffer_descriptors.h`
Since: All versions
{{< /callout >}}
A set of descriptors to a collection of buffers.
```cpp
template <typename TBuffer, // The type to store in the buffer.
TSize BUFFER_SIZE, // The size of each buffer.
size_t N_BUFFERS, // The total number of buffers.
typename TFlag = bool> // The 'in use' flag type.
class buffer_descriptors
```
The type used for the 'in use' flag depends on how the buffer descriptors class is used.
For interrupts and multi-threaded code, either the flag type must force a fence (by using an atomic type) or the calls to allocate and release must ensure that they are not re-ordered by the compiler or processor.
## Member types
| Type | |
| ------------- | -------------------------------------------------------------------- |
| value_type | The type that is stored in the buffers |
| size_type | An unsigned integral type |
| flag_type | |
| pointer | |
| descriptor | A nested class that encapsulates the details of an individual buffer |
| notification | A nested class that is sent to the user defined callback function |
| callback_type | `etl::delegate<void(notification)>` |
## Static Constants
| Value | |
| ----------- | --------------------------------------------------------- |
| N_BUFFERS | The number of buffers that the buffer descriptor controls |
| BUFFER_SIZE | The number of elements in each buffer |
## Constructors
```cpp
buffer_descriptors(pointer pbuffers)
```
**Description**
Construct with a pointer to the start of the buffers to control.
This storage should be contiguous and large enough to hold `N_BUFFERS`.
---
```cpp
buffer_descriptors(pointer pbuffers, const callback_type& callback)
```
**Description**
Construct with a pointer to the start of the buffers to control and the callback.
## Member functions
```cpp
void set_callback(const callback_type& callback)
```
**Description**
Set the callback for notification.
---
```cpp
bool is_valid() const
```
**Description**
Returns true if class contains valid buffers.
---
```cpp
void notify(notification n)
```
**Description**
Calls the user defined callback with the descriptor and buffer size.
Used when the buffer has been filled and is ready for processing via the callback.
---
```cpp
descriptor allocate()
```
**Description**
Returns a new descriptor.
If all descriptors are in use then the descriptor will be invalid.
---
```cpp
descriptor allocate(value_type fill)
```
**Description**
Returns a new descriptor and fills the buffer with fill.
If all descriptors are in use then the descriptor will be invalid.
---
```cpp
void clear()
```
**Description**
Clears by releasing all allocated descriptors.
```cpp
descriptor
```
**Description**
A nested class that encapsulates the details of an individual buffer.
---
```cpp
const size_type MAX_SIZE
```
**Description**
The maximum size of the buffer.
---
```cpp
descriptor()
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR pointer data() const
```
**Description**
Returns a pointer to the start of the buffer.
---
```cpp
ETL_CONSTEXPR size_type max_size() const
```
**Description**
Returns the maximum size of the buffer.
---
```cpp
bool is_valid() const
```
**Description**
Returns true if the descriptor points to a valid buffer.
---
```cpp
bool is_allocated() const
```
**Description**
Returns true if the descriptor has been allocated.
---
```cpp
bool is_released() const
```
**Description**
Returns true if the descriptor has been released.
---
```cpp
void release()
```
**Description**
Releases the descriptor.
---
```cpp
notification
```
**Description**
A nested class that is sent to the user defined callback function.
---
```cpp
notification()
```
**Description**
Default contructor.
Initialises to a default constructed descriptor and a count of zero.
---
```cpp
notification(descriptor desc, size_t count)
```
**Description**
Construct with the supplied parameters.
---
```cpp
descriptor get_descriptor() const
```
**Description**
Gets the descriptor.
---
```cpp
size_t get_count() const
```
**Description**
Gets the count.
## Example
*Very simplified.*
Assumes that there is a DMA driver class called DMA.
In the real world the descriptor would be queued in the callback and handled in a foreground thread.
The handler in the thread would release the descriptor.
```cpp
constexpr size_t BUFFER_SIZE = 256U;
constexpr size_t N_BUFFERS = 8U;
// Define the buffer descriptors type.
using BD = etl::buffer_descriptors<char, BUFFER_SIZE, N_BUFFERS, std::atomic_char>;
// The buffers to use with it.
char buffers[N_BUFFERS][BUFFER_SIZE];
// The function to call when a buffer is ready.
void Callback(BD::notification notification)
{
// Process the buffer in the descriptor here.
ProcessData(notification.get_descriptor().data(), notification.get_count());
// Finished with the descriptor now, so release it back.
notification.get_descriptor().release();
}
// Create the buffer_descriptors.
BD bd(&buffers[0][0], BD::callback_type::create<Callback>());
// The current dma descriptor.
BD::descriptor dma_descriptor;
// An object that controls the DMA.
DMA dma;
// Call to start the DMA.
void DMAStart()
{
// Get a new descriptor.
dma_descriptor = bd.allocate();
if (dma_descriptor.is_valid())
{
// Link the buffer to the DMA channel.
dma.Start(dma_descriptor.data());
}
else
{
// No valid descriptors available.
LogError("No Descriptor Available");
}
}
// Called when the DMA has completed (usually an interrupt).
void DMAComplete()
{
// DMA is complete. Notify the callback.
bd.notify(BD::notification(dma_descriptor, dma.GetTransferredSize()));
}
```

246
docs/IO/debounce.md Normal file
View File

@ -0,0 +1,246 @@
---
title: "debounce"
---
{{< callout type="info">}}
Header: `debounce.h`
Since: `TBC`
{{< /callout >}}
A class to debounce signals.
It can detect signal hold, and generate auto repeat.
```cpp
etl::debounce<uint16_t Valid_Count = 0,
uint16_t Hold_Count = 0,
uint16_t Repeat_Count = 0>
```
There are four variants of the class which are selected at compile time according to the supplied template parameters.
All of the template parameters are optional.
If the first parameter is supplied then the debouncer acts as a simple signal debounce.
The signal will become valid after `VALID_COUNT` identical samples have been added.
If the second parameter is supplied then the debouncer will detect the signal being held true for `HOLD_COUNT` samples after becoming valid.
If the third parameter is supplied then the debouncer will indicate that a change has occurred for the signal being held true for each `REPEAT_COUNT` that occurs after entering the hold state.
If no template parameters are supplied then the template variant using internal variables is used.
This has similar parameters supplied to the constructor or the `set` member function.
The diagram below shows the effect of the various parameters.
![Debounce sequence](debounce.png)
## Functions
```cpp
debounce(bool initial_state = false)
```
**Description**
Default constructor.
`etl::debounce<Valid_Count, Hold_Count, Repeat_Count>`
The initial state defaults to:
Initial state = `false`
Valid count = `Valid_Count`
Hold count = `Hold_Count`
Repeat count = `Repeat_Count`
---
`etl::debounce<Valid_Count, Hold_Count>`
The initial state defaults to:
Initial state = `false`
Valid count = `Valid_Count`
Hold count = `Hold_Count`
Repeat count = `0` (Disabled)
---
`etl::debounce<Valid_Count>`
The initial state defaults to:
Initial state = `false`
Valid count = `Valid_Count`
Hold count = `0` (Disabled)
Repeat count = `0` (Disabled)
---
`etl::debounce<>`
The initial state defaults to:
Initial state = `false`
Valid count = `1`
Hold count = `0` (Disabled)
Repeat count = `0` (Disabled)
---
```cpp
debounce(bool initial_state,
uint16_t valid_count = 1,
uint16_t hold_count = 0,
uint16_t repeat_count = 0)
```
**Description**
The constructor available when no template parameters are supplied.
Valid count = `1`
Hold count = `0` (Disabled)
Repeat count = `0` (Disabled)
---
```cpp
bool add(bool sample)
```
**Description**
Adds a new signal sample. Returns true if the state of the debouncer becomes valid, held or repeating.
```cpp
bool has_changed() const
```
**Description**
Returns `true` if the state of the debouncer became valid, held or repeating after the last sample
---
```cpp
bool is_set() const
```
**Description**
Returns `true` if the debouncer is set, `false` if cleared.
---
```cpp
bool is_held() const
```
**Description**
Returns `true` if the debouncer signal is being held.
---
```cpp
bool is_repeating() const
```
**Description**
Returns `true` if the debouncer signal is repeating.
---
```cpp
void set(uint16_t valid_count, uint16_t hold_count = 0, uint16_t repeat_count = 0)
```
**Description**
Sets the debouncer parameters.
Only available when no template parameters are supplied.
## Examples
```cpp
etl::debounce<20> debouncer;
```
**Description**
Simple debounce.
Valid after 20 identical samples.
---
```cpp
etl::debounce<20, 1000> debouncer;
```
**Description**
Key debounce.
Valid after 20 identical samples.
Hold detection after 1000 'set' samples.
---
```cpp
etl::debounce<20, 1000, 100> debouncer;
```
**Description**
Key debounce with hold and auto repeat.
Valid after 20 identical samples.
Hold detection after 1000 'set' samples.
Repeat every 100 samples after hold.
---
```cpp
etl::debounce<> debouncer;
debouncer.set(20, 1000, 100);
```
**Description**
Key debounce with hold and auto repeat.
Runtime parameters.
---
The example below targets the Arduino hardware.
```cpp
//***********************************************************************************
// A debounce demo that reads a key and toggles the LED.
// Set the pin to the correct one for your key.
//***********************************************************************************
#include <debounce.h>
// The sample time in ms.
const int Sample_Time = 1;
// The number of samples that must agree before a key state change is recognised.
// 50 = 50ms for 1ms sample time.
const int Debounce_Count = 50;
// The number of samples that must agree before a key held state is recognised.
// 1000 = 1s for 1ms sample time.
const int Hold_Count = 1000;
// The number of samples that must agree before a key repeat state is recognised.
// 200 = 200ms for 1ms sample time.
const int Repeat_Count = 200;
// The pin that the key is attached to.
const int Key = XX;
void setup()
{
// Initialize LED pin as an output.
pinMode(LED_BUILTIN , OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
// Initialize KEY pin as an input.
pinMode(KEY, INPUT);
}
void loop()
{
static int led_state = LOW;
static etl::debounce<Debounce_Count, Hold_Count, Repeat_Count> key_state;
// Assumes 'HIGH' is 'pressed' and 'LOW' is 'released'.
if (key_state.add(digitalRead(KEY) == HIGH))
{
if (key_state.is_set())
{
// Toggle the LED state on every validated press or repeat.
led_state = (led_state == LOW ? HIGH : LOW);
digitalWrite(LED_BUILTIN, led_state);
}
}
delay(1); // Wait 1ms
}
```

BIN
docs/IO/debounce.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

411
docs/IO/io_port.md Normal file
View File

@ -0,0 +1,411 @@
---
title: "io_port"
---
{{< callout type="info">}}
Header: `io_port.h`
From: `20.39.0`
{{< /callout >}}
A set of templates for building interface classes to memory mapped hardware ports.
They avoid the need to directly map carefully packed (and possibly non-portable) structures onto memory addresses.
>A read from a write-only, or write to a read-only port will result in a compile time error.
**Defines classes for the following IO types**
Read / Write.
Read only.
Write only.
Write only with shadow register.
With a shadow register the value written is stored locally and may be read back.
The port may either have an address fixed at compile time or set at runtime. The compile time versions require no extra overhead compared to a plain memory mapped structure.
Ports may be sent as parameters to algorithms that expect iterators, except the runtime address version of `io_port_wos`, which must use the built-in iterator if the shadow value is to be correctly updated for writes.
All classes define the following typedefs.
| Type name | Maps to |
| ----------------- | ------------------- |
| `value_type` | `T` |
| `pointer` | `volatile T*` |
| `const_pointer` | `volatile const T*` |
| `reference` | `volatile T&` |
| `const_reference` | `volatile const T&` |
## Read/write port
```cpp
io_port_rw<typename T, uintptr_t Address>
```
**Description**
Compile time port address.
---
**Types**
iterator
const_iterator
---
```cpp
operator T() const
```
**Description**
Read the value.
Conversion operator to T.
---
```cpp
iterator iter()
```
**Description**
Get an iterator to this port.
---
```cpp
const_iterator iter() const
const_iterator citer() const
```
**Description**
Get a const_iterator to this port.
---
```cpp
T read() const
```
**Description**
Read the value.
---
```cpp
void write(T value)
```
**Description**
Write the value.
---
```cpp
io_port_rw& operator =(T value)
```
**Description**
Write the value.
---
```cpp
pointer get_address()
const_pointer get_address() const
```
**Description**
Gets the address of the port.
---
```cpp
io_port_rw& operator |=(value_type value)
```
**Description**
Or-Equals operator.
---
```cpp
io_port_rw& operator &=(value_type value)
```
**Description**
And-Equals operator.
---
```cpp
io_port_rw& operator ^=(value_type value)
```
**Description**
Exclusive-Or-Equals operator.
---
```cpp
io_port_rw& operator <<=(int shift)
```
**Description**
Left-Shift-Equals operator.
---
```cpp
io_port_rw& operator >>=(int shift)
```
**Description**
Right-Shift-Equals operator.
---
```cpp
value_type operator ~() const
```
**Description**
Not operator.
## Read only port
```cpp
io_port_ro<typename T, uintptr_t Address>
```
---
**Types**
```cpp
const_iterator
```
---
```cpp
operator T() const
```
**Description**
Read the value. Conversion operator to T.
---
```cpp
const_iterator iter() const
const_iterator citer() const
```
**Description**
Get a const_iterator to this port.
---
```cpp
T read() const
```
**Description**
Read the value.
---
```cpp
const_pointer get_address() const
```
**Description**
Gets the address of the port.
## Write only port
```cpp
io_port_wo<typename T, uintptr_t Address>
```
---
**Types**
iterator
---
```cpp
iterator iter()
```
**Description**
Get an iterator to this port.
---
```cpp
void write(T value)
```
**Description**
Write the value.
---
```cpp
io_port_wo& operator =(T value)
```
**Description**
Write the value.
---
```cpp
pointer get_address()
```
**Description**
Gets the address of the port.
## Write only port, with shadow register
```cpp
io_port_wos<typename T, uintptr_t Address>
```
---
**Types**
```cpp
iterator
const_iterator
```
---
```cpp
operator T() const
```
**Description**
Read the value. Conversion operator to `T`.
---
```cpp
iterator iter()
```
**Description**
Get an iterator to this port.
---
```cpp
const_iterator iter() const
const_iterator citer() const
```
**Description**
Get a `const_iterator` to this port.
---
```cpp
T read() const
```
**Description**
Read the value.
---
```cpp
void write(T value)
```
**Description**
Write the value.
---
```cpp
io_port_rw& operator =(T value)
```
**Description**
Write the value.
---
```cpp
pointer get_address()
const_pointer get_address() const
```
**Description**
Gets the address of the port.
---
```cpp
io_port_rw& operator |=(value_type value)
```
**Description**
Or-Equals operator.
---
```cpp
io_port_rw& operator &=(value_type value)
```
**Description**
And-Equals operator.
---
```cpp
io_port_rw& operator ^=(value_type value)
```
**Description**
Exclusive-Or-Equals operator.
---
```cpp
io_port_rw& operator <<=(int shift)
```
**Description**
Left-Shift-Equals operator.
---
```cpp
io_port_rw& operator >>=(int shift)
```
**Description**
Right-Shift-Equals operator.
---
```cpp
value_type operator ~() const
```
**description**
Not operator.
## Example serial port
The example uses a port at a compile time address.
| Variable | Description |
| --------- | ---------------------------------------------------------- |
| `rxdata` | An 8 bit read only port |
| `txdata` | An 8 bit write only port |
| `control` | A 16 bit write only port, with shadow register |
| `status` | A 16 bit read only port. It shares an address with control |
| `option` | An 8 bit read/write port |
```cpp
template <uintptr_t Address>
struct serial_port
{
etl::io_port_ro<char, Address> rxdata; // Read only rx data register.
etl::io_port_wo<char, Address + 1> txdata; // Write only tx register.
etl::io_port_wos<uint16_t, Address + 2> control; // Write only, with shadow, control register.
etl::io_port_ro<uint16_t, Address + 2> status; // Read only status register.
etl::io_port_ro<char, Address> option; // Read/Write register.
};
serial_port<0x800> port; // A serial port at address 0x800
// Read Rx data
char data = port.rxdata;
// Write Tx data
port.txdata = 'A';
// Compile error! txdata is write only.
data = port.txdata;
// Write to the control register and read back what we wrote.
port.control = 0x1234;
uint16_t control = port.control;
// Flip bit 3 of the control register.
port.control ^= 0x0080;
// Read from the status register.
uint16_t status = port.status;
// Copy data from a buffer to the Tx data port.
std::copy(txBuffer.begin(), txBuffer.end(), serial_port.txdata.iter());
// Copy data from the Rx data port to a buffer.
std::copy_n(serial_port.rxdata, serial_port.status, std::back_inserter(rxBuffer));
```

75
docs/Is the ETL free.md Normal file
View File

@ -0,0 +1,75 @@
---
title: "Is the ETL free?"
# Force it to the top of the list
weight: 1
# Disable the Table of Contents entirely for this page
toc: false
---
The ETL is free for you or your company to use, including in commercial applications.
*However, it is not free for me to create or maintain.*
## Why Open Source Needs Support
Development, support, documentation, testing, and hosting all require time and resources.
*Currently, this work is carried entirely by me, usually without compensation.*
As the ETL has grown in functionality and popularity, so has the workload. In some weeks, maintaining the project takes over 30 hours. Without financial support, this is difficult to sustain alongside paid work and personal obligations.
## Why Sponsor the Embedded Template Library (ETL)?
The Embedded Template Library (ETL) is a modern, high-performance C++ library designed specifically for embedded systems. It provides STL-like functionality for environments where efficiency, reliability, and low overhead are essential.
The ETL is used by hobbyists, engineers, and international companies developing commercial embedded products. Yet it is maintained by a single developer in their spare time.
If the ETL has helped your project or become part of your development toolset, please consider supporting its continued growth.
## Why Sponsorship Matters
- **Sustainability**
Ongoing support helps keep the library maintained and up to date.
- **Reliability**
Sponsorship allows for regular testing, bug fixes, and improvements.
- **Responsibility**
Supporting the tools you depend on strengthens the software ecosystem.
- **Recognition**
Sponsors can be publicly acknowledged if desired.
Whether you use the ETL in personal projects or commercial products, your support helps keep it available and improving.
The ETL began as a way to share years of embedded development experience. Since 2014, it has grown into a feature-rich and widely used library.
*But it is still powered by one developer, without corporate funding.*
If you or your company benefit from the ETL, please consider becoming a sponsor. Even small contributions help cover hosting, tools, and time spent supporting the library and its users.
[Why CFOs should care about Open Source software](https://opensourcepledge.com/blog/CFOs-care-about-OSS/)
## How to sponsor
There are two ways that you can help me with the maintenance and further development of the library.
**Through the GitHub donations link.**
[Github sponsors](https://github.com/sponsors/ETLCPP)
---
**By direct bank transfer**
Donations are accepted in many world currencies.
AED, AUD, BGN, CAD, CHF, CLP, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, ILS, INR, ISK, JPY, KRW,
KZT, MAD, MXN, NOK, NZD, PHP, PLN, QAR, RON, RSD, SAR, SEK, SGD, THB, TRY, USD, ZAR
I can supply invoices for companies that require one for accounting and tax purposes.
**UK**
Beneficiary John Wellbelove
Account 12655643
Sort code 04-00-75
**Swift (International)**
Beneficiary John Wellbelove
IBAN GB17 REVO 0099 7000 7513 26
BIC REVOGB21
Many thanks for any support you can give to keep this project actively supported,
*John Wellbelove*

23
docs/Messaging/_index.md Normal file
View File

@ -0,0 +1,23 @@
---
title: "Messaging"
weight: 100
---
## Headers
- `message.h`
Defines the core message model. etl::imessage is the base interface (virtual or non-virtual, depending on `ETL_HAS_VIRTUAL_MESSAGES`). `etl::message<ID>` provides typed messages with static IDs. Type traits (`is_message`, `is_message_type`, etc.) and ID comparison utilities support compile-time validation.
- `message_router.h`
Defines `etl::imessage_router`, the central routing interface with receive, accepts, and router identity. Provides message_router<TDerived, ...> that statically dispatches by message ID (contiguous IDs optimized). Includes null_message_router and message_producer helpers, plus send_message utilities.
- `message_bus.h`
Implements `etl::imessage_bus`, a router that manages a sorted list of subscribed routers and forwards messages based on destination ID (broadcast or addressed). Supports subscription limits and forwards to successors.
- `message_broker.h`
Implements etl::message_broker, a router with explicit subscription objects mapping routers to message ID lists (span). It routes only to subscribers that match both message ID and destination ID, then forwards to any successor.
- `message_packet.h`
A type-erased, in-place container for a fixed set of message types. Validates message ID acceptance, supports copy/move, and exposes `get()` as `etl::imessage&`. Uses aligned storage sized to the largest message type.
- `shared_message.h`
Reference-counted wrapper around pooled messages (`ireference_counted_message_pool`). Supports copy/move semantics with automatic release when the last reference drops.
## Basic architecture
![message-framework](images/message-framework.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -0,0 +1,217 @@
---
title: "message_broker"
weight: 6
---
{{< callout type="info">}}
Header: `message_broker.h`
{{< /callout >}}
Message Broker
A variant of the observer pattern in that message routers and derived types are be able to subscribe to selected sets of messages. The message_broker is similar to the message_bus, but it provides more control over the routing of messages. While the message_bus simply broadcasts every message to all subscribers, the message_broker allows you to specify which subscribers should receive each message.
Derived from `imessage_router`.
## Types
```cpp
message_id_span_t etl::span<const etl::message_id_t>
```
## subscription
A nested class of `etl::message_broker`.
The base for broker subscription information.
Derive from this to define your subscription class.
See Example.
---
```cpp
subscription(etl::imessage_router& router)
```
Constructor.
---
```cpp
virtual message_id_span_t message_id_list() const = 0;
```
Override this to return a span of message ids.
## message_broker
```cpp
message_broker()
```
The broker is constructed with an id of `etl::imessage_router::MESSAGE_BROKER`.
---
```cpp
message_broker(etl::imessage_router& successor)
```
The broker is constructed with an id of `etl::imessage_router::MESSAGE_BROKER`.
Sets the successor.
---
```cpp
message_broker(etl::message_router_id_t id)
```
The broker is constructed with the specified id.
---
```cpp
message_broker(etl::message_router_id_t id, etl::imessage_router& successor)
```
The broker is constructed with the specified id.
Sets the successor.
---
```cpp
void subscribe(etl::imessage_router& router)
```
Subscribes an `etl::imessage_router` derived class to the broker.
A subscription object must have a lifetime of at least the same as the broker.
A subscription cannot be shared with another broker.
---
```cpp
void unsubscribe(etl::imessage_router& router)
```
Unsubscribes the specified `etl::imessage_router` derived class from the bus.
Does not unsubscribe from nested buses.
---
```cpp
void receive(const etl::imessage& message)
void receive(etl::shared_message message)
```
Receives a message and distributes it to all subscribers that have registered to receive the message type.
Forwards the message to any successor.
Override this in a derived class if you wish to capture messages sent to the broker.
Call the base receive function from here to allow normal operation to continue.
---
```cpp
bool accepts(etl::message_id_t id) const
```
Always returns `true`.
---
```cpp
void clear()
```
Clears the broker of all subscribers.
---
```cpp
ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE
```
Always returns `false`.
---
```cpp
bool is_producer() const ETL_OVERRIDE
```
Always returns `true`.
---
```cpp
bool is_consumer() const ETL_OVERRIDE
```
Always returns `true`.
---
```cpp
bool empty() const
```
Returns `true` is the are are no subscribers.
## Example
```cpp
// Some router ids.
enum
{
ROUTER_ID_1,
ROUTER_ID_2,
};
// Custom subscription type.
class Subscription : public etl::message_broker::subscription
{
public:
Subscription(etl::imessage_router& router, std::initializer_list<etl::message_id_t> id_list_)
: etl::message_broker::subscription(router)
, id_list(id_list_)
{
}
etl::message_broker::message_id_span_t message_id_list() const override
{
return etl::message_broker::message_id_span_t(id_list.begin(), id_list.end());
}
std::vector<etl::message_id_t> id_list;
};
// Instances of messages.
Message1 message1;
Message2 message2;
Message3 message3;
Message4 message4;
// Custom broker.
class Broker : public etl::message_broker
{
public:
using etl::message_broker::receive;
// Hook incoming messages and translate Message4 to Message3.
void receive(const etl::imessage& msg) override
{
if (msg.get_message_id() == Message4::ID)
{
etl::message_broker::receive(Message3());
}
else
{
etl::message_broker::receive(msg);
}
}
};
// Instances of message routers.
Router1 router1;
Router2 router2;
// The subscriptions.
Subscription subscription1{ router1, { Message1::ID, Message2::ID } };
Subscription subscription2{ router2, { Message2::ID, Message3::ID } };
// Instance of message broker.
etl::message_broker broker;
// Subscribe router1 and router1 to the broker.
broker.subscribe(subscription1);
broker.subscribe(subscription2);
broker.receive(message1); // Received by router1
broker.receive(message2); // Received by router1 and router2
broker.receive(message3); // Received by router2
broker.receive(message4); // Received by router2 as a Message3
```

View File

@ -0,0 +1,207 @@
---
title: "message_bus"
weight: 5
---
{{< callout type="info">}}
Header: `message_broker.h`
From: `20.33.0`
{{< /callout >}}
Message Bus
This page documents version `20.0.0` and above.
A variant of the observer pattern in that message routers and derived types are be able to subscribe to messages on a bus. The messages can be either broadcast, to be automatically picked up by any router that has a handler, or addressed to a particular router or router id. Message buses may be nested by setting a successor.
## imessage_bus
Derived from imessage_router.
The base for all message buses.
Inherits publicly from `etl::imessage_router`.
Message buses are therefore also a type of router.
Objects of type `etl::imessage_bus` cannot be directly constructed.
## Member functions
```cpp
bool subscribe(etl::imessage_router& router)
```
Subscribes an `etl::imessage_router` derived class to the bus.
Returns `true` on success.
---
```cpp
void unsubscribe(etl::imessage_router& router)
```
Unsubscribes the specified `etl::imessage_router` derived class from the bus.
Does not unsubscribe from nested buses.
---
```cpp
void unsubscribe(etl::message_router_id_t id)
```
Unsubscribes routers with the specified id from the bus.
Does not unsubscribe from nested buses.
`etl::imessage::MESSAGE_BUS` will unsubscribe all message buses.
`etl::imessage::ALL_MESSAGE_ROUTERS` will unsubscribe all routers and buses. Equivalent to calling `clear()`.
---
```cpp
void receive(const etl::imessage& message)
void receive(etl::shared_message message)
```
Receives a message and distributes it to all subscribers.
Forwards the message to any successor.
The routers are called first, in order of ascending router id.
Routers with the duplicate ids will be called in subscribe order.
Any nested message buses are called in subscribe order.
---
```cpp
void receive(etl::message_router_id_t destination_router_id,
const etl::imessage& message);
void receive(etl::message_router_id_t destination_router_id,
etl::shared_message message)
```
Receives a message and distributes it to all subscribers that have the specified router id.
Forwards the message to any successor.
Routers with the duplicate ids will be called in subscribe order.
Any nested message buses are called in subscribe order.
Override this in a derived class if you wish to capture messages sent to the bus.
Call the base receive function from here to allow normal operation to continue.
---
```cpp
bool accepts(etl::message_id_t id) const
```
Always returns `true`.
---
```cpp
size_t size() const
```
Returns the number of subscribers.
---
```cpp
void clear()
```
Clears the bus of all subscribers.
Message buses inherit all of the public functions of `etl::imessage_router`.
## Errors
```cpp
message_bus_exception
```
Base error class for `etl::message_bus`. Inherits from `etl::exception`.
---
```cpp
message_bus_too_many_subscribers
```
Emitted when the number of subscribers exceeds the capacity. Inherits from `etl::message_bus_exception`.
## message_bus
Derived from `imessage_bus`.
```cpp
template <const uint_least8_t MAX_ROUTERS>
class message_bus
```
`MAX_ROUTERS` The maximum number of routers that can be subscribed.
## Member functions
```cpp
message_bus()
```
Constructs a message bus.
Message buses always have a router id of `etl::imessage::MESSAGE_BUS`.
```cpp
message_bus(etl::imessage_router& successor)
```
Constructs a message bus and sets the successor.
Message buses always have a router id of `etl::imessage::MESSAGE_BUS`.
## Example
```cpp
// Some router ids.
enum
{
ROUTER_ID_1,
ROUTER_ID_2,
ROUTER_ID_3
};
// Instances of messages.
MessageA messageA;
// Instances of message routers.
RouterA routerA(ROUTER_ID_1);
RouterB routerB(ROUTER_ID_1);
RouterC routerC(ROUTER_ID_2);
RouterD routerD(ROUTER_ID_3);
RouterE routerE(ROUTER_ID_1);
// Instances of message buses.
etl::message_bus<4> bus1;
etl::message_bus<2> bus2;
etl::message_bus<1> bus3;
// Subscribe bus2 & bus3 to bus1.
bus1.subscribe(bus3);
bus1.subscribe(bus2);
// Subscribe routerB & routerA to bus1.
bus1.subscribe(routerB);
bus1.subscribe(routerA);
// Subscribe routerD & routerC to bus2.
bus2.subscribe(routerD);
bus2.subscribe(routerC);
// Subscribe routerE to bus3.
bus3.subscibe(routerE);
// Assume all routers accept the same messages.
// Broadcast messageA to everyone.
bus1.receive(messageA);
// The call order will be...
// routerB
// routerA
// routerE
// routerC
// routerD
// Address messageA to routers with id ROUTER_ID_1.
bus1.receive(ROUTER_ID_1, messageA);
// The call order will be...
// routerB
// routerA
// routerE
// Address messageA to routers with id ROUTER_ID_3.
bus1.receive(ROUTER_ID_3, messageA);
// The call order will be...
// routerD
```

View File

@ -0,0 +1,155 @@
---
title: "message_packet"
---
{{< callout type="info">}}
Header: `message_packet.h`
{{< /callout >}}
A container for more than one type of message.
The messages must have been derived from `etl::imessage`.
The messages types that the packet may contain are listed as template parameters.
e.g. `etl::message_packet<Message1, Message2, Message3>`
From `20.40.0` message types are not required to have a virtual destructor.
---
```cpp
message_packet()
```
Default constructs a message packet.
`is_valid()` returns `false`.
---
```cpp
explicit message_packet(const etl::imessage&)
```
Constructs a message packet from an `etl::imessage` reference.
Asserts an `etl::unhandled_message_exception` error if the parameter is not one listed in the template parameter list.
---
```cpp
explicit message_packet(etl::imessage&&) C++11
```
Move constructs a message packet from an `etl::imessage` rvalue reference.
Emits an `etl::unhandled_message_exception` error if the parameter is not one listed in the template parameter list.
---
```cpp
template <typename TMessage>
explicit message_packet(const TMessage&)
```
Constructs a message packet from a `TMessage` reference.
Emits a compile time static assert if the parameter is not one listed in the template parameter list.
From: `20.22.0`
---
```cpp
template <typename TMessage>
explicit message_packet(TMessage&&)
```
Move constructs a message packet from a `TMessage` rvalue reference.
Emits a compile time static assert if the parameter is not one listed in the template parameter list.
From: `20.22.0`
---
```cpp
message_packet(const message_packet&)
```
Constructs a message packet from an `message_packet` reference.
Emits an `etl::unhandled_message_exception` error if the parameter is not one listed in the template parameter list.
---
```cpp
message_packet(message_packet&&)
```
Move constructs a message packet from an `message_packet` rvalue reference.
Emits an `etl::unhandled_message_exception` if the parameter is not one listed in the template parameter list.
---
```cpp
message_packet& operator =(const message_packet&)
```
Assigns a message packet from an `message_packet` reference.
Emits an `etl::unhandled_message_exception` error if the parameter is not one listed in the template parameter list.
---
```cpp
message_packet& operator =(message_packet&&)
```
Move assigns a message packet from an `message_packet` rvalue reference.
Emits an `etl::unhandled_message_exception` error if the parameter is not one listed in the template parameter list.
---
```cpp
etl::imessage& get()
const etl::imessage& get() const
```
Returns a reference to an `etl::imessage`.
---
```cpp
bool is_valid() const
```
Returns `true` if the packet contains a valid message, otherwise `false`.
---
## Constants
`SIZE` The size of the largest message.
`ALIGNMENT` The largest message alignment.
---
## Example
```cpp
enum
{
MESSAGE1,
MESSAGE2,
MESSAGE3
};
struct Message1 : public etl::message<MESSAGE1>
{
};
struct Message2 : public etl::message<MESSAGE2>
{
};
struct Message3 : public etl::message<MESSAGE3>
{
};
using Packet = etl::message_packet<Message1, Message2>
Message1 message1;
Message2 message2;
Message3 message3;
Packet packet1(message1);
Packet packet2(message2);
Packet packet3(message3); // Runtime time error! Packet does not support Message3 type.
etl::imessage& m1 = message1;
Packet packet4(m1); // Construct from an etl::imessage reference.
etl::imessage& m3 = message3;
Packet packet4(m3); // Asserts etl::unhandled_message_exception! Packet does not support Message3 type.
etl::imessage& m = packet2.get(); // Get a reference to an etl::imessage from the packet.
```

View File

@ -0,0 +1,180 @@
---
title: "message_router_registry"
weight: 4
---
{{< callout type="info">}}
Header: `message_router_registry`
From: `20.6.0`
{{< /callout >}}
A class that will act as a registry for all message router types.
When iterating through the registry, routers with identical IDs are ordered by insertion.
**Defines the following classes**
```cpp
etl::imessage_router_registry
etl::message_router_registry
```
## imessage_router_registry
The base class for all router registries.
### Iterators
```cpp
iterator
const_iterator
```
### Member functions
```cpp
iterator begin()
const_iterator begin() const
const_iterator cbegin() const
```
Get the beginning of the registry.
---
```cpp
iterator end()
const_iterator end() const
const_iterator cend() const
```
Get the end of the registry.
---
```cpp
iterator lower_bound(etl::message_router_id_t id)
const_iterator lower_bound(etl::message_router_id_t id) const
```
Get the lower bound in the registry of the router with the specified ID.
---
```cpp
iterator upper_bound(etl::message_router_id_t id)
const_iterator upper_bound(etl::message_router_id_t id) const
```
Get the upper bound in the registry of the router with the specified ID.
---
```cpp
etl::imessage_router* find(etl::message_router_id_t id)
const etl::imessage_router* find(etl::message_router_id_t id) const
```
Returns a pointer to the first router with the specified ID, or `ETL_NULLPTR` if it cannot be found.
---
```cpp
void add(etl::imessage_router& router)
void add(etl::imessage_router* p_router)
```
Registers a router.
If the registry is full then an ETL assert is emitted (`etl::message_router_registry_full`).
Duplicate routers will be ignored.
---
```cpp
template <typename TIterator>
void add(TIterator first, const TIterator& last)
```
Registers a collection of routers.
If the registry becomes full then an ETL assert is emitted (`etl::message_router_registry_full`).
Duplicate routers will be ignored.
---
```cpp
void remove(etl::message_router_id_t id)
```
Unregisters a router.
---
```cpp
bool contains(const etl::message_router_id_t id) const
bool contains(const etl::imessage_router* const p_router) const
bool contains(const etl::imessage_router& router) const
```
Returns `true` if the registry contains a router that has the specified ID or object.
---
```cpp
bool empty() const
```
Returns `true` if the registry is empty, otherwise `false`.
---
```cpp
bool full() const
```
Returns `true` if the registry is full, otherwise `false`.
---
```cpp
size_t size() const
```
Returns the size of the registry.
---
```cpp
size_t available() const
```
Returns the available size of the registry.
---
```cpp
size_t max_size() const
```
Returns the maximum size of the registry.
---
## message_router_registry
```cpp
message_router_registry()
```
Default constructor.
---
```cpp
template <typename TIterator>
message_router_registry(TIterator first, const TIterator& last)
```
Constructs from an iterator range.
---
```cpp
message_router_registry(std::initializer_list<etl::imessage_router*> init)
```
Initializer_list constructor.
Enabled for C++11 or above.
---
```cpp
message_router_registry(const message_router_registry& rhs)
```
Copy constructor.
---
```cpp
message_router_registry& operator =(const message_router_registry& rhs)
```
Assignment operator.

View File

@ -0,0 +1,505 @@
---
title: message_router
weight: 3
---
A class that will automatically route incoming messages to specific handlers based on the message types declared in the template parameter list. Messages are passed to the receive member function which will static cast it to its real type and call the matching on_receive function in the derived class. A compilation error will occur if the matching on_receive does not exist.
The `on_receive` functions are not virtual. The template base class uses `CRTP` to directly call the derived class's functions.
**Defines the following classes**
```cpp
etl::imessage_router
etl::message_router
etl::null_message_router
```
Note: This C++03 portion of this header is a generated from `message_router_generator.h`. To handle more than the standard 16 message types then a new one must be generated.
See [Generators](./generators-tutorial)
## Message router ID
Allowable router IDs run from `0` to `MAX_MESSAGE_ROUTER` (`249`) inclusive.
Each message router is given an ID. Whether this ID is unique or not depends on how you are using and identifying message routers.
Note: A message router 'group' is deemed to be a set of routers with identical IDs.
The default router id is `etl::imessage_router::MESSAGE_ROUTER`.
### Scenario 1
You never send a message to a router using it's ID.
You never use the ID to uniquely identify a router.
You do not require the router ID to act as a priority level when subscribing to a message bus.
You do not require that messages can be sent to a group.
All message router IDs can be identical.
### Scenario 2
You never use the ID to uniquely identify a router.
You may use the router ID to send to a particular router group.
You require the router ID to act as a priority level when subscribing to a message bus.
Router IDs will be assigned in groups. i.e. Some routers may share IDs.
### Scenario 3
You use the ID to uniquely identify a router.
You use the router ID to send to a particular router.
You require the router ID to act as a priority level when subscribing to a message bus.
You require all priority levels to be unique.
All router IDs are unique
## imessage_router
The base class for all routers.
#### Member functions
```cpp
virtual ~imessage_router() {}
```
---
```cpp
virtual void receive(const etl::imessage& message) = 0;
```
Overridden by the derived class.
---
```cpp
virtual void receive(etl::message_router_id_t destination_router_id,
const etl::imessage& message)
```
Receive a message for a specific destination id.
If the destination id is the router's id, then the message is forwarded to `receive(message)`.
Can be overridden by the derived class.
---
```cpp
virtual void receive(etl::shared_message shared_msg)
```
Receive a shared message.
By default, forwards to `receive(shared_msg.get_message())`.
---
```cpp
virtual void receive(etl::message_router_id_t destination_router_id,
etl::shared_message shared_msg)
```
Receive a message for a specific destination id.
By default, forwards to `receive(destination_router_id, shared_msg.get_message())`.
---
```cpp
virtual bool accepts(etl::message_id_t id) const = 0;
```
Returns `true` if the router accepts the message id.
Overridden by the derived class.
---
```cpp
bool accepts(const etl::imessage& msg) const;
```
Returns `true` if the router accepts the message.
---
```cpp
etl::message_router_id_t get_message_router_id() const;
```
Returns the router id.
---
```cpp
virtual bool is_null_router() const = 0;
```
Returns `true` if the router is a null message router, otherwise `false`.
**Deprecated. **
---
```cpp
virtual bool is_producer() const = 0;
```
Returns `true` if the router is a producer of messages, otherwise `false`.
---
```cpp
virtual bool is_consumer() const = 0;
```
Returns `true` if the router is a consumer of messages, otherwise `false`.
---
```cpp
void set_successor(etl::imessage_router& successor);
```
Sets the successor router. Any unhandled message will be sent here.
Allows the router to implement the Chain Of Responsibility design pattern.
## Enumerations
```cpp
NULL_MESSAGE_ROUTER
MESSAGE_BUS
ALL_MESSAGE_ROUTERS
MAX_MESSAGE_ROUTER
```
---
## message_router
User defined message routers are derived from this class.
Derived from `## imessage_router`.
---
### For C++03
```cpp
template <typename TDerived,
typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void>
class message_router
```
**Template parameters**
`TDerived` The derived class.
`T1` The first message type.
`T2...` The additional message types.
The maximum number of types can be set by running the generator for this file.
The default is 16.This may be changed by running a modified version of generate_message_router.bat.
See [Generators](../tutorials/generators-tutorial)
---
### For C++11 and above
```cpp
template <typename TDerived, typename... TMessageTypes>
class message_router
```
**Template parameters**
`TDerived` The derived class.
`TMessageTypes` The list of message types.
**Before: 20.47.0**
This definition will automatically be selected if the compiler supports C++17 or above. It uses fold expressions to resolve `on_receive()` calls.
To use the older C++03 compatible definition, define `ETL_MESSAGE_ROUTER_FORCE_CPP03` as a project setting or in the optional `etl_profile.h`.
**Since: 20.47.0**
This definition will automatically be selected if the compiler supports C++11 or above. It uses either an O(1) or O(N) mechanism to resolve `on_receive()` calls.
To use the older C++03 compatible definition, define `ETL_MESSAGE_ROUTER_FORCE_CPP03` as a project setting or in the optional `etl_profile.h`.
---
The derived class must define the following member functions.
```cpp
void on_receive(const Type& msg);
```
Replace Type with each concrete message type.
Define for all of the template parameter types.
---
```cpp
void on_receive_unknown(const etl::imessage& msg)
```
Called when a message type is received that is not in the template list.
## message_packet
This is a nested member class.
See [etl::message_packet](./message-packet)
---
### Member functions
```cpp
message_router()
```
Constructs the router.
The router id is set to `etl::imassage_router::MESSAGE_ROUTER`.
---
```cpp
message_router(etl::imessage_router& successor)
```
Constructs the router.
The router id must be between `0` and `MAX_MESSAGE_ROUTER` (`249`). Other IDs are reserved for ETL use.
Emits an error if the id is outside the legal range.
Routers may have duplicate ids.
Sets the successor router to this one. Any unhandled message will be sent here.
---
```cpp
message_router(etl::message_router_id_t id)
```
Constructs the router.
The router id must be between `0` and `249`. Ids `250` to `255` are reserved for ETL use.
Asserts an error if the id is outside the legal range.
Routers may have duplicate ids.
---
```cpp
message_router(etl::message_router_id_t id, etl::imessage_router& successor)
```
Constructs the router.
The router id must be between 0 and MAX_MESSAGE_ROUTER (249) . Other IDs are reserved for ETL use.
Sets the successor router to this one. Any unhandled message will be sent here.
---
```cpp
void receive(const etl::imessage& msg)
```
Receives a message and routes to the `on_receive()` handler.
If not handled, passes the message on to a successor, if it exists.
---
```cpp
template <typename TMessage>
void receive(const TMessage& msg)
```
Receives a message and routes directly to the `on_receive()` handler.
This template function will be chosen for concrete message types.
If not handled, passes the message on to a successor, if it exists.
---
```cpp
bool accepts(etl::message_id_t id) const
```
Returns `true` if the router accepts the message id.
---
### Errors
```cpp
message_router_exception
```
Base exception for router errors.
Derived from `etl::exception`.
---
```cpp
message_router_illegal_id
```
The router id is out of the legal range.
Derived from `etl::message_router_exception`.
---
### null_message_router
This router can be used as a sink for messages or a 'null source' router.
Derived from `etl::imessage_router`.
---
```cpp
null_message_router()
```
Constructs a null message router.
The router id will be `etl::imessage_router::NULL_MESSAGE_ROUTER`.
---
```cpp
void receive(const etl::imessage& message)
```
Receives a message.
Does nothing, except pass on to a successor, if it exists.
---
```cpp
bool accepts(etl::message_id_t id) const
```
Returns `false` if no successor is set.
Returns `true` if a successor accepts the message id.
---
```cpp
static null_message_router& instance()
```
Returns an instance of `etl::null_message_router`.
## message_producer
This router can be used as a producer-only of messages, such an interrupt routine.
Derived from `etl::imessage_router`.
---
```cpp
message_producer(etl::message_router_id_t id);
```
Constructs the router.
The router id must be between `0` and `249`. Ids `250` to `255` are reserved for ETL use.
Emits an error if the id is outside the legal range.
Routers may have duplicate ids.
---
```cpp
void receive(const etl::imessage& message)
```
Receives a message.
Does nothing, except pass on to a successor, if it exists.
---
```cpp
bool accepts(etl::message_id_t id) const
```
Returns `false` if no successor is set.
Returns `true` if a successor accepts the message id.
---
```cpp
static null_message_router& instance()
```
Returns an instance of `etl::null_message_router`.
---
## Global functions
```cpp
void send_message(etl::imessage_router& router,
const etl::imessage& message)
```
Send the message to the router.
---
```cpp
void send_message(etl::imessage_router& router,
etl::message_router_id_t id,
const etl::imessage& message)
```
Send the message to the router if it has the specified id.
---
```cpp
void send_message(etl::imessage_router& router,
etl::shared_message& message)
```
Send the shared message to the router.
---
```cpp
void send_message(etl::imessage_router& router,
etl::message_router_id_t id,
etl::shared_message& message)
```
Send the shared message to the router if it has the specified id.
## Example
```cpp
// Message ids.
enum
{
START,
STOP,
SET_SPEED
};
// The start message.
struct Start : public etl::message<START>
{
};
// The stop message.
struct Stop : public etl::message<STOP>
{
};
// The set speed message.
struct SetSpeed : public etl::message<SET_SPEED>
{
SetSpeed(uint32_t speed_)
: speed(speed_)
{
}
uint32_t speed;
};
// The router.
class Router : public etl::message_router<Router, Start, Stop, SetSpeed>
{
public:
// Construct the router with an id of 0.
Router()
: message_router(0)
{
}
// Received a start message.
void on_receive(etl::imessage_router& sender, const Start& msg)
{
std::cout << "Start message received\n";
}
// Received a stop message.
void on_receive(const Stop& msg)
{
std::cout << "Start message received\n";
}
// Received a set speed message.
void on_receive(const SetSpeed& msg)
{
std::cout << "SetSpeed(" << msg.speed << ") message received\n";
}
// Received an unknown message.
void on_receive_unknown(const etl::imessage& msg)
{
std::cout << "Unknown message " << msg.message_id << " received\n";
}
}
// Router and message instances.
Router router;
Start start;
Stop stop;
SetSpeed halfSpeed(50);
SetSpeed maxSpeed(100);
// A queue for Router messages.
etl::queue<Router::message_packet, 10> queue;
// Add to the queue.
queue.emplace(start);
queue.emplace(stop);
queue.emplace(maxSpeed);
queue.emplace(halfSpeed);
// Send the queued messages to 'router'.
while (!queue.empty())
{
etl::send_message(router, queue.front().get());
queue.pop();
}
```
---
An example of a queued message router can be found in the repository in `examples/QueuedMessageRouter`.

112
docs/Messaging/message.md Normal file
View File

@ -0,0 +1,112 @@
---
title: "message"
weight: 1
---
{{< callout type="info">}}
Header: `message.h`
{{< /callout >}}
Message types used for many of the framework classes.
---
```cpp
etl::message_id_t
```
The type used for message ids.
By default can hold a value between 0 and 255.
If `ETL_MESSAGE_ID_TYPE` is defined then this type will be used instead.
---
```cpp
etl::message_router_id_t
```
The type used for message router ids.
Can hold a value between 0 and 255.
---
The message classes are the common communication method across all of the message capable frameworks.
They are identified by a unique id number that specialises the base class.
## imessage
The base class for messages.
It is this class that is passed around, usually by const reference.
The class is abstract.
---
```cpp
etl::message_id_t get_message_id() const ETL_NOEXCEPT = 0;
```
Returns the id of the message.
---
## message
```cpp
message<size_t ID, typename TParent = etl::imessage>
```
Requires an integral id as the template parameter.
Inherits from `TParent`, which defaults to `etl::imessage`.
`TParent` allows additional base interfaces or functionality to be included.
static asserts if `TParent` is not a base of `etl::imessage`.
---
```cpp
ID
```
The id of the message as an enum.
Can be accessed by `etl::message` instances.
---
```cpp
TParent
```
The class that it inherits from. It must ultimately derive from `etl::imessage`.
The default is `etl::imessage`.
---
## Example
```cpp
enum
{
START,
STOP,
SET_SPEED
};
struct MyInterface : public etl::imessage
{
virtual void DoStuff() = 0;
};
// Start implements MyIterface
struct Start : public etl::message<START, MyInterface>
{
void DoStuff() override
{
// Do stuff here.
}
};
struct Stop : public etl::message<STOP>
{
bool isEmergencyStop;
};
struct SetSpeed : public etl::message<SET_SPEED>
{
uint32_t speed;
};
void Receive(const etl::imessage& msg);
```

View File

@ -0,0 +1,139 @@
---
title: "reference_counted_message_pool"
---
{{< callout type="info">}}
Header: `reference_counted_message_pool.h`
Header: `ireference_counted_message_pool.h`
{{< /callout >}}
Allocates `etl::ireference_counted_message` types that are used by `etl::shared_message`.
Uses a supplied `memory_block allocator` derived from `etl::imemory_block_allocator`.
## ireference_counted_message_pool.h
Defines the following class.
`etl::ireference_counted_message_pool`
## reference_counted_message_pool.h
Defines the following classes.
`etl::reference_counted_message_pool_exception`
`etl::reference_counted_message_pool_allocation_failure`
`etl::reference_counted_message_pool_release_failure`
## ireference_counted_message_pool
```cpp
etl::ireference_counted_message_pool
```
The interface for reference counted message pools.
```cpp
virtual ~ireference_counted_message_pool() {}
```
```cpp
virtual void release(const etl::ipool_message& msg) = 0;
```
Virtual `lock()` and `unlock()` functions are defined. The default action is to do nothing.
A derived class may override these functions to provide a thread or interrupt safe pool.
`virtual void lock()`
`virtual void unlock()`
## reference_counted_message_pool
```cpp
etl::reference_counted_message_pool<TCounter>
```
The concrete reference counted message pool.
```cpp
reference_counted_message_pool(imemory_block_allocator& memory_block_allocator)
```
Constructs the pool and assigns the memory block allocator to it.
---
```cpp
template <typename TMessage>
etl::reference_counted_message<TMessage, TCounter>* allocate()
```
Returns a pointer to a pool message that holds a `TMessage`.
The message is default constructed.
ETL_ASSERT if one cannot be allocated and returns `ETL_NULLPTR`.
---
```cpp
template <typename TMessage>
etl::reference_counted_message<TMessage, TCounter>* allocate(const TMessage& message)
```
Returns a pointer to a pool message that holds a `TMessage`.
ETL_ASSERT if one cannot be allocated and returns `ETL_NULLPTR`.
---
```cpp
void release(const etl::ireference_counted_message& rcmessage)
```
Returns the reference counted to a pool message that holds a `TMessage`.
`ETL_ASSERT` if it cannot be released. Reasons can include the message not belonging to the pool.
## pool_message_parameters
**C++03**
The C++03 version defines the largest size and alignment of up to 8 types at a time.
```cpp
template <typename TMessage1, typename TMessage2 = TMessage1,
typename TMessage3 = TMessage1, typename TMessage4 = TMessage1,
typename TMessage5 = TMessage1, typename TMessage6 = TMessage1,
typename TMessage7 = TMessage1, typename TMessage8 = TMessage1>
struct pool_message_parameters
```
---
```cpp
static const size_t max_size;
```
The maximum size.
---
```cpp
static const size_t max_alignment;
```
The maximum alignment.
**C++11 or above**
The C++11 version defines the largest size and alignment of a set of message types.
```cpp
template <typename TMessage1, typename... TMessages>
struct pool_message_parameters
```
---
```cpp
static constexpr size_t max_size
```
The maximum size.
---
```cpp
static constexpr size_t max_alignment;
```
The maximum alignment.
---
**For C++11, with atomic support.**
```cpp
template <typename TObject>
using atomic_counted_message_pool = etl::reference_counted_message_pool<etl::atomic_int32_t>;
```
Defines an alias to a reference counted message pool that uses an atomic.

View File

@ -0,0 +1,197 @@
---
title: "reference_counted_message"
---
{{< callout type="info">}}
Header: `reference_counted_message.h`
{{< /callout >}}
Reference counted message types that are used by `etl::shared_message`.
**Defines the following classes**
```cpp
etl::ireference_counted_message
```
The interface of all reference counted message types.
---
```cpp
etl::reference_counted_message<typename TMessage, typename TCounter>
```
Derived from `etl::ireference_counted_message`.
```cpp
etl::persistent_message<typename TMessage>
```
Derived from `etl::ireference_counted_message`.
## ireference_counted_message
```cpp
etl::ireference_counted_message
```
The interface of all reference counted message types.
---
```cpp
virtual ~ireference_counted_message()
```
---
```cpp
ETL_NODISCARD virtual etl::imessage& get_message() = 0;
```
Get a reference to the message.
---
```cpp
ETL_NODISCARD virtual const etl::imessage& get_message() const = 0;
```
Get a const reference to the message.
---
```cpp
ETL_NODISCARD virtual etl::ireference_counter& get_reference_counter() = 0;
```
Get a reference to the reference counter.
---
```cpp
ETL_NODISCARD virtual const etl::ireference_counter& get_reference_counter() const = 0;
```
Get a const reference to the reference counter.
---
```cpp
virtual void release() = 0;
```
Release back to the owner.
## reference_counted_message
```cpp
etl::reference_counted_message<typename TMessage, typename TCounter>
```
The implementation of reference counted messages owned by a pool.
Will static assert if TMessage is no derived from etl::imessage.
---
```cpp
reference_counted_message(const TMessage& message, etl::ireference_counted_message_pool& owner)
```
Constructs from a message and the pool from which the reference counted message is allocated.
The message is copied.
---
```cpp
reference_counted_message(etl::ireference_counted_message_pool& owner)
```
Constructs from a message and the pool from which the reference counted message is allocated.
The message is default constructed.
---
```cpp
ETL_NODISCARD TMessage& get_message() ETL_OVERRIDE
```
Get a reference to the message.
---
```cpp
ETL_NODISCARD const TMessage& get_message() const ETL_OVERRIDE
```
Get a const reference to the message.
---
```cpp
ETL_NODISCARD etl::ireference_counter& get_reference_counter() ETL_OVERRIDE
```
Get a reference to the reference counter.
---
```cpp
ETL_NODISCARD const etl::ireference_counter& get_reference_counter() const ETL_OVERRIDE
```
Get a const reference to the reference counter.
---
```cpp
void release() ETL_OVERRIDE
```
Release back to the owner pool.
## persistent_message
```cpp
etl::persistent_message<typename TMessage>
```
The implementation of reference counted messages not owned by a pool.
It's counter type is `void`.
Will static assert if `TMessage` is not derived from `etl::imessage`.
---
```cpp
persistent_message(const TMessage& message)
```
Constructs from a message.
The message is copied.
---
```cpp
ETL_NODISCARD TMessage& get_message() ETL_OVERRIDE
```
Get a reference to the message.
---
```cpp
ETL_NODISCARD const TMessage& get_message() const ETL_OVERRIDE
```
Get a const reference to the message.
---
```cpp
ETL_NODISCARD etl::ireference_counter& get_reference_counter() ETL_OVERRIDE
```
Get a reference to the reference counter.
---
```cpp
ETL_NODISCARD const etl::ireference_counter& get_reference_counter() const ETL_OVERRIDE
```
Get a const reference to the reference counter.
---
```cpp
void release() ETL_OVERRIDE
```
Does nothing for a persistent message.
## For C++11, with atomic support.
```cpp
template <typename TMessage>
using atomic_counted_message = etl::reference_counted_message<TMessage, etl::atomic_int32_t>;
```
Defines an alias to a reference counted message that uses an atomic.

View File

@ -0,0 +1,79 @@
---
title: "shared_message"
weight: 2
---
{{< callout type="info">}}
Header: `shared_message.h`
{{< /callout >}}
Shared Messages
The type used to encapsulate reference counted messages.
Shared messages are usually passed by value.
See the Shared Message Tutorial
---
```cpp
template <typename TPool, typename TMessage>
shared_message(TPool& owner, const TMessage& message)
```
Static asserts if `TPool` is not derived from `etl::ireference_counted_message_pool`
Static asserts if `TMessage` not derived from `etl::imessage`.
Requires that `TPool` implements the following member function to allocate from the pool.
```cpp
template <typename TMessage>
etl::ireference_counted_message* allocate(const TMessage& message)
```
---
```cpp
explicit shared_message(etl::ireference_coutnted_message& message)
```
Construct from a reference counted message.
---
```cpp
shared_message(const etl::shared_message& other)
```
Copy constructor.
---
```cpp
shared_message& operator =(const etl::shared_message& other)
```
Assignment operator.
---
```cpp
~shared_message()
```
Destructor.
---
```cpp
ETL_NODISCARD etl::imessage& get_message()
```
Gets a reference to the contained message.
---
```cpp
ETL_NODISCARD const etl::imessage& get_message() const
```
Gets a const reference to the contained message.
---
```cpp
ETL_NODISCARD uint32_t get_reference_count() const
```
Gets the current reference count for this shared message.

View File

@ -1,6 +0,0 @@
plugins:
- jekyll-relative-links
relative_links:
enabled: true
include:
- manchester.md

131
docs/_index.md Normal file
View File

@ -0,0 +1,131 @@
---
title: "Embedded Template Library"
weight: 998
type: hextra-home
---
<div class="not-prose badges">
<div>
<img src="https://img.shields.io/github/v/release/jwellbelove/etl" alt="release">
<img src="https://img.shields.io/github/release-date/jwellbelove/etl?color=%231182c3" alt="date">
<img src="https://img.shields.io/badge/c%2B%2B-98/03/11/14/17/20/23-blue.svg" alt="standard">
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="license">
<img src="https://img.shields.io/github/contributors-anon/ETLCPP/etl" alt="contributors">
<img src="https://img.shields.io/github/forks/ETLCPP/etl?style=flat" alt="forks">
<img src="https://img.shields.io/github/stars/ETLCPP/etl?style=flat" alt="stars">
</div>
<div>
<img src="https://github.com/ETLCPP/etl/actions/workflows/msvc.yml/badge.svg?branch=master" alt="CI MSVC">
</div>
<div>
<img src="https://github.com/ETLCPP/etl/actions/workflows/gcc-c++11.yml/badge.svg?branch=master" alt="CI GCC 11">
<img src="https://github.com/ETLCPP/etl/actions/workflows/gcc-c++14.yml/badge.svg?branch=master" alt="CI GCC 14">
<img src="https://github.com/ETLCPP/etl/actions/workflows/gcc-c++17.yml/badge.svg?branch=master" alt="CI GCC 17">
<img src="https://github.com/ETLCPP/etl/actions/workflows/gcc-c++20.yml/badge.svg?branch=master" alt="CI GCC 20">
<img src="https://github.com/ETLCPP/etl/actions/workflows/gcc-c++23.yml/badge.svg?branch=master" alt="CI GCC 23">
<img src="https://github.com/ETLCPP/etl/actions/workflows/gcc-syntax-checks.yml/badge.svg?branch=master" alt="CI GCC syntax">
</div>
<div>
<img src="https://github.com/ETLCPP/etl/actions/workflows/clang-c++11.yml/badge.svg?branch=master" alt="CI Clang 11">
<img src="https://github.com/ETLCPP/etl/actions/workflows/clang-c++14.yml/badge.svg?branch=master" alt="CI Clang 14">
<img src="https://github.com/ETLCPP/etl/actions/workflows/clang-c++17.yml/badge.svg?branch=master" alt="CI Clang 17">
<img src="https://github.com/ETLCPP/etl/actions/workflows/clang-c++20.yml/badge.svg?branch=master" alt="CI Clang 20">
<img src="https://github.com/ETLCPP/etl/actions/workflows/clang-c++23.yml/badge.svg?branch=master" alt="CI Clang 23">
<img src="https://github.com/ETLCPP/etl/actions/workflows/clang-syntax-checks.yml/badge.svg?branch=master" alt="CI Clang syntax">
</div>
<div>
<a href="https://github.com/ETLCPP/etl/actions/workflows/coverage.yml"><img src="https://github.com/ETLCPP/etl/actions/workflows/coverage.yml/badge.svg" alt="coverage"></a>
<a href="https://www.codacy.com/manual/jwellbelove/etl"><img src="https://api.codacy.com/project/badge/Grade/3c14cd918ccf40008d0bcd7b083d5946" alt="Codacy"></a>
</div>
<div>
<a href="https://www.etlcpp.com/sponsor.html"><img src="https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86" alt="Sponsor"></a>
</div>
</div>
## Version
This documents version **{{< version >}}**.
## Motivation
C++ is a powerful language for embedded systems development, with templates offering a great deal of flexibility and type safety. While the C++ Standard Library provides a wealth of well-tested functionality, it’s often not well suited to environments with strict deterministic behavior and limited resources.
In many embedded applications, dynamic memory allocation is discouraged or outright prohibited, making standard STL containers and many other components impractical or unusable.
What’s needed is a template library specifically designed for embedded systems — one that allows developers to define fixed or maximum sizes for containers and other objects at compile time. Additionally, since many older (but still in use) embedded toolchains lack full support for standards beyond C++03, it's valuable to have access to a library that backports select features from later versions of the C++ Standard Library.
## About the ETL
The Embedded Template Library (ETL) is not intended as a full replacement for the C++ Standard Template Library (STL), but rather as a complementary solution tailored specifically for embedded systems.
**Its design goals include**
- Providing a set of containers with fixed or maximum sizes defined at compile-time.
- Offering APIs that closely resemble those of the STL, enabling familiar and consistent usage.
- Maintaining compatibility with C++98 while implementing many features introduced in later standards
(C++11/14/17/20/23/26) wherever possible.
- Ensuring deterministic behavior, which is critical in real-time and resource-constrained environments.
- Introducing additional components and utilities useful in embedded contexts but absent from the STL.
- The ETL avoids dynamic memory allocation entirely; the heap is never used. All non-intrusive containers have a fixed capacity, allowing memory requirements to be fully determined at compile-time. This makes the ETL ideal for lower-resource embedded applications where predictability, performance, and memory control are essential.
The library is compatible with any compiler that supports C++03 or later.
Help on integrating the ETL with your project may be found here.
## Key Features of the ETL
- Actively Maintained: Developed and maintained on GitHub since 2014.
- Open Source: MIT licensed.
- No STL Dependency: Designed to operate independently of the C++ Standard Template Library.
- No Dynamic Memory Allocation: All storage is allocated either at compile-time or on the stack; heap usage is entirely avoided.
- RTTI and Virtual Functions: No runtime type information (RTTI) is required. Virtual functions are used sparingly and only when strictly necessary.
- Header-Only Library: All functionality is provided via header files; No separate compilation needed.
- Fixed-Capacity Containers: Offers STL-like containers with fixed or maximum capacity, plus additional non-standard container types.
- Cache Efficiency: Containers use contiguous memory layouts for optimal cache performance.
- Compact Codebase: Shared base classes (based on type) help reduce overall container code size.
- Compile-Time Features:
Templated compile-time constants
Template-based design pattern base classes (e.g., Visitor, Observer)
Type-safe smart enumerations
Type-safe typedefs and constants
- Embedded System Frameworks:
Message routing
Finite state machines
Task scheduling
- C++11 Backports:
Implements many C++11 features (type traits, algorithms, containers) for use in C++03 environments.
- Utilities:
CRC calculations (8, 16, 32 & 64-bit)
Checksums and hash functions
- Variants (type-safe unions)
- Extensive template support utilities
- Robust Error Handling: Configurable error checking using asserts, exceptions, error handlers, or no checks; user’s choice.
- Thoroughly Tested:
Over 10,000 unit tests
Tested with Visual Studio 2022, GCC 12, and Clang 14
Continuous integration via GitHub Actions.
- Readable and Well-Documented: Clean, maintainable source code with clear documentation.
- Support: Free email support available. A Slack group is available. Paid support on request.
- Archived: A snapshot of the ETL is preserved in the Arctic Code Vault for long-term digital preservation.
## Support the ETL
Maintaining the ETL can take a lot of man-hours of work, but unfortunately it doesn't pay the bills. When I have to take on paying work, the ETL gets a lot less attention. So if you have found the library is an important component in your work and you would like to help out, then please consider by supporting the project.
---
[**Is the ETL free?**]({{< relref "is the ETL free.md" >}})
---
Any help porting the library to work under different platforms and compilers would be gratefully received.
I am especially interested in people who are using Keil, IAR, Green Hills, TI Code Composer etc, bare metal
or RTOS, and DSPs.
Many thanks.
John.

56
docs/about.md Normal file
View File

@ -0,0 +1,56 @@
---
title: "About"
weight: 3002
---
## About me
I have been involved in technology and computer systems for all of my working life and have amassed considerable knowledge of designing and implementing systems that are both performant and correct.
My role normally encompasses the entire project life-cycle, from specification to maintenance phase.
Most systems I have worked on have required high speed and deterministic performance, often within a highly constrained platform. I am experienced in designing and adapting algorithms to solutions that are both space and time efficient, avoiding the normal overheads of standard solutions.
Acting as a mentor for colleagues has often been a significant, though unofficial, part of my role.
## Why write this library?
I wrote this library, and all the others I have written over the
years, because I'm lazy.
Yes, lazy!
One of the things I really hate when writing software is having to do the same, or something almost the same, over and over again. The first thing I think when presented with a problem that requires a specific set of functionality is "Is this a specific case of a more generic problem?". Surprisingly, I can say "yes" more often than you would expect. Even if not all of the problem can be seen as generic, there are almost certainly parts that are. In every job I've had I've left an extensive code library behind me.
Reinventing the wheel every time is a bad idea, for many reasons.
- **Compile-Time Features:**
Templated compile-time constants
Template-based design pattern base classes (e.g., Visitor, Observer)
Type-safe smart enumerations
Type-safe typedefs and constants
- **Code Bloat**
Multiple instances of slight variations of a theme results in an increase in code size due to no commonality of functionality.
Testing, more testing or no testing.
Are all the variants tested to the same degree?
Are some tested at all?
- **Variable functionality**
Not all the variants are going to have the same level of functionality, or the same API.
Ad-hoc solutions are invariably only going to solve the little bit of the problem that was needed at the time.
This goes against the YAGNI principle, but...
*I think that YAGNI can often be just another way of saying ISEP.*
*I believe in GIRFT.*
*I have over three decades of empirical proof.*
- **No collective knowledge base**
Without commonality every new variant has to be learnt. The underlying principles may be understood (i.e. Linked list), but each implementation has to be understood separately, along with its particular caveats and foibles.
Documentation is likely to be patchy, if it exists at all.
- **Octopus code**
The application is liable to have a close coupling with the solution. For example, I've often seen code using linked lists directly accessing the node pointers. Ad-hoc solutions are liable to have lazy (the bad kind) implementations.
>YAGNI - You Aren't Going To Need It
>ISEP - It's Somebody Else's Problem
>GIRFT - Get It Right First Time
## Why not use 'C'?
**Greenspun's Tenth Rule** has an unofficial C corollary:
*"Any sufficiently advanced C program contains an ad hoc, informally specified, bug-ridden, slow implementation of half of C++."*
I spent 12 years programming in pure C.
I discovered that I had been reverse engineering C++ all that time.

6
docs/binary/_index.md Normal file
View File

@ -0,0 +1,6 @@
---
title: "Binary utilities"
weight: 100
---
Classes and functions that define and manipulate binary data.

574
docs/binary/binary.md Normal file
View File

@ -0,0 +1,574 @@
---
title: binary
---
{{< callout type="info">}}
Header: `binary.h`
Since: `TBC`
{{< /callout >}}
Utility functions for manipulating binary numbers.
## Rotate
Rotate the bits in the value left or right.
```cpp
template <typename T>
ETL_CONSTEXPR14 T rotate_left(T value)
```
**Return**
`value` rotated left by one bit.
```cpp
template <typename T>
ETL_CONSTEXPR14 T rotate_left(T value, size_t distance)
```
**Return**
`value` rotated left by `distance`.
```cpp
template <typename T>
ETL_CONSTEXPR14 T rotate_right(T value)
```
**Return**
`value` rotated right by one bit.
```cpp
template <typename T>
ETL_CONSTEXPR14 T rotate_right(T value, size_t distance)
```
**Return**
`value` rotated right by `distance`.
```cpp
template <typename T>
ETL_CONSTEXPR14 T rotate(T value, typename etl::make_signed<size_t>::type distance)
```
**Parameters**
`distance` Positive is left, negative is right.
**Return**
`value` rotated left or right by `distance`.
## reverse_bits
Reverse the order of the bits in a value.
```cpp
template <typename T>
ETL_CONSTEXPR14 T reverse_bits(T value)
```
The structures below define a member constant value that is Value reversed in bits.
```cpp
template <int8_t Value>
struct reverse_bits_const<int8_t, Value>
```
```cpp
template <uint8_t Value>
struct reverse_bits_const<uint8_t, Value>
```
```cpp
template <int16_t Value>
struct reverse_bits_const<int16_t, Value>
```
```cpp
template <uint16_t Value>
struct reverse_bits_const<uint16_t, Value>
```
```cpp
template <int32_t Value>
struct reverse_bits_const<int32_t, Value>
```
```cpp
template <uint32_t Value>
struct reverse_bits_const<uint32_t, Value>
```
```cpp
template <int64_t Value>
struct reverse_bits_const<int64_t, Value>
```
```cpp
template <uint64_t Value>
struct reverse_bits_const<uint64_t, Value>
```
Defines `value` The reversed bits.
## reverse_bytes
Reverse the order of the bytes in a value.
```cpp
template <typename T>
ETL_CONSTEXPR14 T reverse_bytes(T value)
```
## gray_to_binary
```cpp
template <typename T>
ETL_CONSTEXPR14 T gray_to_binary(T value)
```
Converts a gray code value to binary.
## binary_to_gray
```cpp
template <typename T>
ETL_CONSTEXPR T binary_to_gray(T value)
```
Converts a binary value to the gray code equivalent.
## count_bits
```cpp
template <typename T>
ETL_CONSTEXPR14 uint_least8_t count_bits(T value)
```
**Return**
The number of set bits in `value`.
## parity
```cpp
template <typename T>
ETL_CONSTEXPR14 uint_least8_t parity(T value)
```
**Return**
`1` if the parity of the value is odd, `0` if it is even.
## max_value_for_nbits
```cpp
template <size_t NBits>
struct max_value_for_nbits
```
**Return**
Maximum unsigned value a particular number of bits can represent.
`value_type` The type for the value.
`value` The maximum value.
## fold_bits
```cpp
template <typename TReturn, size_t NBits, typename TValue>
ETL_CONSTEXPR14 TReturn fold_bits(TValue value)
```
**Description**
Fold a binary number down to a set number of bits using XOR.
**Example**
`0xE8C9AACCBC3D9A8F` folded down to 20 bits = `0x998E8`
```cpp
uint32_t result = etl::fold_bits<uint32_t, 20>(0xE8C9AACCBC3D9A8F);
```
## sign_extend
Sign extends a binary number.
```cpp
template <typename TReturn, size_t NBits, typename TValue>
ETL_CONSTEXPR14 TReturn sign_extend(TValue value)
```
**Description**
Converts an N bit binary number, where bit N-1 is the sign bit, to a signed integral type.
---
```cpp
template <typename TReturn, size_t NBits, size_t Shift, typename TValue>
ETL_CONSTEXPR14 TReturn sign_extend(TValue value)
```
**Description**
Converts an N bit binary number, where bit N-1 is the sign bit, and `Shift` is the right shift amount, to a signed integral type.
---
```cpp
template <typename TReturn, typename TValue>
ETL_CONSTEXPR14 TReturn sign_extend(TValue value, size_t nbits)
```
**Description**
Converts an N bit binary number, where bit N-1 is the sign bit, to a signed integral type.
---
```cpp
template <typename TReturn, typename TValue>
ETL_CONSTEXPR14 TReturn sign_extend(TValue value, size_t nbits, size_t shift)
```
**Description**
Converts an N bit binary number, where bit N-1 is the sign bit, and shift is the right shift amount, to a signed integral type.
## count_leading_zeros
```cpp
template <typename T>
ETL_CONSTEXPR14 uint_least8_t count_leading_zeros(T value)
```
**Description**
Counts the number of leading zeros in a binary number
## count_trailing_zeros
```cpp
template <typename T>
ETL_CONSTEXPR14 uint_least8_t count_trailing_zeros(T value)
```
**Description**
Counts the number of trailing zeros in a binary number
## count_leading_ones
```cpp
template <typename T>
ETL_CONSTEXPR14 uint_least8_t count_leading_ones(T value)
```
**Description**
Counts the number of leading ones in a binary number
## count_trailing_ones
```cpp
template <typename T>
ETL_CONSTEXPR14 uint_least8_t count_trailing_ones(T value)
```
**Description**
Counts the number of trailing ones in a binary number
## first_set_bit_position
```cpp
template <typename T>
ETL_CONSTEXPR14 uint_least8_t first_set_bit_position(T value)
```
**Description**
Finds the index of the first set bit from lsb.
## first_clear_bit_position
```cpp
template <typename T>
ETL_CONSTEXPR14 uint_least8_t first_clear_bit_position(T value)
```
**Description**
Finds the index of the first clear bit from lsb.
## first_bit_position
```cpp
template <typename T>
ETL_CONSTEXPR14 uint_least8_t first_bit_position(bool state, T value)
```
**Description**
Finds the index of the first bit in the specified state, from lsb.
## binary_fill
```cpp
template <typename TResult, typename TValue>
ETL_CONSTEXPR TResult binary_fill(TValue value)
```
Fills a value of the specified width with a repeating binary pattern.
*Run time*
Generate `0x12121212`
```cpp
etl::binary_fill<uint32_t>(uint8_t(0x12));
```
---
```cpp
template <typename TResult, typename TValue, TValue Value>
ETL_CONSTEXPR TResult binary_fill()
```
*Partial compile time*
Generate `0x12121212`
```cpp
etl::binary_fill<uint32_t, uint8_t, 0x12>();
```
## has_zero_byte
```cpp
template <typename TValue>
ETL_CONSTEXPR14 bool has_zero_byte(TValue value)
```
*Run time*
Checks to see if a value contains a byte of value zero.
**Example**
`etl::has_zero_byte(uint32_t(0x01234567)) == false`
`etl::has_zero_byte(uint32_t(0x01230067)) == true`
---
```cpp
template <typename TValue, TValue Value>
ETL_CONSTEXPR14 bool has_zero_byte()
```
Checks to see if `Value` contains a byte of value zero.
*Compile time value*
## has_byte_n
Checks to see if a value contains a byte of a particular value.
```cpp
template <typename TValue>
ETL_CONSTEXPR14 bool has_byte_n(TValue value, uint8_t n)
```
*Run time*
```cpp
etl::has_byte_n(uint32_t(0x01234567), 0x12) == false
etl::has_byte_n(uint32_t(0x01234567), 0x45) == true
```
---
```cpp
template <typename TValue, TValue Value>
ETL_CONSTEXPR14 bool has_byte_n(TValue value)
```
*Partial compile time*
```cpp
etl::has_byte_n<0x12>(uint32_t(0x01234567)) == false
etl::has_byte_n<0x45>(uint32_t(0x01234567)) == true
```
## binary_merge
Merges two binary values according to a mask.
Bits set in the mask select bits in the first value, clear bits select those in the second.
```cpp
template <typename T>
ETL_CONSTEXPR T binary_merge(T first, T second, T mask)
```
```cpp
uint8_t first = 0x12;
uint8_t second = 0x34;
const uint8_t mask = 0xF0;
etl::binary_merge(first, second, mask) Equals 0x14
```
---
```cpp
template <typename T, T Mask>
ETL_CONSTEXPR T binary_merge(T first, T second)
```
```cpp
uint8_t first = 0x12;
uint8_t second = 0x34;
const uint8_t mask = 0xF0;
etl::binary_merge<uint8_t, mask>(first, second) Equals 0x14
```
## binary_interleave
Interleaves two values such that bits abcd and efgh will result in eafbgchd.
```cpp
ETL_CONSTEXPR14 uint16_t binary_interleave(uint8_t first, uint8_t second);
ETL_CONSTEXPR14 uint32_t binary_interleave(uint16_t first, uint16_t second);
ETL_CONSTEXPR14 uint64_t binary_interleave(uint32_t first, uint32_t second);
```
## Odd / Even
Determines the odd or evenness of a value.
```cpp
template <typename T>
ETL_CONSTEXPR bool is_odd(T value)
```
```cpp
template <typename T>
ETL_CONSTEXPR bool is_even(T value)
```
## Constants
```cpp
enum binary_constant
```
An enumeration of 256 constants from `b00000000` to `b11111111` (`0` to `255`)
---
```cpp
enum bit_constant
```
An enumeration of 32 constants from `b0` to `b31` (`1` to `4294967296`)
---
```cpp
template <size_t Position>
struct bit
```
`value_type` The type of the value.
`value` The value of the bit at `Position`.
## Creating bit masks
These classes and constexpr functions help create lsb and msb masks.
```cpp
template <typename T, size_t NBits>
class lsb_mask;
```
Defines the member constant value as a binary value of NBits `1` shift to the LSB.
e.g. `lsb_mask<int8_t, 3>::value == 0b00000111`
From: `20.34.0`
---
```cpp
template <typename T>
ETL_CONSTEXPR T make_lsb_mask(size_t nbits)
```
Returns a binary value of nbits `1` shift to the LSB.
e.g. `make_lsb_mask<int8_t>(3) == 0b00000111`
From: `20.34.0`
---
```cpp
template <typename T, size_t NBits>
ETL_CONSTEXPR T make_lsb_mask()
```
**Description**
Returns a binary value of nbits `1` shift to the LSB.
e.g. `make_lsb_mask<int8_t, 3>() == 0b00000111`
From: `20.38.7`
---
```cpp
template <typename T, size_t NBits>
class msb_mask;
```
**Return**
A binary value of nbits `1` shift to the MSB.
e.g. `msb_mask<int8_t, 3>::value == 0b11100000`
From: `20.34.0`
---
```cpp
template <typename T>
ETL_CONSTEXPR T make_msb_mask(size_t nbits)
```
**Description**
Defines the member constant value as a binary value of NBits `1` shift to the MSB.
e.g. `make_msb_mask<int8_t>(3) == 0b11100000`
20.34.0
---
```cpp
template <typename T, size_t NBits>
ETL_CONSTEXPR T make_msb_mask()
```
**Description**
Defines the member constant value as a binary value of NBits `1` shift to the MSB.
e.g. `make_msb_mask<int8_t, 3>() == 0b11100000`
From: `20.38.7`
## Bit manipulation functors
These functors are most useful where lambdas are not available.
## binary_not
```cpp
template <typename T>
struct binary_not : public etl::unary_function<T, T>;
```
From: `20.38.11`
---
```cpp
ETL_CONSTEXPR
binary_not()
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR
ETL_NODISCARD
T operator()(T value) const ETL_NOEXCEPT
```
**Return**
~value.
## binary_and
```cpp
template <typename T>
struct binary_and : public etl::unary_function<T, T>;
```
From: `20.38.11`
---
```cpp
ETL_CONSTEXPR
explicit binary_and(T and_value)
```
**Description**
Constructor.
---
```cpp
ETL_CONSTEXPR
ETL_NODISCARD
T operator()(T value) const ETL_NOEXCEPT
```
**Return**
`value & and_value`.
## binary_or
```cpp
template <typename T>
struct binary_or : public etl::unary_function<T, T>;
```
From: `20.38.11`
---
```cpp
ETL_CONSTEXPR
explicit binary_or(T or_value)
```
**Description**
Constructor.
---
```cpp
ETL_CONSTEXPR
ETL_NODISCARD
T operator()(T value) const ETL_NOEXCEPT
```
**Return**
`value | or_value`.
## binary_xor
```cpp
template <typename T>
struct binary_xor : public etl::unary_function<T, T>;
```
From: `20.38.11`
---
```cpp
ETL_CONSTEXPR
explicit binary_xor(T xor_value)
```
**Description**
Constructor.
---
```cpp
ETL_CONSTEXPR
ETL_NODISCARD
T operator()(T value) const ETL_NOEXCEPT
```
**Return**
value ^ xor_value.

117
docs/binary/bit.md Normal file
View File

@ -0,0 +1,117 @@
---
title: "bit"
---
{{< callout type="info">}}
Header: `bit.h`
Since: `TBC`
Similar to: [STL bit header](https://en.cppreference.com/cpp/header/bit)
{{< /callout >}}
Utility functions for manipulating binary numbers.
A reverse engineered version of C++20's and C++23's `<bit>` header.
## bit_cast
```cpp
template <typename TDestination, typename TSource>
ETL_CONSTEXPR14 TDestination bit_cast(const TSource& source) ETL_NOEXCEPT
```
**Description**
Returns a value of type `TDestination` by reinterpreting the `TSource` object.
## byteswap
```cpp
template <typename T>
ETL_CONSTEXPR14 T byteswap(T n) ETL_NOEXCEPT
```
**Description**
Reverses the bytes in `n`.
## has_single_bit
```cpp
template <typename T>
ETL_CONSTEXPR14 bool has_single_bit(T n) ETL_NOEXCEPT
```
**Description**
Checks if `n` is a power of two, or has one bit set.
## bit_ceil
```cpp
template <typename T>
ETL_CONSTEXPR14 T bit_ceil(T n)
```
**Description**
Calculates the smallest power of two, that is not smaller than `n`.
## bit_floor
```cpp
template <typename T>
ETL_CONSTEXPR14 T bit_floor(T n) ETL_NOEXCEPT
```
**Description**
Calculates the largest power of two that is not greater than `n`.
## bit_width
```cpp
template <typename T>
ETL_CONSTEXPR14 T bit_width(T n) ETL_NOEXCEPT
```
**Description**
If `n` is not `0`, calculates the number of bits needed to store it.
If `n` is `0`, then the result is `0`.
## rotl
```cpp
template <typename T>
ETL_NODISCARD ETL_CONSTEXPR14 T rotl(T value, int n) ETL_NOEXCEPT
```
**Description**
Computes a left circular shift of value by `n`.
## rotr
```cpp
template <typename T>
ETL_NODISCARD ETL_CONSTEXPR14 T rotr(T value, int n) ETL_NOEXCEPT
```
**Description**
Computes a right circular shift of value by `n`.
## countl_zero
```cpp
template <typename T>
ETL_NODISCARD ETL_CONSTEXPR14 int countl_zero(T value) ETL_NOEXCEPT
```
**Description**
Returns the number of consecutive `0` bits in `n`, starting from the most significant bit (left).
## countl_one
```cpp
template <typename T>
ETL_NODISCARD ETL_CONSTEXPR14 int countl_one(T value) ETL_NOEXCEPT
```
**Description**
Returns the number of consecutive `1` bits in `n`, starting from the most significant bit (left).
## countr_zero
```cpp
template <typename T>
ETL_NODISCARD ETL_CONSTEXPR14 int countr_zero(T value) ETL_NOEXCEPT
```
**Description**
Returns the number of consecutive `0` bits in `n`, starting from the least significant bit (right).
## countr_one
```cpp
template <typename T>
ETL_NODISCARD ETL_CONSTEXPR14 int countr_one(T value) ETL_NOEXCEPT
```
**Description**
Returns the number of consecutive `1` bits in `n`, starting from the least significant bit (right).
## popcount
```cpp
template <typename T>
ETL_NODISCARD ETL_CONSTEXPR14 int popcount(T value) ETL_NOEXCEPT
```
**Description**
Counts the number of `1` bits in an unsigned integer.

149
docs/binary/byte.md Normal file
View File

@ -0,0 +1,149 @@
---
title: "byte"
---
{{< callout type="info">}}
Header: `byte.h`
From: `20.24.0`
Similar to: [std::byte](https://en.cppreference.com/cpp/types/byte)
{{< /callout >}}
A type that implements the concept of byte
**C++03**
Implemented as a class.
Cannot be cast using `static_cast`.
**C++11 or above**
Implemented as enum class.
All functions are `constexpr`.
## Constructors
```cpp
byte()
```
**Description**
Constructs a default initialised byte.
C++03
---
```cpp
template <typename T>
explicit byte(T v)
```
Constructs a byte initialised to `v`.
## Non-member functions
```cpp
template <typename TInteger>
constexpr TInteger to_integer(etl::byte b) noexcept
```
**Description**
Converts to an integral type.
`constexpr` and `noexcept` for C++11 and above.
---
```cpp
template <typename TInteger>
constexpr etl::byte operator <<(etl::byte b, TInteger shift) noexcept
```
**Description**
Shifts the value of the byte to the left and returns the new byte.
`constexpr` and `noexcept` for C++11 and above.
---
```cpp
template <typename TInteger>
constexpr etl::byte operator >>(etl::byte b, TInteger shift) noexcept
```
**Description**
Shifts the value of the byte to the right and returns the new byte.
`constexpr` and `noexcept` for C++11 and above.
---
```cpp
template <typename TInteger>
constexpr etl::byte& operator <<=(etl::byte& b, TInteger shift) noexcept
```
**Description**
Shifts the value of the byte to the left and returns a reference to the byte.
`constexpr` and `noexcept` for C++11 and above.
---
```cpp
template <typename TInteger>
constexpr etl::byte& operator >>=(etl::byte& b, TInteger shift) noexcept
```
**Description**
Shifts the value of the byte to the right and returns a reference to the byte.
`constexpr` and `noexcept` for C++11 and above.
---
```cpp
constexpr etl::byte operator |(etl::byte lhs, etl::byte rhs) noexcept
```
ORs the two bytes returns the new byte.
`constexpr` and `noexcept` for C++11 and above.
---
```cpp
constexpr etl::byte operator &(etl::byte lhs, etl::byte rhs) noexcept
```
**Description**
ANDs the two bytes returns the new byte.
`constexpr` and `noexcept` for C++11 and above.
---
```cpp
constexpr etl::byte operator ^(etl::byte lhs, etl::byte rhs) noexcept
```
**Description**
Exclusive ORs the two bytes returns the new byte.
`constexpr` and `noexcept` for C++11 and above.
---
```cpp
constexpr etl::byte& operator |=(etl::byte& lhs, etl::byte rhs) noexcept
```
**Description**
ORs the two bytes returns and a reference to the first parameter.
`constexpr` for C++14 and above.
`noexcept` for C++11 and above.
---
```cpp
constexpr etl::byte& operator &=(etl::byte& lhs, etl::byte rhs) noexcept
```
**Description**
ANDs the two bytes returns and a reference to the first parameter.
`constexpr` for C++14 and above.
`noexcept` for C++11 and above.
---
```cpp
constexpr etl::byte& operator ^=(etl::byte& lhs, etl::byte rhs) noexcept
```
**Description**
Exclusive ORs the two bytes and returns a reference to the first parameter.
`constexpr` for C++14 and above.
`noexcept` for C++11 and above.
---
```cpp
constexpr etl::byte operator ~(etl::byte b) noexcept
```
**Description**
Negates the value of the byte and returns the new value.
`constexpr` and `noexcept` for C++11 and above.

144
docs/binary/flags.md Normal file
View File

@ -0,0 +1,144 @@
---
title: "flags"
---
{{< callout type="info">}}
Header: `flags.h`
Since: `TBC`
{{< /callout >}}
Provides a wrapper around a set of binary flags.
Supports compile time and runtime variants
```cpp
template <typename T, T MASK = etl::integral_limits<T>::max>
class flags
```
`T` must be an unsigned integral type.
`MASK` is used to exclude unused or undefined bits from operations of the flags. By default, all bits are included.
Most member functions may be chained.
```cpp
bool isF5Set = flags.set(bitPattern, true).flip().test(F5);
```
## Constructor
```cpp
ETL_CONSTEXPR flags() ETL_NOEXCEPT
```
**Description**
Constructs a flag set with all elements set to `0` (`false`).
---
```cpp
ETL_CONSTEXPR flags(value_type pattern) ETL_NOEXCEPT
```
**Description**
Constructs a flag set with elements set to pattern.
---
```cpp
ETL_CONSTEXPR flags(const flags<T, MASK>& pattern) ETL_NOEXCEPT
```
**Description**
Constructs a flag set with elements set to pattern.
## Modifiers
```cpp
ETL_CONSTEXPR14 flags<T, MASK>& operator=(flags<T, MASK> other) ETL_NOEXCEPT
```
**Description**
Assigns from another flags object.
---
```cpp
ETL_CONSTEXPR14 flags<T, MASK>& operator=(value_type pattern) ETL_NOEXCEPT
```
**Description**
Assigns from a bit pattern.
---
```cpp
template <value_type pattern, bool value>
ETL_CONSTEXPR14 flags<T, MASK>& set() ETL_NOEXCEPT
```
---
```cpp
template <value_type pattern>
ETL_CONSTEXPR14 flags<T, MASK>& set(bool value) ETL_NOEXCEPT
```
---
```cpp
template <value_type pattern>
ETL_CONSTEXPR14 flags<T, MASK>& set() ETL_NOEXCEPT
```
---
```cpp
ETL_CONSTEXPR14 flags<T, MASK>& set(value_type pattern) ETL_NOEXCEPT
```
---
```cpp
ETL_CONSTEXPR14 flags<T, MASK>& set(value_type pattern, bool value) ETL_NOEXCEPT
```
---
```cpp
ETL_CONSTEXPR14 flags<T, MASK>& clear() ETL_NOEXCEPT
```
____________________________________________________________________________________________________
template <value_type pattern>
ETL_CONSTEXPR14 flags<T, MASK>& reset() ETL_NOEXCEPT
____________________________________________________________________________________________________
ETL_CONSTEXPR14 flags<T, MASK>& reset(value_type pattern) ETL_NOEXCEPT
____________________________________________________________________________________________________
ETL_CONSTEXPR14 flags<T, MASK>& flip() ETL_NOEXCEPT
____________________________________________________________________________________________________
template <value_type pattern>
ETL_CONSTEXPR14 flags<T, MASK>& flip() ETL_NOEXCEPT
____________________________________________________________________________________________________
ETL_CONSTEXPR14 flags<T, MASK>& flip(value_type pattern) ETL_NOEXCEPT
____________________________________________________________________________________________________
Access
template <value_type pattern>
ETL_CONSTEXPR bool test() const ETL_NOEXCEPT
Test the bits for the compile time pattern.
____________________________________________________________________________________________________
ETL_CONSTEXPR bool test(value_type pattern) const ETL_NOEXCEPT
Test the bits for the run time pattern.
____________________________________________________________________________________________________
ETL_CONSTEXPR value_type value() const ETL_NOEXCEPT
ETL_CONSTEXPR operator value_type() const ETL_NOEXCEPT
Returns the value of the flags as a value_type.
____________________________________________________________________________________________________
Operations
____________________________________________________________________________________________________
Non-member functions
template <typename T, T MASK>
void swap(flags<T, MASK>& lhs, flags<T, MASK>& rhs)
Swaps two flags.
template <typename T, T MASK>
bool operator == (flags<T, MASK>& lhs, flags<T, MASK>& rhs)
Checks equality of two flags.
template <typename T, T MASK>
bool operator != (flags<T, MASK>& lhs, flags<T, MASK>& rhs)
Checks inequality of two flags.

15
docs/blog/_index.md Normal file
View File

@ -0,0 +1,15 @@
---
title: "Blog"
weight: 3001
---
## Graphics
[Determining line-line intersections]({{% relref "./graphics/determining-line-line-intersections.md" %}})
[Applications of dot and cross products]({{% relref "./graphics/applications-of-dot-and-cross-products.md" %}})
[Scanning an arbitrarily rotated rectangular region]({{% relref "./graphics/scanning-an-arbitrarily-rotated-rectangular-region.md" %}})
## Algorithms
[Implementing a low cost moving average]({{% relref "implementing-a-low-cost-moving-average.md" %}})

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -0,0 +1,5 @@
---
title: "Graphics"
weight: 1
---

View File

@ -0,0 +1,71 @@
---
title: "Applications of dot and cross products"
weight: 5
---
**Author:** John Wellbelove
**Date:** 2019
## The problem
Sometimes in graphical applications there is a need to know the relative position of a point with respect to a line from a reference point.
Where is the target in relation to the reference and its direction?
Dot and cross products can make this an easy task.
Let's start with a reminder of what dot and cross products are.
Take two vectors `x1,y1` and `x2,y2`
The dot product is `(x1 * x2) + (y1 * y2)` and the cross product is `(x1 * y2) - (x2 * y1)`.
Remember that the dot product is a scalar based on `cos(θ)` and the cross product is a scalar based on `sin(θ)`.
**Example**
![DotCross1](images/DotCross1.png)
We have a reference object at `Xr,Yr` facing in the direction of the arrow.
The target is at point `Xt,Yt`
![DotCross3](images/DotCross3.png)
A arbitrary point on the line from the reference in the specified direction is `Xw,Yw`
First, find the coordinates of the target and waypoint relative to the reference.
`dXw = Xw - Xr`
`dYw = Yw - Yr`
`dXt = Xt - Xr`
`dYt = Yt - Yr`
Now find the dot and cross products of these vectors.
`Dot = (dXw * dXt) + (dYw * dYt)`
`Cross = (dXw * dYt) - (dXt * dYw)`
The absolute values of the dot and cross products is unimportant, we just need the *sign*.
`Dot > 0`, `Cross < 0` : The target is forward of the reference and to the right.
`Dot > 0`, `Cross > 0` : The target is forward of the reference and to the left.
`Dot < 0`, `Cross < 0` : The target is behind the reference and to the right.
`Dot < 0`, `Cross > 0` : The target is behind the reference and to the left.
*forward*, *behind*, *left*, and *right* are relative to the reference's direction.
This calculation will be valid for any direction.
## Other uses
This technique can also be used to determine if a point is within a closed convex hull.
![DotCross4](images/DotCross4.png)
A closed convex hull defined by the lines `L1`, `L2`, `L3`, `L4`, and `L5`.
Point `P1` is inside the hull, point `P2` is outside.
For `P1`, the cross product for all of the lines will indicate that it is to the *right* and therefore, *must* be inside.
For `P2`, the cross product for `L1` will put it on the *left* hand side and therefore it *cannot* be inside the hull.
**Why does this work?**
The dot product of vectors `A` and `B` is `|A||B|cos(Ø)`
The cross product of vectors `A` and `B` is `|A||B|sin(Ø)`
Where `Ø` is the angle between the vectors `A` and `B`. Range `+-180°`
Therefore the sign of the result indicates the quadrant that target occupies in the circle around the reference, relative to the reference's direction.

View File

@ -0,0 +1,115 @@
---
title: "Determining line-line intersections"
weight: 2
---
**Author:** John Wellbelove
**Date:** 2019
It's quite common in graphics and image processing to want to know the intersection coordinates of two lines.
The common formula for a line is the familiar `y = Mx + C`.
But there is another that can be a lot easier to use when determining line to line intersections in a graphical environment.
## The issues
When using `y = Mx + C` you must be aware of the situations of when the line approaches 'vertical'.
In this case `M` tends towards infinity, which is not good in a programming environment.
The usual trick is to flip the coordinates when the slope is more than 1, and then flip back after the calculations have been made.
This can be confusing to follow and result in errors.
Also, to keep any accuracy, the calculations must normally be kept in the floating point domain, which is not ideal for performance, as the image will be in integral pixel coordinates.
## The solution
Change the definition of your lines to use the formula `Ax + By = C`.
Ideally, your lines would already be in the form `Ax + By = C`, but this is not normally the case, but we *can* easily generate the parameters from two points.
Assume we have a line defined by `(x1, y1)` and `(x2, y2)`.
We can deduce `A`, `B`, and `C` thus:
`A = y2 - y1`
`B = x1 - x2`
`C = Ax1`+ `By1`
---
Another useful calculation is the *determinant*.
Given two lines `A1x + B1y = C1` and `A2x + B2y = C2`:
`determinant = A1 * B2 - A2 * B1`
If `determinant` is zero, then the lines are parallel.
### Notes
- If `A` and `B` are both non-zero.
The equation represents a diagonal line.
- If `A == 0`, `B != 0`.
The line is the parallel to the x-axis.
- If `A != 0`, `B == 0`.
The line is the parallel to the y-axis.
- If `C == 0`
The line passes through the origin.
## Calculating the intersection
The intersection point is calculated like this:
Given two lines described by the points `(x1, y1)`, `(x2, y2)`, and `(x3, y3)`, `(x4, y4)`.
![LineCross1](images/LineCross1.png)
- Calculate the parameters `A`, `B`, and `C` for each.
`A1x + B1y = C1` and `A2x + B2y = C2`
- Calculate the determinant.
`determinant = A1 * B2 - A2 * B1`
- If `determinant == 0` then the lines are parallel, and there is no intersection point.
- Otherwise
`x = (B2 * C1 - B1 * C2) / determinant`
`y = (A1 * C2 - A2 * C1) / determinant`
## They don't need to physically intersect
The intersection point can be found even if the line segments aren't actually long enough to intersect.
The calculation will effectively extend them to where they *would* intersect, if long enough.
This means you can find intersection points relative to a fixed reference line.
![LineCross2](images/LineCross2.png)
## Refection
This describes reflecting a point across a reference line.
It uses the intersection method described above.
In the example below, we want to reflect `P` in the line `Reference`, to give us `P'`.
![Reflection1](images/Reflection1.png)
First, we need the reference line in the form `Ax + By = C`.
Next, we need to find the perpendicular from `Reference` through `P`.
Any line perpendicular to `Ax + By = C` takes the form `−Bx + Ay = D`.
To find `D`, just substitute the `x,y` coordinates from `P`.
Now we have the two lines in the form we require to find the intersection.
Find `I`, which is the intersection of the reference line and the perpendicular to `P`.
Compute `P'` by using the formula `P' = I + (I - P)`.
This calculates the vector from `P` to `I` and then adds it to `I` to move the same amount again.
## Line to point distance
The above technique can be used to find the distance of a point to a reference line.
This distance is merely the absolute length of the vector `I - P`.

View File

@ -0,0 +1,26 @@
---
title: "Dot and cross products"
weight: 4
---
**Author:** John Wellbelove
**Date:** 2019
## Dot Product
The dot product of two vectors is the sum of the products of the corresponding elements.
The dot product of vectors `(x1, y1)` and `(x2, y2)` is `x1 * x2 + y1 * y2`.
If `A` & `B` are vectors, the dot product is `|A||B|cos(θ)`, where `θ` is the angle between the `A` and `B`.
`|A|` is the length of the vector `A`.
`|B|` is the length of the vector `B`.
Therefore, we can calculate `cos(θ) = (A ⋅ B)/(|A||B|)`.
A dot product of `0` indicates two perpendicular lines, and the dot product is greatest when the lines are parallel.
## Cross Product
The cross product of vectors `(x1, y1)` and `(x2, y2)` is `x1 * y2 - y1 * x2`
If `A` & `B` are vectors, the cross product is `|A||B|sin(θ)`.
`|θ|` is the angle between the two vectors, but `θ` can be positive or negative.
Therefore, we can calculate `sin(θ) = (A x B)/(|A||B|)`.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@ -0,0 +1,41 @@
---
title: "Scanning an arbitrarily rotated rectangular region"
weight: 3
---
**Author:** John Wellbelove
**Date:** 2019
Quite often in image processing we need to scan a rectangular region in an image. The region is usually aligned to capture a specific feature in the image.
You may be presented with a skewed image, necessitating that the region should also be skewed.
![ScanRectangle1](images/ScanRectangle1.png)
If it is not absolutely necessary to scan the region at the angle of skew, then the fastest way to interrogate the pixels is to scan the image horizontally.
As was shown in the previous post, the crossing points between two lines can be easily and efficiently determined.
By moving a reference line down across the region, the start and end x coordinates of each scan line can be found.
Only the y coordinate of the reference line is relevant, though it must have a length of at least 1 unit.
Of course, we must check every line in the rectangle, and every line in the rectangle may produce a crossing point.
The reference line shown below will identify points `P1`, `P2`, `P3` and `P4` as valid crossing points.
![ScanRectangle4](images/ScanRectangle4.png)
The solution is to compare the crossing coordinates against the bounds of the enclosing rectangle.
![ScanRectangle5](images/ScanRectangle5.png)
This would eliminate points `P1` and `P4`.
![ScanRectangle2](images/ScanRectangle2.png)
This can be done for all scan lines in the bounded rectangle.
![ScanRectangle6](images/ScanRectangle6.png)
Vertical scans may be easily achieved by simply having a vertical reference line.
This technique can be applied to any convex hull.

View File

@ -0,0 +1,70 @@
---
title: "Implementing a moving average"
weight: 10
author: John Wellbelove
---
**Author:** John Wellbelove
**Date:** 2019
## Example
Imagine we have accumulated 10 values and our window size is 10.
`[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]`
The average of this sequence is `(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10) / 10 = 5.5`
We now add a new sample, `11` to the sequence. As the windows size is 10, we drop the first value.
`[ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ]`
The average of this sequence is `(2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11) / 10 = 6.5`
Now, averaging over 10 samples each time is not that big an issue, but what if it's 1000 or 10,000? Then, the overhead, both in processing time and storage has started to become a little excessive.
In the case of 10,000 samples of 'double' we are looking at 10,000 additions + 1 division each time a sample is added and a likely storage requirement of 80,000 bytes!
So we have an algorithm that has processing and storage complexity of O(N).
## What other values give the same average?
**So let's look at the problem again.**
There are many ways of getting the same average:
`[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]` = Average of `5.5`
`[ 7, 7, 7, 7, 7, 4, 4, 4, 4, 4 ]` = Average of `5.5`
---
**But what about this?**
`[ 5.5, 5.5 , 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5 ]` = Average of `5.5`
An average of `5.5` can be got from 10 samples of `5.5`.
## So why store 10 samples?
We can simply simulate the original sum just by multiplying the current average by the number of samples.
The calculation of the average for adding a new sample becomes this:
`(Old_Average * Sample_Size) + New_Sample) / (Sample_Size + 1)`
Now we have 1 multiplication, 2 additions and 1 division.
Our algorithm now has a complexity of O(1).
We can average over as large a sample size as we like and it will always take the same amount of time and use the same amount of storage. We can also change the sample size on-the-fly if we wish.
There is one downside in that the average will not exactly match the original version, as the actual oldest value is not being erased from the sum, but for the performance and storage advantages it may be a perfectly suitable solution.
You may find that you will need a slightly smaller sample size with the rolling mean to get similar results.
---
**Note**
The multiplication may be elided by re-arranging the formula.
`Old_Average + ((New_Sample - Old_Average) / (Sample_Size + 1))`
This may produce a *negative* interim value, which may be a problem if you are using scaled unsigned integral types for the average value.
---
The ETL has an implementation of this algorithm.
[pseudo_moving_average]({{% relref "../maths/pseudo_moving_average.md" %}})

8
docs/callbacks/_index.md Normal file
View File

@ -0,0 +1,8 @@
---
title: "Callbacks"
weight: 100
---
Classes that allow callbacks to be easily defined.
Includes delegates, STL style function wrappers, closures, and signal/slot frameworks.

View File

@ -0,0 +1,80 @@
---
title: "callback_service"
---
{{< callout type="info">}}
Header: `callback_service.h`
{{< /callout >}}
This template class allows easier integration of 'C' style events (such as interrupt vectors) and C++ handlers.
It can allow abstraction between low level events such as interrupts and their application dependent handlers.
The handlers may be any combination of global, static or member functions.
It utilises the templated function wrapper.
The callbacks are identified by an id. The values of the ids must range from zero or a specified offset, up to the maximum number of specified callbacks. Calling an unused callback id will either do nothing or, if the user has specified a handler, call this with the id of the callback.
There are functions that use both runtime and compile time checks of the callback id.
Compile time is preferable.
## Member functions
```cpp
template <const size_t RANGE, const size_t OFFSET = 0U>
etl::callback_service
```
`RANGE` The id range of the callbacks.
`OFFSET` The starting id for the range.
It can allow abstraction between low level events such as interrupts and their application dependent handlers.
```cpp
callback_service()
```
Sets all of the callbacks to route to the unhandled callback.
Sets the unhandled callback to default (do nothing).
---
```cpp
template <const size_t ID>
void register_callback(etl::ifunction<size_t>& callback)
```
Registers callback with the id specified in the template parameter.
A compile time error will occur if the id is out of range.
---
```cpp
void register_callback(size_t id, etl::ifunction<size_t>& callback)
```
Registers callback with the id specified in the template parameter.
The registration will be ignored if the id is out of range.
---
```cpp
void register_unhandled_callback(etl::ifunction<size_t>& callback)
```
Registers the callback to be used for unhandled ids.
---
```cpp
template <const size_t ID>
void callback()
```
Calls the callback associated with the id.
Calls the unhandled callback if the id has not been registered.
A compile time error will occur if the id is out of range.
---
```cpp
void callback(const size_t id)
```
Calls the callback associated with the id.
Calls the unhandled callback if the id has not been registered or if is out of range.
## Example
See the example project in `examples\FunctionInterruptSimulation`.

75
docs/callbacks/closure.md Normal file
View File

@ -0,0 +1,75 @@
---
title: "closure"
---
`etl::closure` wraps an `etl::delegate` and a set of arguments.
**C++11 and above**
```cpp
etl::closure<TReturn(TArgs...)>
```
**C++03.**
```cpp
etl::delegate<TReturn(TArg0)>
etl::delegate<TReturn(TArg0, TArg1)>
etl::delegate<TReturn(TArg0, TArg1, TArg2)>
etl::delegate<TReturn(TArg0, TArg1, TArg2, TArg3)>
etl::delegate<TReturn(TArg0, TArg1, TArg2, TArg3, TArg4)>
```
## Types
`delegate_type` The delegate type `etl::delegate<TReturn(TArgs...)>`
## Constructor
C++11 and above.
```cpp
ETL_CONSTEXPR14 closure(const delegate_type& f, const TArgs... args)
```
C++03.
```cpp
closure(const delegate_type& f, const TArg0 arg0)
closure(const delegate_type& f, const TArg0 arg0, const TArg1 arg1)
closure(const delegate_type& f, const TArg0 arg0, const TArg1 arg1, const TArg2 arg2)
closure(const delegate_type& f, const TArg0 arg0, const TArg1 arg1, const TArg2 arg2,
const TArg3 arg3)
closure(const delegate_type& f, const TArg0 arg0, const TArg1 arg1, const TArg2 arg2,
const TArg3 arg3, const TArg4 arg4)
```
## Operations
```cpp
template <size_t index, typename UArg>
void bind(UArg arg)
```
**Description**
Bind a new value to the argument at the specified index.
`UArg` must be one of `TArgs`.
Only non-reference types can be rebound.
Static asserts if `UArg` is not convertible to the closure's argument.
Static asserts if `UArg` is a reference type.
*C++11 and above.*
---
```cpp
template <typename... UArgs>
void bind(UArgs&&... args)
```
**Description**
Bind new values to all of the arguments at once.
The number of arguments must match the delegate.
Static asserts if the number of arguments don't match the delegate.
*C++11 and above.*
---
```cpp
ETL_CONSTEXPR14 TReturn operator()(TParams... args) const
```
**Description**
Invokes the stored delegate with the bound arguments.

View File

@ -0,0 +1,93 @@
---
title: "delegate_service"
---
{{< callout type="info">}}
Header: `delegate_service.h`
{{< /callout >}}
Delegate Service
This template class allows easier integration of 'C' style events (such as interrupt vectors) and C++ handlers.
It can allow abstraction between low level events such as interrupts and their application dependent handlers.
The handlers may be any combination of global, static, member functions, lambdas and functors.
It utilises the templated function wrapper.
The delegate callbacks are identified by an id. The values of the ids must range from zero or a specified offset, up to the maximum range of specified delegates. Calling an unused delegate id will either do nothing or, if the user has specified a handler, call this with the id of the delegate.
There are functions that use both runtime and compile time checks of the delegate id.
Compile time is preferable.
---
```cpp
template <size_t Range, size_t Offset = 0U, const etl::delegate<void(size_t)>* Delegates = nullptr>
delegate_service
```
`Range`
The id range of the delegates (last - first + 1).
`Offset`
The starting id for the range. Default `0`.
`Delegates`
An optional pointer to an array of delegate pointers.
If the pointer to a delegate array is supplied as a template parameter then the delegate service may be declared `constexpr`, otherwise the service is runtime only.
## Member functions
```cpp
delegate_service()
```
Runtime only.
Sets all of the delegates to route to the unhandled delegate.
Sets the unhandled delegate to default (do nothing).
---
```cpp
template <const size_t ID>
void register_delegate(etl::delegate<void(size_t)>& callback)
```
Runtime only.
Registers delegate with the id specified in the template parameter.
A compile time error will occur if the id is out of range.
---
```cpp
void register_delegate(size_t id, etl::delegate<void(size_t)>& callback)
```
Runtime only.
Registers delegate with the id specified in the template parameter.
The registration will be ignored if the id is out of range.
---
```cpp
void register_unhandled_delegate(etl::delegate<void(size_t)>& callback)
```
Runtime only.
Registers the delegate to be used for unhandled ids.
---
```cpp
template <const size_t ID>
void call()
```
Calls the delegate associated with the id.
Calls the unhandled delegate if the id has not been registered.
A compile time error will occur if the id is out of range.
---
```cpp
void call(const size_t id)
```
Calls the delegate associated with the id.
Calls the unhandled delegate if the id has not been registered or if is out of range.
## Example
See the example project in `examples\FunctionInterruptSimulation-Delegates`.

View File

@ -0,0 +1,220 @@
---
title: "delegate vs inplace_function"
weight: 1
---
## Efficiency and performance
### Invocation cost
**delegate**
One indirect call via stub function pointer; no allocation; forwards args directly; minimal overhead.
**inplace_function**
One indirect call via vtable invoke pointer; no allocation; overhead effectively the same as `delegate`.
### Copy / move cost
**delegate**
Trivial copy/move (object pointer + stub pointer).
**inplace_function**
Copies/moves the stored callable in an inline buffer; cost depends on callable traits; may run destructor on clear/reset.
### Size / footprint
**delegate**
Typically two pointers; very small, stable footprint.
**inplace_function**
Buffer + vtable pointer + object pointer; size depends on `Object_Size`/`Object_Alignment`.
### Ownership / lifetime
**delegate**
Non-owning for functors/lambdas; stores pointer to external callable; caller must ensure lifetime.
**inplace_function**
Owning; stores a copy/move of the callable inline (RAII).
### When to prefer
**delegate**
Minimal footprint, cheapest copies, free/member function binding, controlled lifetimes.
**inplace_function**
Value semantics, safe storage of lambdas with captures, uniform SBO wrapper.
## External API differences
### Template shape and size
`delegate<TSignature>`
`inplace_function<TSignature, Object_Size = 32, Object_Alignment = alignof(void*)>`
### Construction / binding
**delegate**
`create<FreeFn>()`
`create(T& obj, Method)` and `create(const T& obj, ConstMethod)` at run time
`create<T, Method, Instance>()`
Construct from functor/lambda by reference (non-owning); rvalues deleted to avoid dangling
`set()` mirrors `create()` for re-binding
**inplace_function**
Constructor from function pointer
Constructor from object + (const/non-const) member function (run time)
Constructor from functor/lambda by (const) reference; callable stored inline (owning)
`set()` mirrors constructors; also `set<FreeFn>()` and `set<T, Method, Instance>()` (compile time)
`create<FreeFn>()`, `create<T, Method, Instance>()` (compile time)
`make_inplace_function` helpers: `make_inplace_function(free_fn)`, `make_inplace_function(obj, &T::Method)` , `make_inplace_function<TSignature>(lambda)`.
### Equality and swap
**delegate**
`operator==`/`!=` compare stub and object; structural equality.
**inplace_function**
`operator==`/`!=` with `nullptr`; `swap()` provided; no general equality between two functions.
### Introspection helpers
**delegate**
`delegate_tag`
`is_delegate<T>`.
**inplace_function**
`is_inplace_function<T>`.
### Call helpers
`is_valid()`
`explicit bool`
`call_if(...)`
`call_or(alternative, ...)`
`call_or<FreeFn>(...)`.
### Functor storage semantics
**delegate**
Non-owning pointer to external functor/lambda.
**inplace_function**
Owns a copy/move in fixed buffer.
### Size control
**delegate**
Fixed small size (two pointers).
**inplace_function**
User-controlled via `Object_Size`/`Object_Alignment`; aliases `inplace_function_for` and `inplace_function_for_any` to compute required size/alignment.
### C++ language features
Classic non-type template parameter APIs; C++17 "auto" `make_*` helpers exist when enabled.
## Performance differences:
### Call overhead
**delegate**
One indirect call through a stub function pointer; minimal overhead.
**inplace_function**
One indirect call via `vtable->invoke(object, ...);` typically one extra pointer load; practically similar.
### Copy / move and lifetime
**delegate**
Trivial POD-like copy/move (object pointer + stub); no construction/destruction of target.
**inplace_function**
Copies/moves/destroys the stored callable in the inline buffer; cost depends on callable traits.
### Construction / binding cost
**delegate**
Binding free/member functions sets two pointers; binding a functor stores its address (non-owning).
**inplace_function**
Constructs a copy/move of the callable into the SBO buffer; more work up front.
### Memory footprint and cache locality
**delegate**
~2 pointers regardless of target; high container density and good cache locality.
**inplace_function**
Buffer + vtable pointer + object pointer; larger, size depends on Object_Size/Object_Alignment.
### Clear / reset cost
**delegate**
Clears pointers; no destructor invocation.
**inplace_function**
May run callable’s destructor; potentially non-trivial.
### Determinism / Real-time suitability
**delegate**
Very predictable and minimal costs at call/copy/reset; good for ISR/RT paths.
**inplace_function**
Deterministic at call; copy/move/reset depend on callable’s traits (still allocation-free).
## Rule of thumb
- Use `delegate` when:
You only bind free/member functions or non-owning functors and want the smallest handle with the cheapest copies.
- Use `inplace_function` when:
You must own captured state safely (value semantics) and still avoid the heap; accept slightly larger handle/copy costs for safety.
## Choose etl::delegate when
- You need the smallest possible callable handle (two pointers) for large arrays/vectors of callbacks.
- You must avoid any allocation, construction, destruction, or SBO buffer management in the callable wrapper.
- You bind free functions or member functions and the target object’s lifetime is externally guaranteed.
- You want trivial copy/move/equality semantics (copy two pointers; compare stub+object) for fast shuffling/lookup.
- You need deterministic, RT/ISR-safe behavior with no hidden destructors or move/destruct paths on clear/reset.
- You build static/ROM lookup tables of callbacks (compile-time create<Fn>(), create<T,Method,Instance>()).
- You store callbacks in fixed-capacity containers (etl::array/vector) and must minimize memory per element.
- You need ABI-stable, non-owning callback tokens passed across modules without copying callables.
- You already use etl::delegate_service or similar indexed dispatch; its API expects etl::delegate.
- You don't want to size/tune an inline buffer (Object_Size/Object_Alignment) per signature or platform.
### Typical scenarios
- Interrupt vectors, GPIO/event ISR callbacks, hard real-time control loops.
- Command/ID -> handler tables, message routing switchboards, state-machine transition actions.
- Global registries/singletons where handler objects are static or live for program lifetime.
- Shared tables of callbacks across DLLs/modules where owning captured state is undesirable.
### Why etl::delegate over etl::inplace_function in these cases
- Lower footprint: always two pointers versus user-sized SBO buffer + vtable pointer + object pointer.
- Lower copy/move cost: trivial POD-like copies; no callable copy/move/dtor required.
- Non-owning by design: avoids accidental copies of heavy callables; no lifetime surprises at clear/reset.
- Compile-time binding support: completely payload-free delegates for fixed targets (no storage touched).
- Equality: pointer-based equality lets you deduplicate/lookup handlers efficiently.
### Notes
- `etl::delegate` is non-owning; only choose it when the bound object outlives the delegate (rvalue lambdas are rejected by API).
- Prefer `etl::inplace_function`0 when you must own captured state (value semantics) or need to accept arbitrary lambdas safely.
## Choose etl::inplace_function when
- You need value semantics (own the callable) so lifetimes are safe without tracking external objects.
- You want to accept arbitrary lambdas with captures and store them inline using small-buffer optimization (no heap).
- You need a single uniform callable wrapper that erases the concrete type across modules/APIs.
- You plan to copy/move callbacks between threads/queues safely (callable is self-contained in the buffer).
- You must avoid dynamic allocation but still need to store captured state (tune Object_Size/Object_Alignment).
- You want compile-time or run-time binding to free functions, member functions, and functors in one type.
- You need reset/clear semantics that correctly destroy the stored callable (RAII).
- You prefer exceptions on misuse (invoking uninitialized) to surface bugs early.
### Typical scenarios
- Job systems, task queues, and executors that capture small state per task without heap churn.
- Pipelines and event buses that accept user-provided lambdas with captures.
- Configurable command tables where handlers carry lightweight configuration/state.
- Deferred work items, timeouts, and continuations stored in fixed-capacity containers.
- API boundaries returning/storing callbacks where the provider shouldn't manage the callee's lifetime.
### Why etl::inplace_function over etl::delegate in these cases
- Ownership: inplace_function owns the callable; no external lifetime management needed.
- Safety with captures: stores copies/moves of lambdas/functors; no dangling pointers to external objects.
- Uniform wrapper: a single type covers free/member/functor targets with the same call site and storage.
- No heap: SBO avoids allocations while still allowing captured state; predictable embedded-friendly footprint.
- Destruction: clear()/reset() run the callable's destructor when needed; no leaks or latent state.
### Notes
- Tune the buffer size/alignment to the largest expected callable; too-small buffers will `static_assert`.
- Copy/move cost depends on the callable; prefer lightweight captures for best performance.
- Invocation overhead is one indirect call through a vtable stub (similar to delegate).
- Use make_inplace_function helpers or create<> to bind targets; is_valid(), call_if(), and call_or() are available.
- If you only bind free/member functions and can guarantee lifetimes, etl::delegate is smaller and cheaper to copy.

406
docs/callbacks/delegate.md Normal file
View File

@ -0,0 +1,406 @@
---
title: "delegate"
---
{{< callout type="info">}}
Header: `delegate.h`
Since: `TBC`
Similar to: [std::function_ref](https://en.cppreference.com/w/cpp/utility/functional/function_ref.html)
{{< /callout >}}
`etl::delegate` is a type-safe, generic, and efficient delegate implementation. A delegate is essentially a type-safe function pointer.
It can be used to encapsulate a callable unit (like a function, a function pointer, member function, or a callable object like a functor or a lambda function) and call it later.
`etl::delegate` is similar in some ways to `std::function_ref` introduced with C++26.
The delegate functions may be defined at compile time and/or runtime, depending on the function type.
Most delegates can only be constructed via a `create` function, except lambdas and functors, which can be created by the delegate constructor.
This may be used to implement a platform abstraction layer that allows an embedded application to interface with multiple hardware platforms.
Here's a high-level overview of how `etl::delegate` works:
**Creation**
When you create a delegate, you specify the function signature that it should match. This is done using template parameters. For example, `etl::delegate<void(int)>` creates a delegate that can hold references to functions that take an integer as an argument and return `void`.
**Assignment**
You can assign a function to the delegate using the create method. The function you assign must match the delegate's function signature. For example, if you have a delegate of type `etl::delegate<void(int)>`, you could assign a function `void myFunction(int)` to it like this:
`auto myDelegate = etl::delegate<void(int)>::create<myFunction>();`
**Invocation**
Once a function has been assigned to the delegate, you can call that function through the delegate just like you would call a regular function. For example, if `myDelegate` is a delegate that holds a reference to `myFunction`, you could call myFunction through the delegate like this: `myDelegate(123);`
## Notes
`<=20.21.0`
This class only supports >=C++11.
---
`>=20.22.0`
This class is automatically selects C++03 or C++11 versions based on the value of `ETL_USING_CPP11`
The C++03 variant only supports delegates taking 0 or 1 parameters.
`etl::delegate` is non-owning. You cannot use lambdas that capture variables that will have gone out of scope when the delegate is called. This would result in dangling references. Lambdas are not copied; The delegate merely keeps pointers to lambdas. This also applies to functors.
---
`>=20.40.0`
Move constructors from lambdas or functors are disabled, thereby stopping a delegate being created from a temporary defined in a parameter.
`>=20.42.0`
`etl::delegate` is `noexcept`
---
`>=20.47.0`
A delegate can be created from a run-time global function pointer, or a non-capturing lambda.
---
`>=20.22.0`
*For C++03*
`etl::delegate<TReturn(void)>`
`etl::delegate<TReturn(TParam)>`
For the examples below, assume the following definitions.
```cpp
class Test
{
public:
int member_function(int);
static int member_static(int);
int operator()(int);
int operator()(int) const;
};
Test test;
int global(int);
auto lambda = [](int i){ return i; };
```
**Public types**
```cpp
return_type TReturn 20.43.0
argument_types etl::type_list<TParams...> 20.43.0
```
### Run time construction
**Lambdas**
```cpp
etl::delegate<int(int)> d(lambda);
etl::delegate<int(int)> d = lambda;
etl::delegate<int(int)> d = etl::delegate<int(int)>::create(lambda);
d.set(lambda);
```
**Functors**
```cpp
etl::delegate<int(int)> d(test);
etl::delegate<int(int)> d = test;
etl::delegate<int(int)> d = etl::delegate<int(int)>::create(test);
d.set<test>();
```
**Member functions**
```cpp
etl::delegate<int(int)> d = etl::delegate<int(int)>::create<Test, &Test::member_function>(test);
d.set<Test, &Test::member_function>(test);
d.set<Test, test, &Test::member_function>();
```
### Compile time construction
**Global functions**
```cpp
auto d = etl::delegate<int(int)>::create<global>();
```
**Member functions** (if the instance is known at compile time)
```cpp
auto d = etl::delegate<int(int)>::create<Test, test, &Test::member_function>(); // Deprecated
auto d = etl::delegate<int(int)>::create<Test, &Test::member_function, test>(); // New
```
**Functors** (if the instance is known at compile time)
```cpp
auto d = etl::delegate<int(int)>::create<Test, test>();
auto d = etl::delegate<int(int)>::create<const Test, test>();
```
Note: These are disabled for GCC <= v8.1 as it generates an 'Internal Compiler Error'.
**Static member functions**
```cpp
auto d = etl::delegate<int(int)>::create<Test::member_static>();
```
**Global functions or non-capturing lambdas**
*From 20.47.0*
```cpp
auto d = etl::delegate<int(int)>::create(+[](int a){ return a * 2; })
```
### Constexpr
Most delegates can be declared as `constexpr`. (C++11 and above)
```cpp
static Test test;
constexpr auto d = etl::delegate<int(int)>::create<Test, test, &Test::member_function>();
```
All create functions are `constexpr` under C++14.
All create functions are `[[nodiscard]]` under C++17.
### Calling the delegate
The delegate may be called as a function with the defined parameter signature.
```cpp
etl::delegate<int(int)> d;
int r = d(3);
```
## Types
`return_type` The return type of the callback.
`argument_types` An `etl::type_list` of the arguments.
## Constructors
```cpp
ETL_CONSTEXPR14 delegate() ETL_NOEXCEPT
```
**Description**
Constructs an uninitialised delegate.
---
```cpp
ETL_CONSTEXPR14 delegate(const delegate& other) ETL_NOEXCEPT
```
**Description**
Copy constructs a delegate.
---
```cpp
delegate(TReturn (*)(TArgs...) fp) ETL_NOEXCEPT
```
**Description**
Constructs from a run-time function pointer, or non-capturing lambda converted to a function pointer.
*From `20.47.0`*
## Creation
```cpp
template <TReturn (*Method)(TArgs...)>
ETL_NODISCARD
static ETL_CONSTEXPR14 delegate create() ETL_NOEXCEPT
```
**Description**
Create from a global function (Compile time).
**Returns**
A constructed delegate.
---
```cpp
ETL_NODISCARD
static delegate create(function_ptr fp) ETL_NOEXCEPT
```
**Description**
Create from a run-time function pointer.
*From `20.47.0`*
**Returns**
A constructed delegate.
---
```cpp
template <typename TLambda>
ETL_NODISCARD
static ETL_CONSTEXPR14 delegate create(TLambda& instance) ETL_NOEXCEPT
```
**Description**
Create from lambda or functor.
**Returns**
A constructed delegate.
## Calling the delegate
```cpp
ETL_CONSTEXPR14 TReturn operator()(TParams... args) const ETL_NOEXCEPT
```
**Description**
Calls the delegate.
`constexpr` from `20.42.1`
---
20.17.0
```cpp
ETL_CONSTEXPR14 bool call_if(TParams... args) const ETL_NOEXCEPT
```
**Description**
For delegates returning void.
Calls the delegate if valid.
Returns `true` if valid, otherwise `false`.
`constexpr` from `20.42.2`
---
```cpp
ETL_CONSTEXPR14 etl::optional<TReturn> call_if(TParams... args) const ETL_NOEXCEPT
```
**Description**
For delegates returning `TReturn`.
Calls the delegate if valid.
Returns a valid `etl::optional<TReturn>` containing the return value, if valid.
`constexpr` from `20.42.2`
---
20.17.0
```cpp
template <typename TAlternative>
ETL_CONSTEXPR14 TReturn call_or(TAlternative alternative, TParams... args) const ETL_NOEXCEPT
```
**Description**
Calls the delegate if valid, otherwise calls `alternative`.
`constexpr` from `20.42.2`
---
```cpp
template <TReturn(*Method)(TParams...)>
ETL_CONSTEXPR14 TReturn call_or(TParams... args) const ETL_NOEXCEPT
```
**Description**
Calls the delegate if valid, otherwise calls `Method`.
## Modifiers
```cpp
void clear() ETL_NOEXCEPT
```
**Description**
Sets the delegate back to the uninitialised state.
## Status
```cpp
ETL_NODISCARD ETL_CONSTEXPR14 bool is_valid() const ETL_NOEXCEPT
ETL_CONSTEXPR14 operator bool() const
```
**Description**
Returns true if the delegate has been initialised, otherwise `false`.
---
```cpp
ETL_CONSTEXPR14 operator =() ETL_NOEXCEPT
```
**Description**
Assigns from a delegate or lambda.
---
```cpp
ETL_CONSTEXPR14 operator ==() ETL_NOEXCEPT
ETL_CONSTEXPR14 operator !=() ETL_NOEXCEPT
```
**Description**
Compares delegates.
## Make a delegate
```cpp
make_delegate
```
**Description**
For C++17 and above.
`20.39.5`
---
```cpp
template <auto Function>
constexpr auto make_delegate() noexcept
```
**Description**
Make a delegate from a free function.
Returns `etl::delegate<function_type>::create<Function>()`
---
```cpp
template <typename TLambda>
constexpr auto make_delegate(TLambda& instance) noexcept
```
**Description**
Make a delegate from a functor or lambda function.
Returns `etl::delegate<function_type>(instance)`
---
```cpp
template <typename T, T& Instance>
constexpr auto make_delegate() noexcept
```
**Description**
Make a delegate from a functor, compile time.
Returns `etl::delegate<function_type>::create<T, Instance>()`
---
```cpp
template <typename T, auto Method, T& Instance>
constexpr auto make_delegate() noexcept
```
**Description**
Make a delegate from a member function at compile time.
Returns `etl::delegate<function_type>::create<T, Method, Instance>()`
---
```cpp
template <typename T, auto Method, const T& Instance>
constexpr auto make_delegate() noexcept
```
**Description**
Make a delegate from a const member function at compile time.
Returns `etl::delegate<function_type>::create<T, Method, Instance>()`
---
```cpp
template <typename T, auto Method>
constexpr auto make_delegate(T& instance) noexcept
```
**Description**
Make a delegate from a member function at run time.
Returns `etl::delegate<function_type>::create<T, Method>(instance)`
---
```cpp
template <typename T, auto Method>
constexpr auto make_delegate(const T& instance) noexcept
```
**Description**
Make a delegate from a member function at run time.
Returns `etl::delegate<function_type>::create<T, Method>(instance)`

View File

@ -0,0 +1,115 @@
---
title: "delegate_observable"
---
{{< callout type="info">}}
Header: `delegate_observable.h`
Since: `TBC`
{{< /callout >}}
`etl::delegate_observable` is a variation on the observer pattern idea, but using delegates as the callback mechanism.
```cpp
template <typename TNotification, size_t Max_Observers>
class delegate_observable
```
`TNotification` is the notification type.
`Max_Observers` is the maximum number of observers that can be handled.
## Template deduction guide
```cpp
template <typename TNotification, typename... TDelegates>
delegate_observable(TNotification, TDelegates...)
-> delegate_observable<TNotification, sizeof...(TDelegates)>;
```
**Example**
```cpp
etl::delegate<void(int)> delegate1;
etl::delegate<void(int)> delegate2;
etl::delegate_observable observable(int{}, delegate1, delegate2);
```
## Public types
| Type | Description |
| ------------------- | ------------------------------------------- |
| `delegate_type` | The type of delegate used in this observer. |
| `size_type` | The type used internally for sizes. |
| `notification_type` | The type of the notification. |
## Construction
```cpp
ETL_CONSTEXPR14 delegate_observable()
```
**Description**
Default constructor.
---
```cpp
template <typename... TDelegate>
ETL_CONSTEXPR14 delegate_observable(TDelegate&&... delegates)
```
**Description**
Construct from a collection of observers.
---
```cpp
template <typename... TDelegate>
ETL_CONSTEXPR14 delegate_observable(notification_type, TDelegate&&... delegates)
```
**Description**
Construct from notification type and a list of observers.
Variant for template deduction guide.
The notification value is ignored. It is here to allow deduction of the notification type for the template deduction guide.
## Modifiers
```cpp
ETL_CONSTEXPR14 bool add_observer(delegate_type observer)
```
**Description**
Add an observer to the list.
**Return**
`true` if the observer was removed, `false` if not.
---
```cpp
ETL_CONSTEXPR14 bool remove_observer(const delegate_type& observer)
```
**Description**
Remove a particular observer from the list.
**Return**
`true if the observer was removed, false if not.
---
```cpp
ETL_CONSTEXPR14 void clear_observers()
```
**Description**
Clear all observers.
## Status
```cpp
ETL_CONSTEXPR14 size_type number_of_observers() const
```
**Return**
The number of observers.
## Notofication
```cpp
ETL_CONSTEXPR14 void notify_observers(notification_type n) const
```
**Description**
Notify all of the observers, sending them the notification.

332
docs/callbacks/function.md Normal file
View File

@ -0,0 +1,332 @@
---
title: "function"
---
{{< callout type="warning">}}
Deprecated: Please use the more versatile `etl::delegate` or `etl::inplace_function` classes instead.
{{< /callout >}}
{{< callout type="info">}}
Header: `function.h`
Since: `TBC`
{{< /callout >}}
A set of wrapper templates to allow a member or static function to be called without the caller having to know the specific details of the callee apart from the parameter type. The templates allow the called function to be abstracted.
This may be used to implement a platform abstraction layer that allows an embedded application to interface with multiple hardware platforms.
| Template | Description |
| ----------------- | ------------------------------------------------------------------------- |
| etl::function | Callbacks to free or member functions taking zero or one parameter.<br/>Function pointer at runtime. |
| etl::function_fv | Callback to a free function taking no parameters. (Functiion Void).<br/>Function pointer at compile time. |
| etl::function_fp | Callback to a free function taking one parameter. (Function Parameter).<br/> Function pointer at compile time.
| etl::function_mv | Callback to a member function taking no parameters. (Member Void).<br/>Function pointer at compile time. |
| etl::function_imv | Callback to a member function taking no parameters. (Instance Member Void ).<br/>Instance reference and function pointer at compile time. |
| etl::function_mp | Callback to a member function taking one parameter. (Member Parameter).<br/>Function pointer at compile time.|
| etl::function_imp | Callback to a member function taking one parameter. (Instance Member Parameter).<br/>Instance reference and function pointer at compile time.|
*Instances of any of these types may be passed as pointers or references to etl::ifunction.*
## Interface classes.
```cpp
template <typename TParameter>
class ifunction
```
**Description**
Interface class for a function taking one parameter.
---
```cpp
template <>
class ifunction<void>
```
**Description**
Interface class for a function taking no parameters.
**All of the following classes are derived from the above interface classes.**
## Function address at run time.
The functions are called indirectly through an internal pointer.
```cpp
template <typename TObject,
typename TParameter>
class function : public ifunction<TParameter>
```
**Description**
Class for a member function taking one parameter.
---
```cpp
template <typename TObject>
class function<TObject, void> : public ifunction<void>
```
**Description**
Class for a member function taking no parameters.
```cpp
template <typename TParameter>
class function<void, TParameter> : public ifunction<TParameter>
```
**Description**
Class for a free function taking one parameter.
---
```cpp
template <>
class function<void, void> : public ifunction<void>
```
**Description**
Class for a free function taking no parameters.
## Function address at compile time.
These will be more efficient than the previous definitions, as the one level of indirection is eliminated.
```cpp
template <typename TObject,
void (TObject::*Function)()>
class function_mv : public ifunction<void>
```
**Description**
Class for a member function taking no parameters.
---
```cpp
template <typename TObject,
TObject& Instance,
void (TObject::*Function)()>
class function_imv : public ifunction<void>
```
**Description**
Class for a member function taking no parameters.
---
```cpp
template <typename TObject,
typename TParameter,
void (TObject::*Function)(TParameter)>
class function_mp : public ifunction<TParameter>
```
**Description**
Class for a member function taking one parameter.
---
```cpp
template <typename TObject,
typename TParameter,
TObject& Instance,
void (TObject::*Function)(TParameter)>
class function_imp : public ifunction<TParameter>
```
**Description**
Class for a member function taking one parameter.
---
```cpp
template <void (*Function)()>
class function_fv : public ifunction<void>
```
**Description**
Class for a free function taking no parameters.
---
```cpp
template <typename TParameter,
void (*Function)()>
class function_fp : public ifunction<TParameter>
```
**Description**
Class for a free function taking one parameter.
## Example
```cpp
etl::function
```
These templates are designed to enable easy creation of callbacks to global, static and class member functions without the caller having to know which type actually it is.
One use that is applicable to embedded platforms is to use them connect interrupt vectors to class member handling functions. Particularly useful when the code is applicable to multiple targets devices.
The template is designed in such a way that the caller does not need to be aware of the type of the callee.
The caller declares an instance of `etl::function` or one of its variants. The caller defines a pointer or reference to an `etl::ifunction`. This pointer or reference will be initialised with the instance defined in the caller.
**Example**
The interrupt vector table contains entries for three timer timeouts and two uart character rx handlers. These are vectored to normal static functions.
```cpp
void Timer1TimeoutInterrupt();
void Timer2TimeoutInterrupt();
void Timer3TimeoutInterrupt();
void Uart1RxInterrupt();
void Uart2RxInterrupt();
```
The timer timeout interrupts are handled by an instance of the class `Timer` and the free function `FreeTimerInterruptHandler`. The UART Rx interrupts are handled by instances of the class `Uart`.
`Timer1` interrupts call the member function of an instance of `Timer`.
`Timer2` interrupts call the static member function of `Timer`.
`Timer3` interrupts call the free function `FreeTimerInterruptHandler`.
`UART1` interrupts call the member function of instance 1 of `Uart`.
`UART1` interrupts call the member function of instance 2 of `Uart`.
```cpp
#include <iostream>
#include <iomanip>
#include "function.h"
//********************************
// Fake UART Rx register.
//********************************
char get_char()
{
static char c = 'A';
return c++;
}
//********************************
// Interrupt vectors & callbacks.
//********************************
// Callback interfaces.
// Note that they do not require any knowledge about the callee apart from the parameter type.
etl::ifunction<void>* timer1_callback; // A pointer to a callback taking no parameters.
etl::ifunction<void>* timer2_callback; // A pointer to a callback taking no parameters.
etl::ifunction<void>* timer3_callback; // A pointer to a callback taking no parameters.
etl::ifunction<char>* uart1_rx_callback; // A pointer to a callback taking a char parameter.
etl::ifunction<char>* uart2_rx_callback; // A pointer to a callback taking a char parameter.
extern "C"
{
// Function called from the timer1 interrupt vector.
void Timer1Interrupt()
{
(*timer1_callback)();
}
// Function called from the timer2 interrupt vector.
void Timer2Interrupt()
{
(*timer2_callback)();
}
// Function called from the timer3 interrupt vector.
void Timer3Interrupt()
{
(*timer3_callback)();
}
// Function called from the UART1 rx interrupt vector.
void Uart1RxInterrupt()
{
(*uart1_rx_callback)(get_char());
}
// Function called from the UART2 rx interrupt vector.
void Uart2RxInterrupt()
{
(*uart2_rx_callback)(get_char());
}
}
//********************************
// Timer driver.
//********************************
class Timer
{
public:
// Constructor.
Timer()
{
}
// Handler for interrupts from the timer.
void MemberTimerInterruptHandler()
{
std::cout << "Timer interrupt (member)\n";
}
// Static handler for interrupts from the timer.
static void StaticTimerInterruptHandler()
{
std::cout << "Timer interrupt (static)\n";
}
};
//********************************
// Free function timer driver.
//********************************
void FreeTimerInterruptHandler()
{
std::cout << "Timer interrupt (free)\n";
}
etl::function_fv<FreeTimerInterruptHandler> free_callback;
//********************************
// UART driver.
//********************************
class Uart
{
public:
// Constructor.
Uart(int port_id)
: port_id(port_id)
{
}
// Handler for rx interrupts from the UART.
void RxInterruptHandler(char c)
{
std::cout << "UART" << port_id << " Rx char interrupt : Received '" << c << "'\n";
}
int port_id;
};
// Declare the driver instances.
Timer timer;
Uart uart1(0);
Uart uart2(1);
etl::function_imv<Timer, timer, &Timer::MemberTimerInterruptHandler> timer_member_callback;
etl::function_fv<&Timer::StaticTimerInterruptHandler> timer_static_callback;
etl::function_imp<Uart, char, uart1, &Uart::RxInterruptHandler> uart1_callback;
etl::function_imp<Uart, char, uart2, &Uart::RxInterruptHandler> uart2_callback;
//********************************
// Test it out.
//********************************
int main()
{
// Setup the callbacks.
timer1_callback = &timer_member_callback;
timer2_callback = &timer_static_callback;
timer3_callback = &free_callback;
uart1_rx_callback = &uart1_callback;
uart2_rx_callback = &uart2_callback;
// Simulate the interrupts.
Timer1Interrupt();
Timer2Interrupt();
Timer3Interrupt();
Uart1RxInterrupt();
Uart2RxInterrupt();
return 0;
}
```

View File

@ -0,0 +1,414 @@
---
title: "inplace_function"
weight: 1
---
{{< callout type="info">}}
Header: `inplace_function.h`
From: `20.45.0`
Similar to: [std::function](https://en.cppreference.com/w/cpp/utility/functional/function.html)
{{< /callout >}}
A small, in-place function wrapper that stores callable objects inside a fixed-size buffer (no dynamic allocation). It supports free functions, member functions, functors, and lambdas, with both runtime and compile-time bindings.
```cpp
template <typename TSignature,
size_t Object_Size = ETL_DEFAULT_INPLACE_FUNCTION_SIZE,
size_t Object_Alignment = ETL_DEFAULT_INPLACE_FUNCTION_ALIGNMENT>
class inplace_function;
```
The defaults are defined as follows:-
```cpp
#if !defined(ETL_DEFAULT_INPLACE_FUNCTION_SIZE)
#define ETL_DEFAULT_INPLACE_FUNCTION_SIZE 32
#endif
```
```cpp
#if !defined(ETL_DEFAULT_INPLACE_FUNCTION_ALIGNMENT)
#define ETL_DEFAULT_INPLACE_FUNCTION_ALIGNMENT alignof(void*)
#endif
```
Set your own definitions if you require different defaults.
## Template Parameters
```cpp
TSignature
```
**Description**
The function signature. e.g. `int(char, float)`
---
```cpp
Object_Size
```
**Description**
Size of the internal storage buffer.
Defaults to `ETL_DEFAULT_INPLACE_FUNCTION_SIZE`.
---
```cpp
Object_Alignment
```
**Description**
Alignment of the internal storage buffer.
Defaults to `ETL_DEFAULT_INPLACE_FUNCTION_ALIGNMENT`.
## Exceptions
```cpp
etl::inplace_function_exception
```
**Description**
Base exception.
---
```cpp
etl::inplace_function_uninitialized
```
**Description**
Thrown (via `ETL_ASSERT`) when invoked without a target.
## Member Types
```cpp
function_type
```
**Description**
---
```cpp
return_type
```
**Description**
---
```cpp
argument_types
```
**Description**
## Constructors
**Description**
Default constructor.
**Description**
Copy/move constructors.
**Description**
Construction from a free function pointer.
**Description**
Construction from an object + member function pointer (const or non-const).
**Description**
Construction from a lambda/functor (const or non-const).
## Assignment
**Description**
Copy/move assignment.
---
**Description**
Assignment from nullptr clears the target.
---
**Description**
Assignment from function pointer.
---
**Description**
Assignment from lambda/functor.
## Invocation
```cpp
operator()
```
**Description**
Invokes the bound callable and asserts if uninitialised.
**Parameters**
**Returns**
---
```cpp
call_if(...)
```
**Description**
Calls the delegate function, if valid.
Indicates success in the return type.
**Parameters**
`TArgs...`
**Returns**
For `void` return `bool` indicating whether it executed.
For non-void returns `etl::optional<TReturn>`.
---
```cpp
call_or(...)
```
**Description**
Invokes the target or a fallback callable.
**Parameters**
**Returns**
## Observers
```cpp
bool is_valid() const
```
**Returns**
`true` if there is a valid callable.
---
```cpp
explicit operator bool() const
```
**Description**
**Parameters**
**Returns**
The result of `is_valid()`
## Modifiers
```cpp
void clear()
```
**Description**
Clears any stored callable.
**Parameters**
None
**Returns**
`void`
---
```cpp
void swap(inplace_function& other)
```
**Description**
Swaps with another inplace_function.
**Parameters**
None
**Returns**
'void`
## Storage Introspection
```cpp
static constexpr size_t size()
```
**Description**
Interogates the internal storage size.
**Parameters**
None
**Returns**
The size of the internal storage.
---
```cpp
static constexpr size_t alignment()
```
**Description**
Interogates the internal storage alignment.
**Parameters**
None
**Returns**
The alignment of the internal storage.
## Compile-Time Binding (No Payload)
### Free function
```cpp
template <TReturn(*Function)(TArgs...)>
void set()
```
**Description**
Sets the callable to `Function`.
---
```cpp
template <TReturn(*Function)(TArgs...)>
inplace_function<TReturn(TArgs...),
Object_Size,
Object_Alignment> create()
```
**Description**
Creates an `etl::inplace_function` using `Function`.
---
### Member function + instance (external linkage)
```cpp
template <typename TObject, TReturn(TObject::*Method)(TArgs...), TObject& Instance>
set<TObject, &TMethod, Instance>()
```
**Description**
Sets the callable to the member function `Method` for the object `Instance`.
---
```cpp
create<TObject, &TMethod, Instance>()
```
**Description**
**Parameters**
**Returns**
---
### Callable object + instance (operator())
```cpp
set<T, Instance>()
```
**Description**
**Parameters**
**Returns**
---
```cpp
create<T, Instance>()
```
**Description**
**Parameters**
**Returns**
## Helper Aliases
```cpp
etl::inplace_function_for<TSignature, TStorage>
```
**Description**
**Parameters**
**Returns**
---
```cpp
etl::inplace_function_for_any<TSignature, T0, ...>
```
**Description**
**Parameters**
**Returns**
## Helper Factories
```cpp
make_inplace_function(function_ptr)
```
**Description**
**Parameters**
**Returns**
```cpp
make_inplace_function(obj, &Type::Method)
```
**Description**
**Parameters**
**Returns**
```cpp
make_inplace_function(lambda_or_functor)
```
**Description**
```cpp
make_inplace_function<TSignature>(function_like)
```
**Description**
**Parameters**
**Returns**
C++17-only overloads also exist for compile-time binding.
## Example
```cpp
#include "etl/inplace_function.h"
int add(int a, int b) { return a + b; }
struct Accumulator
{
int base = 0;
int add_to(int v) { return base + v; }
};
void example()
{
etl::inplace_function<int(int, int)> f(add);
int sum = f(1, 2);
Accumulator acc{ 10 };
etl::inplace_function<int(int)> g(&Accumulator::add_to, acc);
int result = g(5);
}
```
## Notes
If the callable object is larger than `Object_Size` or requires stricter alignment than `Object_Alignment`, compilation fails with a `static_assert`.
`operator()` asserts when called without a target; use `call_if` or `call_or` to avoid this.
Prefer `inplace_function_for`, `inplace_function_for_any` or `make_inplace_function` to deduce storage sizes safely.

327
docs/callbacks/signal.md Normal file
View File

@ -0,0 +1,327 @@
---
title: "signal"
---
{{< callout type="info">}}
Header: `signal.h`
From: `20.44.0`
{{< /callout >}}
A class that implements simple signal/slot framework.
Uses `etl::delegate` as the default slot type, though other types may be used.
```cpp
template <typename TFunction, size_t Size, typename TSlot = etl::delegate<TFunction>>
class signal
```
`TFunction` The callback function signature.
`Size` The maximum numbr of slots for the signal.
`TSlot` The callback slot type. Default = `etl::delegate<TFunction>`
## Types
`slot_type` Defined as the slot type.
`size_type` The size type used internally.
`span_type` The span type used in the connect API.
## Constructors
```cpp
template <typename... TSlots>
ETL_CONSTEXPR14 explicit signal(TSlots&&... slots) ETL_NOEXCEPT
```
Construct the signal from a variadic list of slots.
Can be used as a `constexpr` constructor.
Static asserts if any of the slots are not `slot_type`.
Static asserts if the number of slots exceeds capacity.
## Connect
```cpp
bool connect(const slot_type& slot)
```
Connects the slot, if not already connected and returns `true`.
If the signal is full, asserts `etl::signal_full` and returns `false`.
---
```cpp
bool connect(std::initializer_list<const slot_type> slots)
```
Connects all of the slots and returns `true`.
If the number of slots exceeds the signal's max size, asserts an `etl::signal_full` and returns `false`.
Enabled if `ETL_HAS_INITIALIZER_LIST` and `ETL_USING_CPP17` are defined as `1`.
---
```cpp
bool connect(const span_type slots)
```
Connects all of the slots and returns `true`.
If the number of slots exceeds the signal's max size, asserts an `etl::signal_full` and returns `false`.
## Disconnect
```cpp
void disconnect(const slot_type& slot) ETL_NOEXCEPT
```
Disconnects slot from the signal.
If the signal does not contain the slot there is no error.
---
```cpp
void disconnect(std::initializer_list<const slot_type> slots) ETL_NOEXCEPT
```
Disconnects all of the slots from the signal.
If the signal does not contain a particular slot, there is no error.
Enabled if `ETL_HAS_INITIALIZER_LIST` and `ETL_USING_CPP17` are defined as `1`.
---
```cpp
void disconnect(const span_type slots) ETL_NOEXCEPT
```
Disconnects all of the slots from the signal.
If the signal does not contain a particular slot, there is no error.
```cpp
void disconnect_all() ETL_NOEXCEPT
```
Disconnects all slots from the signal.
## Status
```cpp
ETL_CONSTEXPR14 bool connected(const slot_type& slot) const ETL_NOEXCEPT
```
Checks if a slot is connected to the signal.
---
```cpp
ETL_CONSTEXPR14 bool empty() const ETL_NOEXCEPT
```
Return `true` if the signal has no slots connected.
---
```cpp
ETL_CONSTEXPR14 bool full() const ETL_NOEXCEPT
```
Return `true` if the signal has the maximum number of slots connected.
---
```cpp
ETL_CONSTEXPR14 size_type max_size() const ETL_NOEXCEPT
```
Returns the total number of slots that can be connected.
---
```cpp
ETL_CONSTEXPR14 size_type size() const ETL_NOEXCEPT
```
Returns the total slots currently connected.
---
```cpp
ETL_CONSTEXPR14 size_type available() const ETL_NOEXCEPT
```
Returns the total empty slots available.
## Call
```cpp
template <typename... TArgs>
void operator()(TArgs&&... args) const ETL_NOEXCEPT
```
Function operator that calls each slot with the supplied parameters.
## Errors
```cpp
etl::signal_full
```
Indicates that an attempt to add a slot to a full signal occurred.
Inherits from `etl::signal_exception`.
## Examples
```cpp
constexpr size_t MaxSlots = 3;
using callback_type = void(int a, int b);
using signal_type = etl::signal<callback_type, MaxSlots>;
using slot_type = signal_type::slot_type;
using span_type = signal_type::span_type;
using not_slot_type = etl::delegate<void(int)>;
```
**Defining the slot functions**
```cpp
void Function1(int a, int b)
{
std::cout << "Function1: " << a << "," << b << "\n";
}
void Function2(int a, int b)
{
std::cout << "Function2: " << a << "," << b << "\n";
}
void Function3(int a, int b)
{
std::cout << "Function3: " << a << "," << b << "\n";
}
0
void Function4(int a, int b)
{
std::cout << "Function4: " << a << "," << b << "\n";
}
void Function5(int a)
{
std::cout << "Function5: " << a << "\n";
}
```
**Creating the slots**
```cpp
constexpr slot_type MakeSlot1() noexcept
{
return slot_type::create<Function1>();
}
constexpr slot_type MakeSlot2() noexcept
{
return slot_type::create<Function2>();
}
constexpr slot_type MakeSlot3() noexcept
{
return slot_type::create<Function3>();
}
constexpr slot_type MakeSlot4() noexcept
{
return slot_type::create<Function4>();
}
constexpr not_slot_type MakeSlot5() noexcept
{
return not_slot_type::create<Function5>();
}
```
**Define the signals as `constexpr`**
```cpp
// Define the signal and connect as constexpr
constexpr signal_type({ MakeSlot1(), MakeSlot2(), MakeSlot3() });
// Define the signal and connect as constexpr.
// Static assert "Number of slots exceeds capacity"
constexpr signal_type({ MakeSlot1(), MakeSlot2(), MakeSlot3(), MakeSlot4() });
// Define the signal and connect as constexpr.
// Static assert "All slots must be slot_type"
constexpr signal_type({ MakeSlot1(), MakeSlot2(), MakeSlot5() });
```
**Defining the signal at runtime**
```cpp
// Define the signal.
signal_type signal;
// Connect one at a time.
signal.connect(MakeSlot1());
signal.connect(MakeSlot2());
signal.connect(MakeSlot3());
// Connect using initializer_list.
signal.connect({ MakeSlot1(), MakeSlot2(), MakeSlot3() });
// Connect using span.
const slot_type slot_list[] = { MakeSlot1(), MakeSlot2(), MakeSlot3() };
signal.connect(slot_list);
```
**Checking the status**
```cpp
// Define the signal.
signal_type signal;
signal.max_size() // Returns 3
signal.size() // Returns 0
signal.available() // Returns 3
signal.empty(); // Returns true
signal.full(); // Returns false
signal.connected(MakeSlot1()) // Returns false
signal.connected(MakeSlot2()) // Returns false
signal.connected(MakeSlot3()) // Returns false
signal.connect(MakeSlot1()); // Returns true
signal.max_size() // Returns 3
signal.size() // Returns 1
signal.available() // Returns 2
signal.empty(); // Returns false
signal.full(); // Returns false
signal.connected(MakeSlot1()) // Returns true
signal.connected(MakeSlot2()) // Returns false
signal.connected(MakeSlot3()) // Returns false
signal.connect(MakeSlot1()); // Already connected. Returns true
signal.max_size() // Returns 3
signal.size() // Returns 1
signal.available() // Returns 2
signal.empty(); // Returns false
signal.full(); // Returns false
signal.connected(MakeSlot1()) // Returns true
signal.connected(MakeSlot2()) // Returns false
signal.connected(MakeSlot3()) // Returns false
signal.connect(MakeSlot2()); // Returns true
signal.max_size() // Returns 3
signal.size() // Returns 2
signal.available() // Returns 1
signal.empty(); // Returns false
signal.full(); // Returns false
signal.connected(MakeSlot1()) // Returns true
signal.connected(MakeSlot2()) // Returns true
signal.connected(MakeSlot3()) // Returns false
signal.connect(MakeSlot3()); // Returns true
signal.max_size() // Returns 3
signal.size() // Returns 3
signal.available() // Returns 0
signal.empty(); // Returns false
signal.full(); // Returns true
signal.connected(MakeSlot1()) // Returns true
signal.connected(MakeSlot2()) // Returns true
signal.connected(MakeSlot3()) // Returns true
signal.connect(MakeSlot4()); // ETL_ASSERT etl::signal_full. Returns false
```
**Calling the signal**
```cpp
signal_type signal({ MakeSlot1(), MakeSlot2(), MakeSlot3() });
signal(1, 2); // Call all of the slots with the parameters 1 & 2
```
**Output**
```
Function1: 1,2
Function2: 1,2
Function3: 1,2
```

12
docs/chrono/_index.md Normal file
View File

@ -0,0 +1,12 @@
---
title: "Chrono"
weight: 100
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono](https://en.cppreference.com/w/cpp/chrono.html)
{{< /callout >}}
An implementation of C++11's date and time library.

View File

@ -0,0 +1,38 @@
---
title: "Chrono literals"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::literals::chrono_literals](https://en.cppreference.com/w/cpp/chrono.html#Literals)
{{< /callout >}}
The ETL Chrono literals are define slightly differently from the STL in that they are *user* defined, as opposed to *language* defined.
**Example**
For STL, the literal to define year `2025` would be `2025y`.
For ETL, the literal is `2025_y`.
By default, the ETL uses the designations of the STL.
As this may clash with other user defined literals, the ETL allows more verbose forms to be used, by defining the macro `ETL_USE_VERBOSE_CHRONO_LITERALS`.
If enabled, the example of `2025_y` would be written as `2025_year`.
| Duration type | STL like | Verbose |
| --------------------------- | ---------- | ------------------- |
| `etl::chrono::year` | `2025_y` | `2025_year` |
| `etl::chrono::day` | `10_d` | `10_day` |
| `etl::chrono::hours` | `14_h` | `14_hours` |
| `etl::chrono::minutes` | `30_min` | `30_minutes` |
| `etl::chrono::seconds` | `45_s` | `45_seconds` |
| `etl::chrono::milliseconds` | `500_ms` | `500_milliseconds` |
| `etl::chrono::microseconds` | `500_us` | `500_microseconds` |
| `etl::chrono::nanoseconds` | `500_ns` | `500_nanoseconds` |
Chrono literals may by accessed by using one of the following namespaces.
```cpp
using namespace etl::chrono;
using namespace etl::literals;
using namespace etl::chrono_literals;
```

123
docs/chrono/clocks.md Normal file
View File

@ -0,0 +1,123 @@
---
title: "Clocks"
---
## Macros
Default macro definitions.
Define these in `etl_profile.h` to set your own duration types for the clocks.
| Macro | Definition |
| -------------------------------------------- | -------------------------- |
| `ETL_CHRONO_SYSTEM_CLOCK_DURATION` | `etl::chrono::nanoseconds` |
| `ETL_CHRONO_SYSTEM_CLOCK_IS_STEADY` | `true` |
| `ETL_CHRONO_HIGH_RESOLUTION_CLOCK_DURATION` | `etl::chrono::nanoseconds` |
| `ETL_CHRONO_HIGH_RESOLUTION_CLOCK_IS_STEADY` | `true` |
| `ETL_CHRONO_STEADY_CLOCK_DURATION` | `etl::chrono::nanoseconds` |
## Platform clock access
Declarations of the functions that must be defined to interface the clocks with the underlying platform.
```cpp
extern "C" ETL_CHRONO_SYSTEM_CLOCK_DURATION::rep etl_get_system_clock();
extern "C" ETL_CHRONO_HIGH_RESOLUTION_CLOCK_DURATION::rep etl_get_high_resolution_clock();
extern "C" ETL_CHRONO_STEADY_CLOCK_DURATION::rep etl_get_steady_clock();
```
These functions must return the current count of the underlying clock. The value is in terms of the
clock duration defined for that clock.
**Example**
If the `system_clock` duration is set to `etl::chrono::nanoseconds`, then a return value of `1000` represents `1000ns`.
## system_clock
```cpp
class system_clock
```
### Member types
```cpp
using duration = ETL_CHRONO_SYSTEM_CLOCK_DURATION
using rep = duration::rep
using period = duration::period
using time_point = time_point<system_clock, duration>
```
### Member functions
```cpp
static time_point now() ETL_NOEXCEPT
static time_t to_time_t(const time_point& t) ETL_NOEXCEPT
static time_point from_time_t(time_t t) ETL_NOEXCEPT
```
## high_resolution_clock
```cpp
class high_resolution_clock
```
### Member types
```cpp
using duration = ETL_CHRONO_HIGH_RESOLUTION_CLOCK_DURATION
using rep = duration::rep
using period = duration::period
using time_point = time_point<high_resolution_clock, duration>
```
### Member functions
```cpp
static time_point now() ETL_NOEXCEPT
```
## steady_clock
```cpp
class steady_clock
```
### Member types
```cpp
using duration = ETL_CHRONO_STEADY_CLOCK_DURATION
using rep = duration::rep
using period = duration::period
using time_point = time_point<steady_clock, duration>
```
### Member functions
```cpp
static time_point now() ETL_NOEXCEPT
```
## system_time
```cpp
template <typename Duration>
using sys_time = etl::chrono::time_point<etl::chrono::system_clock, Duration>
using sys_seconds = sys_time<etl::chrono::seconds>
using sys_days = sys_time<etl::chrono::days>
```
## local_time
```cpp
struct local_t
```
```cpp
template <typename TDuration>
using local_time = etl::chrono::time_point<etl::chrono::local_t, TDuration>
using local_seconds = local_time<etl::chrono::seconds>
using local_days = local_time<etl::chrono::days>
```
## clock_cast
Cast a time point from one clock to another.
This implementation assumes all clock epochs are the same.
```cpp
template <typename TToClock,
typename TFromClock,
typename TFromDuration>
ETL_CONSTEXPR14 etl::chrono::time_point<TToClock,
typename TToClock::duration>
clock_cast(const etl::chrono::time_point<TFromClock, TFromDuration>& from_time_point) ETL_NOEXCEPT
```

317
docs/chrono/day.md Normal file
View File

@ -0,0 +1,317 @@
---
title: "day"
---
{{< callout type="info">}}
Header: `chrono.h`
Since: `TBC`
Similar to: [std::chrono::day](https://en.cppreference.com/w/cpp/chrono/day.html)
{{< /callout >}}
A class representing a day.
```cpp
class day
```
## Typesdefs
rep The internal representation.
## Construction
```cpp
ETL_CONSTEXPR
day()
ETL_NOEXCEPT
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR
explicit day(unsigned value)
ETL_NOEXCEPT
```
**Description**
Construct from unsigned.
---
```cpp
ETL_CONSTEXPR14
day(const etl::chrono::day& other)
ETL_NOEXCEPT
```
**Description**
Copy constructor.
## Tests
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
bool ok() const
ETL_NOEXCEPT
```
**Return**
`true` if the day is within the valid range.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
int compare(const etl::chrono::day& other) const
ETL_NOEXCEPT
```
**Description**
Compare `day` with another.
if `day < other`, returns `-1`
else if `day > other`, returns `1`
else returns `0`
## Assignment
```cpp
ETL_CONSTEXPR14
etl::chrono::day& operator =(const etl::chrono::day& rhs)
ETL_NOEXCEPT
```
**Description**
Assignment operator
## Increment/decrement
```cpp
ETL_CONSTEXPR14
etl::chrono::day& operator ++()
ETL_NOEXCEPT
```
**Description**
Pre-increment operator.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::day operator ++(int)
ETL_NOEXCEPT
```
**Description**
Post-increment operator.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::day& operator --()
ETL_NOEXCEPT
```
**Description**
Pre-decrement operator.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::day operator --(int)
ETL_NOEXCEPT
```
**Description**
Post-decrement operator.
## Mathematical operators
```cpp
ETL_CONSTEXPR14
etl::chrono::day& operator +=(const etl::chrono::days& ms)
ETL_NOEXCEPT
```
**Description**
Plus-equals operator adding etl::chrono::days.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::day& operator -=(const etl::chrono::days& ms)
ETL_NOEXCEPT
```
**Description**
Minus-equals operator subtracting `etl::chrono::days`.
## Conversion
```cpp
ETL_CONSTEXPR14
operator unsigned() const
ETL_NOEXCEPT
```
**Description**
Conversion operator to unsigned int.
## Non-member mathematical operators
```cpp
ETL_CONSTEXPR14
etl::chrono::day operator +(const etl::chrono::day& m,
const etl::chrono::days& ms)
ETL_NOEXCEPT
```
**Description**
Add `etl::chrono::days` to `etl::chrono::day`.
**Return**
`etl::chrono::day.`
---
```cpp
ETL_CONSTEXPR14
etl::chrono::day operator +(const etl::chrono::days& ms,
const etl::chrono::day& m)
ETL_NOEXCEPT
```
**Description**
Add `etl::chrono::day` to `etl::chrono::days`.
**Return**
`etl::chrono::day`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::day operator -(const etl::chrono::day& m,
const etl::chrono::days& ms)
ETL_NOEXCEPT
```
**Description**
Subtract `etl::chrono::days` from `etl::chrono::day`.
**Return**
`etl::chrono::day`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::day operator -(const etl::chrono::days& ms,
const etl::chrono::day& m)
ETL_NOEXCEPT
```
**Description**
Subtract `etl::chrono::day` from `etl::chrono::days`.
**Return**
`etl::chrono::days`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::days operator -(const etl::chrono::day& m1,
const etl::chrono::day& m2) ETL_NOEXCEPT
```
**Description**
Subtract `etl::chrono::day` from `etl::chrono::day`.
**Return**
`etl::chrono::days`.
## Non-member comparison operators
```cpp
ETL_CONSTEXPR14
bool operator ==(const etl::chrono::day& m1,
const etl::chrono::day& m2)
ETL_NOEXCEPT
```
**Description**
Equality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator !=(const etl::chrono::day& m1,
const etl::chrono::day& m2)
ETL_NOEXCEPT
```
**Description**
Inequality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <(const etl::chrono::day& m1,
const etl::chrono::day& m2)
ETL_NOEXCEPT
```
**Description**
Less-than operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <=(const etl::chrono::day& m1,
const etl::chrono::day& m2)
ETL_NOEXCEPT
```
**Description**
Less-than-or-equal operator.
---
```cpp
ETL_CONSTEXPR14
bool operator >(const etl::chrono::day& m1,
const etl::chrono::day& m2)
ETL_NOEXCEPT
```
**Description**
Greater-than operator.
---
```cpp
ETL_CONSTEXPR14
bool operator >=(const etl::chrono::day& m1,
const etl::chrono::day& m2)
ETL_NOEXCEPT
```
**Description**
Greater-than-or-equal operator.
---
```cpp
[[nodiscard]] inline constexpr
auto operator <=>(const etl::chrono::day& m1,
const etl::chrono::day& m2)
noexcept
```
**Description**
Spaceship operator.
C++20
## Defined days
```cpp
etl::chrono::January
etl::chrono::February
etl::chrono::March
etl::chrono::April
etl::chrono::May
etl::chrono::June
etl::chrono::July
etl::chrono::August
etl::chrono::September
etl::chrono::October
etl::chrono::November
etl::chrono::December
```
## Hash
```cpp
template <>
struct hash<etl::chrono::day>
```
**Description**
Hash function for `etl::chrono::day`.

View File

@ -0,0 +1,16 @@
---
title: "Durations"
weight: 100
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono](https://en.cppreference.com/w/cpp/chrono.html)
{{< /callout >}}
Classes that represent a duration.
`etl::chrono::duration`
`etl::chrono::duration_cast`
`etl::chrono::duration_values`

View File

@ -0,0 +1,526 @@
---
title: "duration"
---
{{< callout type="info">}}
Header: `chrono.h`
Since: `TBC`
Similar to: [std::chrono::duration](https://en.cppreference.com/w/cpp/chrono/duration.html)
Similar to: [std::chrono::duration_values](https://en.cppreference.com/w/cpp/chrono/duration_values.html)
{{< /callout >}}
Templates representing a time interval.
## duration_values
```cpp
template <typename TRep>
struct duration_values
```
```cpp
ETL_NODISCARD static ETL_CONSTEXPR TRep zero() ETL_NOEXCEPT
```
**Return**
`TRep(0)`
---
```cpp
ETL_NODISCARD static ETL_CONSTEXPR14 TRep min() ETL_NOEXCEPT
```
**Return**
`etl::numeric_limits<TRep>::min()`
---
```cpp
ETL_NODISCARD static ETL_CONSTEXPR14 TRep max() ETL_NOEXCEPT
```
**Returns**
`etl::numeric_limits<TRep>::max()`
## duration
```cpp
template <typename TRep, typename TPeriod = etl::ratio<1>>
class duration
```
```cpp
using rep = TRep
using period = typename TPeriod::type;
```
### Construction
```cpp
ETL_CONSTEXPR
duration()
ETL_NOEXCEPT
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR14
duration(const etl::chrono::duration<TRep, TPeriod>& other)
ETL_NOEXCEPT
```
---
```cpp
template <typename TRep2>
ETL_CONSTEXPR14
explicit duration(const TRep2& value)
ETL_NOEXCEPT
```
---
```cpp
template <typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
duration(const etl::chrono::duration<TRep2, TPeriod2>& other)
ETL_NOEXCEPT
```
**Description**
Construct from another duration type.
Enabled if `etl::ratio_divide<TPeriod2, TPeriod>::den == 1`
### Tests
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
int compare(const time_point& other) const
ETL_NOEXCEPT
```
**Description**
Compare day with another.
if `time_point < other`, returns `-1`
else if `time_point > other`, returns `1`
else returns `0`
### Assignment
```cpp
ETL_CONSTEXPR14
etl::chrono::duration<TRep, TPeriod> operator =(const etl::chrono::duration<TRep, TPeriod>& other) ETL_NOEXCEPT
```
---
```cpp
template <typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
etl::chrono::duration<TRep, TPeriod> operator =(const etl::chrono::duration<TRep2, TPeriod2>& other) ETL_NOEXCEPT
```
### Convertion
```cpp
ETL_CONSTEXPR14
TRep count() const
ETL_NOEXCEPT
```
**Return**
The duration count as a numeric.
---
```cpp
ETL_CONSTEXPR14
etl::common_type_t<duration> operator +() const
ETL_NOEXCEPT
```
**Description**
Implements unary plus.
---
```cpp
ETL_CONSTEXPR14
etl::common_type_t<duration> operator -() const
ETL_NOEXCEPT
```
**Description**
Implements unary minus.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::duration<TRep, TPeriod> absolute() const
ETL_NOEXCEPT
```
**Return**
The absolute value of the duration.
---
### Constants
```cpp
ETL_NODISCARD
static ETL_CONSTEXPR14 etl::chrono::duration<TRep, TPeriod> zero()
ETL_NOEXCEPT
```
**Return**
The duration zero value.
---
```cpp
ETL_NODISCARD
static ETL_CONSTEXPR14 etl::chrono::duration<TRep, TPeriod> min()
ETL_NOEXCEPT
```
**Return**
The minimum duration value.
---
```cpp
ETL_NODISCARD
static ETL_CONSTEXPR14 etl::chrono::duration<TRep, TPeriod> max()
ETL_NOEXCEPT
---
**Return**
The maximum duration value.
## Increment/decrement
```cpp
ETL_CONSTEXPR14
duration& operator ++()
ETL_NOEXCEPT
```
**Description**
Pre-increments the duration count.
---
```cpp
ETL_CONSTEXPR14
duration operator ++(int)
ETL_NOEXCEPT
```
**Description**
Post-increments the duration count.
---
```cpp
ETL_CONSTEXPR14
duration& operator --()
ETL_NOEXCEPT
```
**Description**
Pre-decrements the duration count.
---
```cpp
ETL_CONSTEXPR14
duration operator --(int)
ETL_NOEXCEPT
```
**Description**
Post-decrements the duration count.
### Mathematical operators
```cpp
ETL_CONSTEXPR14
duration& operator +=(const duration<TRep, TPeriod>& d)
ETL_NOEXCEPT
```
**Description**
Adds duration `d` to this duration.
---
```cpp
ETL_CONSTEXPR14
duration& operator -=(const duration<TRep, TPeriod>& d)
ETL_NOEXCEPT
```
**Description**
Subtracts duration `d` to this duration.
---
```cpp
ETL_CONSTEXPR14
duration& operator *=(const TRep& r)
ETL_NOEXCEPT
```
**Description**
Multiplies this duration by `r`.
---
```cpp
ETL_CONSTEXPR14
duration& operator /=(const TRep& r)
ETL_NOEXCEPT
```
**Description**
Divides this duration by `r`.
---
```cpp
ETL_CONSTEXPR14
duration& operator %=(const TRep& r)
ETL_NOEXCEPT
```
**Description**
Sets this duration to the modulus of `r`.
---
```cpp
ETL_CONSTEXPR14
duration& operator %=(const duration<TRep, TPeriod>& d)
ETL_NOEXCEPT
```
**Description**
Sets this duration to the modulus of duration `d`.
### Comparison
```cpp
template <typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
int compare(const duration<TRep2, TPeriod2>& other) const
ETL_NOEXCEPT
```
**Description**
Compare duration with another.
If `duration < other`, returns `-1`
else if `duration > other`, returns `1`
else returns `0`
### Non-member mathematical operators
```cpp
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
etl::common_type_t<etl::chrono::duration<TRep1, TPeriod1>,
etl::chrono::duration<TRep2, TPeriod2>>
operator +(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs)
ETL_NOEXCEPT
```
**Description**
Operator `+`
---
```cpp
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
etl::common_type_t<etl::chrono::duration<TRep1, TPeriod1>,
etl::chrono::duration<TRep2, TPeriod2> >::type
operator -(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs)
ETL_NOEXCEPT
```
**Description**
Operator `-`
---
```cpp
template <typename TRep1, typename TPeriod1, typename TRep2>
ETL_CONSTEXPR14
etl::chrono::duration<etl::common_type_t<TRep1, TRep2>, TPeriod1>>
operator *(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const TRep2& rhs)
ETL_NOEXCEPT
```
**Description**
Operator `*`
Enabled if `TRep2` is not a specialization of `etl::chrono::duration`.
---
```cpp
template <typename TRep1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
etl::chrono::duration<etl::common_type_t<TRep1, TRep2>, TPeriod2>
operator *(const TRep1& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs)
ETL_NOEXCEPT
```
**Description**
Operator `*`
---
```cpp
template <typename TRep1, typename TPeriod1, typename TRep2>
ETL_CONSTEXPR14
etl::common_type_t<TRep1, TRep2>, TPeriod1>
operator /(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const TRep2& rhs)
ETL_NOEXCEPT
```
**Description**
Operator `/`
Enabled if `TRep2` is not a specialization of `etl::chrono::duration`.
---
```cpp
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
etl::common_type_t<TRep1, TRep2>
operator /(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs)
ETL_NOEXCEPT
```
**Description**
Operator `/`
---
```cpp
template <typename TRep1, typename TPeriod1, typename TRep2>
ETL_CONSTEXPR14
etl::chrono::duration<etl::common_type_t<TRep1, TRep2>, TPeriod1>
operator %(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const TRep2& rhs)
ETL_NOEXCEPT
```
**Description**
Operator `%`
```
```cpp
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
etl::common_type_t<etl::chrono::duration<TRep1, TPeriod1>,
etl::chrono::duration<TRep2, TPeriod2>>
operator %(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs)
ETL_NOEXCEPT
```
**Description**
Operator `%`
### Non-member comparison operators
```cpp
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
bool operator ==(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs)
ETL_NOEXCEPT
```
**Description**
Checks for equality.
---
```cpp
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
bool operator !=(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs)
ETL_NOEXCEPT
```
**Description**
Checks for inequality.
---
```cpp
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
bool operator <(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs)
ETL_NOEXCEPT
```
**Description**
Checks for less-than.
---
```cpp
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
bool operator <=(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs)
ETL_NOEXCEPT
```
**Description**
Checks for less-than-or-equal.
---
```cpp
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
bool operator >(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs)
ETL_NOEXCEPT
```
**Description**
Checks for greater-than.
---
```cpp
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
bool operator >=(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs)
ETL_NOEXCEPT
```
**Description**
Checks for greater-than-or-equal.
---
```cpp
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
[[nodiscard]]
constexpr
auto operator <=>(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs)
noexcept
```
**Description**
Spaceship operator.
C++20
## common_type
```cpp
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
struct common_type<etl::chrono::duration<TRep1, TPeriod1>, etl::chrono::duration<TRep2, TPeriod2>>
```
**Description**
`etl::common_type` specialisation for `etl::duration`.
## Hash
```cpp
template <typename TRep, typename TPeriod>
struct hash<etl::chrono::duration<TRep, TPeriod>>
```
## Pre-defined duration types
```cpp
etl::chrono::years
etl::chrono::months
etl::chrono::weeks
etl::chrono::days
etl::chrono::hours
etl::chrono::minutes
etl::chrono::seconds
etl::chrono::milliseconds
etl::chrono::microseconds
etl::chrono::nanoseconds
```
## duration_cast
```cpp
template <typename TToDuration, typename TRep, typename TPeriod>
ETL_CONSTEXPR14
TToDuration duration_cast(const etl::chrono::duration<TRep, TPeriod>& d)
ETL_NOEXCEPT
```
**Description**
Converts from one duration type to another.

View File

@ -0,0 +1,21 @@
---
title: "duration_cast"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::duration_cast](https://en.cppreference.com/w/cpp/chrono/duration/duration_cast.html)
{{< /callout >}}
Templates representing a time interval.
## duration_cast
```cpp
template <typename TToDuration, typename TRep, typename TPeriod>
ETL_CONSTEXPR14
TToDuration duration_cast(const etl::chrono::duration<TRep, TPeriod>& d)
ETL_NOEXCEPT
```
**Description**
Converts from one duration type to another.

View File

@ -0,0 +1,38 @@
---
title: "duration_values"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::duration_values](https://en.cppreference.com/w/cpp/chrono/duration_values.html)
{{< /callout >}}
Templates representing a time interval.
## duration_values
```cpp
template <typename TRep>
struct duration_values
```
```cpp
ETL_NODISCARD static ETL_CONSTEXPR TRep zero() ETL_NOEXCEPT
```
**Return**
`TRep(0)`
---
```cpp
ETL_NODISCARD static ETL_CONSTEXPR14 TRep min() ETL_NOEXCEPT
```
**Return**
`etl::numeric_limits<TRep>::min()`
---
```cpp
ETL_NODISCARD static ETL_CONSTEXPR14 TRep max() ETL_NOEXCEPT
```
**Returns**
`etl::numeric_limits<TRep>::max()`

138
docs/chrono/hh_mm_ss.md Normal file
View File

@ -0,0 +1,138 @@
---
title: "hh_mm_ss"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::hh_mm_ss](https://en.cppreference.com/w/cpp/chrono/hh_mm_ss.html)
{{< /callout >}}
A type to hold hours, minutes, and seconds.
```cpp
template <typename TDuration>
class hh_mm_ss
```
**Description**
Static asserts if `TDuration` is not a specialisation of `etl::chrono::duration`.
## Constants
```cpp
static constexpr int fractional_width;
```
**Description**
The number of fractional digits.
## Member types
```cpp
precision
```
**Description**
The return type for `to_duration`.
## Constructors
```cpp
ETL_CONSTEXPR
hh_mm_ss()
ETL_NOEXCEPT
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR14
explicit hh_mm_ss(TDuration d)
ETL_NOEXCEPT
```
**Description**
Construct from `duration`.
## Access
```pp
ETL_NODISCARD
ETL_CONSTEXPR14
bool is_negative() const
ETL_NOEXCEPT
```
**Description**
Checks for negative duration.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::hours hours() const
ETL_NOEXCEPT
```
**Return**
The hours.
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::minutes minutes() const
ETL_NOEXCEPT
```
**Return**
The minutes.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::seconds seconds() const
ETL_NOEXCEPT
```
**Return**
The seconds.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
precision subseconds() const
ETL_NOEXCEPT
```
**Return**
The subseconds.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
explicit operator precision() const
ETL_NOEXCEPT
```
**Return**
The duration.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
precision to_duration() const
ETL_NOEXCEPT
```
**Return***
The duration.
## absolute
```cpp
template <typename TDuration>
ETL_NODISCARD
ETL_CONSTEXPR14
TDuration absolute(TDuration dur)
ETL_NOEXCEPT
```
A specialisation of absolute for `etl::chrono::duration`.
**Return**
The absolute duration value.

25
docs/chrono/last_spec.md Normal file
View File

@ -0,0 +1,25 @@
---
title: "last_spec"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::last_spec](https://en.cppreference.com/w/cpp/chrono/last_spec.html)
{{< /callout >}}
`last_spec` is a tag type that is used in conjunction with other calendar types to indicate the last thing in a sequence.
```cpp
struct last_spec
{
explicit last_spec() = default;
};
inline constexpr last_spec last{};
```
**Example**
`2025_y/March/last` for last day of March 2025 i.e. 2025-03-31

View File

@ -0,0 +1,18 @@
---
title: "Months"
weight: 100
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono](https://en.cppreference.com/w/cpp/chrono.html)
{{< /callout >}}
Classes that represent months.
`etl::chrono::month`
`etl::chrono::month_day`
`etl::chrono::month_day_last`
`etl::chrono::month_weekday`
`etl::chrono::month_weekday_last`

337
docs/chrono/month/month.md Normal file
View File

@ -0,0 +1,337 @@
---
title: "month"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::month](https://en.cppreference.com/w/cpp/chrono/month.html)
{{< /callout >}}
A class representing a month.
```cpp
class month
```
## Member types
`rep` The internal representation.
## Construction
```cpp
ETL_CONSTEXPR
month()
ETL_NOEXCEPT
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR
explicit month(unsigned value)
ETL_NOEXCEPT
```
**Description**
Construct from unsigned.
---
```cpp
ETL_CONSTEXPR14
month(const etl::chrono::month& other)
ETL_NOEXCEPT
```
**Description**
Copy constructor.
## Tests
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
bool ok() const
ETL_NOEXCEPT
```
**Description**
Returns true if the month is in range.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
int compare(const etl::chrono::month& other) const
ETL_NOEXCEPT
```
**Description**
Compare month with another.
if month < other, returns -1
else if month > other, returns 1
else returns 0
## Assignment
```cpp
ETL_CONSTEXPR14
etl::chrono::month& operator =(const etl::chrono::month& rhs)
ETL_NOEXCEPT
```
**Description**
Assignment operator
## Increment / decrement
```cpp
ETL_CONSTEXPR14
etl::chrono::month& operator ++()
ETL_NOEXCEPT
```
**Description**
Pre-increment operator.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::month operator ++(int)
ETL_NOEXCEPT
```
**Description**
Post-increment operator.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::month& operator --()
ETL_NOEXCEPT
```
**Description**
Pre-decrement operator.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::month operator --(int)
ETL_NOEXCEPT
```
**Description**
Post-decrement operator.
## Mathematical operators
```cpp
ETL_CONSTEXPR14
etl::chrono::month& operator +=(const etl::chrono::months& ms)
ETL_NOEXCEPT
```
**Description**
Plus-equals operator adding `etl::chrono::months`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::month& operator -=(const etl::chrono::months& ms)
ETL_NOEXCEPT
```
**Description**
Minus-equals operator subtracting `etl::chrono::months`.
## Constants
```cpp
ETL_NODISCARD
static
ETL_CONSTEXPR14
etl::chrono::month min()
ETL_NOEXCEPT
```
**Description**
The minimum month value for which ok() will return true.
---
```cpp
ETL_NODISCARD
static
ETL_CONSTEXPR14
etl::chrono::month max()
ETL_NOEXCEPT
```
**Description**
The maximum month value for which ok() will return true.
## Conversion
```cpp
ETL_CONSTEXPR14
operator unsigned() const
ETL_NOEXCEPT
```
**Description**
Conversion operator to `unsigned int`.
## Non-member mathematical operators
```cpp
ETL_CONSTEXPR14
etl::chrono::month operator +(const etl::chrono::month& m,
const etl::chrono::months& ms)
ETL_NOEXCEPT
```
**Description**
Add `etl::chrono::months` to `etl::chrono::month`.
**Return**
`etl::chrono::month.`
---
```cpp
ETL_CONSTEXPR14
etl::chrono::month operator +(const etl::chrono::months& ms,
const etl::chrono::month& m)
ETL_NOEXCEPT
```
**Description**
Add `etl::chrono::month` to `etl::chrono::months`.
**Return**
`etl::chrono::month`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::month operator -(const etl::chrono::month& m,
const etl::chrono::months& ms)
ETL_NOEXCEPT
```
**Description**
Subtract `etl::chrono::months` from `etl::chrono::month`.
**Return**
`etl::chrono::month`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::month operator -(const etl::chrono::months& ms,
const etl::chrono::month& m)
ETL_NOEXCEPT
```
**Description**
Subtract `etl::chrono::month` from `etl::chrono::months`.
**Return**
`etl::chrono::months`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::months operator -(const etl::chrono::month& m1,
const etl::chrono::month& m2) ETL_NOEXCEPT
```
**Description**
Subtract `etl::chrono::month` from `etl::chrono::month`.
**Return**
`etl::chrono::months`.
## Non-member comparison operators
```cpp
ETL_CONSTEXPR14
bool operator ==(const etl::chrono::month& m1,
const etl::chrono::month& m2)
ETL_NOEXCEPT
```
**Description**
Equality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator !=(const etl::chrono::month& m1,
const etl::chrono::month& m2)
ETL_NOEXCEPT
```
**Description**
Inequality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <(const etl::chrono::month& m1,
const etl::chrono::month& m2)
ETL_NOEXCEPT
```
**Description**
Less-than operator.
```cpp
ETL_CONSTEXPR14
bool operator <=(const etl::chrono::month& m1,
const etl::chrono::month& m2)
ETL_NOEXCEPT
```
**Description**
Less-than-or-equal operator.
---
```cpp
ETL_CONSTEXPR14
bool operator >(const etl::chrono::month& m1,
const etl::chrono::month& m2)
ETL_NOEXCEPT
```
**Description**
Greater-than operator.
---
```cpp
ETL_CONSTEXPR14
bool operator >=(const etl::chrono::month& m1,
const etl::chrono::month& m2)
ETL_NOEXCEPT
```
**Description**
Greater-than-or-equal operator.
---
```cpp
[[nodiscard]] inline constexpr
auto operator <=>(const etl::chrono::month& m1,
const etl::chrono::month& m2)
noexcept
```
**Description**
Spaceship operator.
C++20
## Defined months
```cpp
etl::chrono::January
etl::chrono::February
etl::chrono::March
etl::chrono::April
etl::chrono::May
etl::chrono::June
etl::chrono::July
etl::chrono::August
etl::chrono::September
etl::chrono::October
etl::chrono::November
etl::chrono::December
```
## Hash
```cpp
template <>
struct hash<etl::chrono::month>
```
Hash function for `etl::chrono::month`.

View File

@ -0,0 +1,171 @@
---
title: "month_day"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::month_day](https://en.cppreference.com/w/cpp/chrono/month_day.html)
{{< /callout >}}
A class representing a month and day.
```cpp
class month_day
```
## Construction
```cpp
ETL_CONSTEXPR
month_day()
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR14
month_day(const etl::chrono::month& m,
const etl::chrono::day& d)
ETL_NOEXCEPT
```
**Description**
Construct from `month` and `day`.
## Access
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::month month() const
ETL_NOEXCEPT
```
**Return**
The month.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::day day() const
ETL_NOEXCEPT
```
**Return**
The day.
## Tests
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
bool ok() const
ETL_NOEXCEPT
```
**Return**
`true` if the month and day is within the valid limits.
---
```cpp
ETL_CONSTEXPR14
int compare(const month_day& other) const
ETL_NOEXCEPT
```
**Description**
Compare `month_day` with another.
if `month < other.month`, returns `-1`
else if `month > other.month`, returns `1`
else if `day < other.day`, returns `-1`
else if `day > other.day`, returns `1`
else returns `0`
## Non-member comparison operators
```cpp
ETL_CONSTEXPR14
bool operator ==(const etl::chrono::month_day& lhs,
const etl::chrono::month_day& rhs)
ETL_NOEXCEPT
```
**Description**
Equality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator !=(const etl::chrono::month_day& lhs,
const etl::chrono::month_day& rhs)
ETL_NOEXCEPT
```
**Description**
Inequality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <(const etl::chrono::month_day& lhs,
const etl::chrono::month_day& rhs)
ETL_NOEXCEPT
```
**Description**
Less-than operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <=(const etl::chrono::month_day& lhs,
const etl::chrono::month_day& rhs)
ETL_NOEXCEPT
```
**Description**
Less-than-equal operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <(const etl::chrono::month_day& lhs,
const etl::chrono::month_day& rhs)
ETL_NOEXCEPT
```
**Description**
Greater-than operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <=(const etl::chrono::month_day& lhs,
const etl::chrono::month_day& rhs)
ETL_NOEXCEPT
```
**Description**
Greater-than-equal operator.
---
```cpp
[[nodiscard]] constexpr
auto operator <=>(const etl::chrono::month_day& lhs,
const etl::chrono::month_day& rhs)
ETL_NOEXCEPT
```
**Description**
Spaceship operator.
C++20
## Hash
```cpp
template <typename TRep, typename TPeriod>
struct hash<etl::chrono::month_day>
```
**Description**
Hash function for `etl::chrono::month_day`.

View File

@ -0,0 +1,147 @@
---
title: "month_day_last"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::month_day_last](https://en.cppreference.com/w/cpp/chrono/month_day_last.html)
{{< /callout >}}
A class representing a month and last day.
```cpp
class month_day_last
```
## Construction
```cpp
ETL_CONSTEXPR14
explicit month_day_last(const etl::chrono::month& m)
ETL_NOEXCEPT
```
**Description**
Construct from month.
## Access
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::month month() const
ETL_NOEXCEPT
```
**Return**
The month.
## Tests
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
bool ok() const
ETL_NOEXCEPT
```
**Return**
`true` if the month is within the valid limits.
---
```cpp
ETL_CONSTEXPR14
int compare(const month_day_last& other) const
ETL_NOEXCEPT
```
**Description**
Compare `month_day_last` with another.
if `month < other.month`, returns `-1`
else if `month > other.month`, returns `1`
else returns `0`
## Non-member comparison operators
```cpp
ETL_CONSTEXPR14
bool operator ==(const etl::chrono::month_day_last& lhs,
const etl::chrono::month_day_last& rhs)
ETL_NOEXCEPT
```
**Description**
Equality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator !=(const etl::chrono::month_day_last& lhs,
const etl::chrono::month_day_last& rhs)
ETL_NOEXCEPT
```
**Description**
Inequality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <(const etl::chrono::month_day_last& lhs,
const etl::chrono::month_day_last& rhs)
ETL_NOEXCEPT
```
**Description**
Less-than operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <=(const etl::chrono::month_day_last& lhs,
const etl::chrono::month_day_last& rhs)
ETL_NOEXCEPT
```
**Description**
Less-than-equal operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <(const etl::chrono::month_day_last& lhs,
const etl::chrono::month_day_last& rhs)
ETL_NOEXCEPT
```
**Description**
Greater-than operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <=(const etl::chrono::month_day_last& lhs,
const etl::chrono::month_day_last& rhs)
ETL_NOEXCEPT
```
**Description**
Greater-than-equal operator.
---
```cpp
[[nodiscard]] constexpr
auto operator <=>(const etl::chrono::month_day_last& lhs,
const etl::chrono::month_day_last& rhs)
ETL_NOEXCEPT
```
**Description**
Spaceship operator.
C++20
## Hash
```cpp
template <typename TRep, typename TPeriod>
struct hash<etl::chrono::month_day_last>
```
**Description**
Hash function for `etl::chrono::month_day_last`.

View File

@ -0,0 +1,156 @@
---
title: "month_weekday"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::month_weekday](https://en.cppreference.com/w/cpp/chrono/month_weekday.html)
{{< /callout >}}
A class representing a month and weekday.
```cpp
class month_weekday
```
## Construction
```cpp
ETL_CONSTEXPR
month_weekday()
```
**Decription**
Default constructor.
---
```cpp
ETL_CONSTEXPR14
month_weekday(const etl::chrono::month& m,
const etl::chrono::weekday_indexed& wd)
ETL_NOEXCEPT
```
**Decription**
Construct from month and weekday_indexed.
## Access
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::month month() const
ETL_NOEXCEPT
```
**Returns**
The month.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::weekday_indexed weekday_indexed() const
ETL_NOEXCEPT
```
**Return**
The weekday.
## Tests
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
bool ok() const
ETL_NOEXCEPT
```
**Return**
`true` if the month and day is within the valid limits.
## Non-member comparison operators
```cpp
ETL_CONSTEXPR14
bool operator ==(const etl::chrono::month_weekday& lhs,
const etl::chrono::month_weekday& rhs)
ETL_NOEXCEPT
```
**Decription**
Equality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator !=(const etl::chrono::month_weekday& lhs,
const etl::chrono::month_weekday& rhs)
ETL_NOEXCEPT
```
**Decription**
Inequality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <(const etl::chrono::month_weekday& lhs,
const etl::chrono::month_weekday& rhs)
ETL_NOEXCEPT
```
**Decription**
Less-than operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <=(const etl::chrono::month_weekday& lhs,
const etl::chrono::month_weekday& rhs)
ETL_NOEXCEPT
```
**Decription**
Less-than-equal operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <(const etl::chrono::month_weekday& lhs,
const etl::chrono::month_weekday& rhs)
ETL_NOEXCEPT
```
**Decription**
Greater-than operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <=(const etl::chrono::month_weekday& lhs,
const etl::chrono::month_weekday& rhs)
ETL_NOEXCEPT
```
**Decription**
Greater-than-equal operator.
---
```cpp
[[nodiscard]] constexpr
auto operator <=>(const etl::chrono::month_weekday& lhs,
const etl::chrono::month_weekday& rhs)
ETL_NOEXCEPT
```
**Decription**
Spaceship operator.
C++20
## Hash
```cpp
template <typename TRep, typename TPeriod>
struct hash<etl::chrono::month_weekday>
```
**Decription**
Hash function for `etl::chrono::month_weekday`.

View File

@ -0,0 +1,143 @@
---
title: "month_weekday_last"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::month_weekday_last](https://en.cppreference.com/w/cpp/chrono/month_weekday_last.html)
{{< /callout >}}
A class representing a month and weekday_last.
```cpp
class month_weekday_last
```
## Construction
```cpp
ETL_CONSTEXPR
month_weekday_last()
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR14
month_weekday_last(const etl::chrono::month& m,
const etl::chrono::weekday_last& wd)
ETL_NOEXCEPT
```
**Description**
Construct from `month` and `weekday_last`.
## Access
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::month month() const
ETL_NOEXCEPT
```
**Return**
The month.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::weekday_last weekday_last() const
ETL_NOEXCEPT
```
**Return**
The weekday.
## Tests
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
bool ok() const
ETL_NOEXCEPT
```
**Return**
`true` if the month and day is within the valid limits.
## Non-member comparison operators
```cpp
ETL_CONSTEXPR14
bool operator ==(const etl::chrono::month_weekday_last& lhs,
const etl::chrono::month_weekday_last& rhs)
ETL_NOEXCEPT
```
**Description**
Equality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator !=(const etl::chrono::month_weekday_last& lhs,
const etl::chrono::month_weekday_last& rhs)
ETL_NOEXCEPT
```
**Description**
Inequality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <(const etl::chrono::month_weekday_last& lhs,
const etl::chrono::month_weekday_last& rhs)
ETL_NOEXCEPT
```
**Description**
Less-than operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <=(const etl::chrono::month_weekday_last& lhs,
const etl::chrono::month_weekday_last& rhs)
ETL_NOEXCEPT
```
**Description**
Less-than-equal operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <(const etl::chrono::month_weekday_last& lhs,
const etl::chrono::month_weekday_last& rhs)
ETL_NOEXCEPT
```
**Description**
Greater-than operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <=(const etl::chrono::month_weekday_last& lhs,
const etl::chrono::month_weekday_last& rhs)
ETL_NOEXCEPT
```
**Description**
Greater-than-equal operator.
## Hash
```cpp
template <typename TRep, typename TPeriod>
struct hash<etl::chrono::month_weekday_last>
```
**Description**
Hash function for `etl::chrono::month_weekday_last`.

329
docs/chrono/operators.md Normal file
View File

@ -0,0 +1,329 @@
---
title: "Operators"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::operator /](https://en.cppreference.com/w/cpp/chrono/operator_slash.html)
{{< /callout >}}
Operators for building dates.
## month_day
Create from month and day.
```cpp
ETL_CONSTEXPR14
etl::chrono::month_day operator /(const etl::chrono::month& m,
const etl::chrono::day& d)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::month_day operator /(const etl::chrono::month& m,
int d)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::month_day operator /(int m,
const etl::chrono::day& d)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::month_day operator /(const etl::chrono::day& d,
const etl::chrono::month& m)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::month_day operator /(const etl::chrono::day& d,
int m)
ETL_NOEXCEPT
```
## month_day_last
Create from month and last_spec.
```cpp
ETL_CONSTEXPR14
etl::chrono::month_day_last operator /(const etl::chrono::month& m,
etl::chrono::last_spec)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::month_day_last operator /(int m,
etl::chrono::last_spec)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::month_day_last operator /(etl::chrono::last_spec,
const etl::chrono::month& m)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::month_day_last operator /(etl::chrono::last_spec,
int m)
ETL_NOEXCEPT
```
## month_weekday
Create from month and weekday.
```cpp
ETL_CONSTEXPR14
etl::chrono::month_weekday operator /(const etl::chrono::month& m,
const etl::chrono::weekday_indexed& wdi)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::month_weekday operator /(int m,
const etl::chrono::weekday_indexed& wdi)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::month_weekday operator /(const etl::chrono::weekday_indexed& wdi,
const etl::chrono::month& m)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::month_weekday operator /(const etl::chrono::weekday_indexed& wdi,
int m)
ETL_NOEXCEPT
```
## month_weekday_last
Create from month and weekday_last.
```cpp
ETL_CONSTEXPR14
etl::chrono::month_weekday_last operator /(const etl::chrono::month& m,
const etl::chrono::weekday_last& wdl)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::month_weekday_last operator /(int m,
const etl::chrono::weekday_last& wdl)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::month_weekday_last operator /(const etl::chrono::weekday_last& wdl,
const etl::chrono::month& m)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::month_weekday_last operator /(const etl::chrono::weekday_last& wdl,
int m)
ETL_NOEXCEPT
```
## year_month
Create from year and month.
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month operator /(const etl::chrono::year& y,
const etl::chrono::month& m)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month operator /(const etl::chrono::year& y,
int m)
ETL_NOEXCEPT
```
## year_month_day
Create from year, month, and day.
```cpp
ETL_CONSTEXPR14 etl::chrono::year_month_day operator /(const etl::chrono::year_month& ym,
const etl::chrono::day& d)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14 etl::chrono::year_month_day operator /(const etl::chrono::year_month& ym,
int d )
ETL_NOEXCEPT
```
## year_month_day
Create from year and month_day.
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day operator /(const etl::chrono::year& y,
const etl::chrono::month_day& md)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day operator /(int y,
const etl::chrono::month_day& md)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day operator /(const etl::chrono::month_day& md,
const etl::chrono::year& y)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day operator /(const etl::chrono::month_day& md,
int y)
ETL_NOEXCEPT
```
## year_month_day_last
Create from year_month and last_spec.
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day_last operator /(const etl::chrono::year_month& ym,
etl::chrono::last_spec)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day_last operator /(const etl::chrono::year& y,
const etl::chrono::month_day_last& mdl)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day_last operator /(int y,
const etl::chrono::month_day_last& mdl)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day_last operator /(const etl::chrono::month_day_last& mdl,
const etl::chrono::year& y)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day_last operator /(const etl::chrono::month_day_last& mdl,
int y)
ETL_NOEXCEPT
```
## year_month_weekday
Create from year_month and weekday.
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_weekday operator /(const etl::chrono::year_month& ym,
const etl::chrono::weekday_indexed& wdi)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_weekday operator /(const etl::chrono::year& y,
const etl::chrono::month_weekday& mwd)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_weekday operator /(int y,
const etl::chrono::month_weekday& mwd)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_weekday operator /(const etl::chrono::month_weekday& mwd,
const etl::chrono::year& y)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_weekday operator /(const etl::chrono::month_weekday& mwd,
int y)
ETL_NOEXCEPT
```
## year_month_weekday_last
Create from year_month and weekday_last.
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_weekday_last operator /(const etl::chrono::year_month& ym,
const etl::chrono::weekday_last& wdl)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_weekday_last operator /(const etl::chrono::year& y,
const etl::chrono::month_weekday_last& mwdl)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_weekday_last operator /(int y,
const etl::chrono::month_weekday_last& mwdl)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_weekday_last operator /(const etl::chrono::month_weekday_last& mwdl,
const etl::chrono::year& y)
ETL_NOEXCEPT
```
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_weekday_last operator /(const etl::chrono::month_weekday_last& mwdl,
int y)
ETL_NOEXCEPT
```

273
docs/chrono/time_point.md Normal file
View File

@ -0,0 +1,273 @@
---
title: "time_point"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::time_point](https://en.cppreference.com/w/cpp/chrono/time_point.html)
{{< /callout >}}
```cpp
template <typename TClock, typename TDuration = typename TClock::duration>
class time_point;
```
Represents a point in time storing a `TDuration` indicating the time
interval from the start of the `TClock`'s epoch.
## Member types
```cpp
using clock = TClock
using duration = TDuration
using rep = typename TDuration::rep
using period = typename TDuration::period
```
## Constructors
```cpp
ETL_CONSTEXPR
time_point()
ETL_NOEXCEPT
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR14
explicit time_point(const duration& dur_)
ETL_NOEXCEPT
```
**Description**
Construct from a duration.
---
```cpp
ETL_CONSTEXPR14
time_point(const time_point& rhs)
ETL_NOEXCEPT
```
**Description**
Copy constructor.
---
```cpp
template <typename TDuration2>
ETL_CONSTEXPR14
explicit time_point(const time_point<clock, TDuration2>& rhs)
ETL_NOEXCEPT
```
**Description**
Copy construct from another time_point with a different duration type.
## Assignment
```cpp
ETL_CONSTEXPR14
time_point& operator =(const time_point& rhs)
ETL_NOEXCEPT
```
**Description**
Assignment operator.
## Access
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14 duration time_since_epoch() const
ETL_NOEXCEPT
```
**Return**
A duration representing the amount of time between this and the clock's epoch.
## Member arithmetic operators
```cpp
ETL_CONSTEXPR14 time_point& operator +=(const duration& rhs)
ETL_NOEXCEPT
```
**Description**
Adds a duration.
---
```cpp
ETL_CONSTEXPR14 time_point& operator -=(const duration& rhs)
ETL_NOEXCEPT
```
**Description**
Subtracts a duration.
## Constants
```cpp
ETL_NODISCARD
static ETL_CONSTEXPR14 time_point min()
ETL_NOEXCEPT
```
**Return**
A time_point with the smallest possible duration.
---
```cpp
ETL_NODISCARD
static ETL_CONSTEXPR14 time_point max()
ETL_NOEXCEPT
```
**Return**
A time_point with the largest possible duration.
## Rounding
```cpp
template <typename TToDuration, typename TClock, typename TDuration>
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::time_point<TClock, TToDuration>
floor(const etl::chrono::time_point<TClock, TDuration>& tp)
ETL_NOEXCEPT
```
**Description**
Rounds down a duration to the nearest lower precision.
---
```cpp
template <typename TToDuration, typename TClock, typename TDuration>
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::time_point<TClock, TToDuration>
ceil(const etl::chrono::time_point<TClock, TDuration>& tp)
ETL_NOEXCEPT
```
**Description**
Rounds up a duration to the nearest higher precision.
---
```cp
template <typename TToDuration, typename TClock, typename TDuration>
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::time_point<TClock, TToDuration>
round(const etl::chrono::time_point<TClock, TDuration>& tp)
ETL_NOEXCEPT
```
**Description**
Rounds a duration to the nearest precision.
If the duration is exactly halfway, it rounds away from zero.
## Casting
```cpp
template <typename TToDuration, typename TClock, typename TDuration>
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::time_point<TClock, TToDuration>
time_point_cast(const etl::chrono::time_point<TClock, TDuration>& tp)
ETL_NOEXCEPT
```
## Comparison
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14 int compare(const time_point& other) const
ETL_NOEXCEPT
```
**Description**
Compare day with another.
If time_point < other, returns -1
else if time_point > other, returns 1
else returns 0
## Non-member comparison operators
```cpp
template <typename TClock, typename TDuration1, typename TDuration2>
ETL_CONSTEXPR14
bool operator ==(const time_point<TClock, TDuration1>& lhs,
const time_point<TClock, TDuration2>& rhs)
ETL_NOEXCEPT
```
**Description**
Equality operator
---
```cpp
template <typename TClock, typename TDuration1, typename TDuration2>
ETL_CONSTEXPR14
bool operator !=(const time_point<TClock, TDuration1>& lhs,
const time_point<TClock, TDuration2>& rhs)
ETL_NOEXCEPT
```
**Description**
Inequality operator
---
```cpp
template <typename TClock, typename TDuration1, typename TDuration2>
ETL_CONSTEXPR14
bool operator <(const time_point<TClock, TDuration1>& lhs,
const time_point<TClock, TDuration2>& rhs)
ETL_NOEXCEPT
```
**Description**
Less-than operator
---
```cpp
template <typename TClock, typename TDuration1, typename TDuration2>
ETL_CONSTEXPR14
bool operator <=(const time_point<TClock, TDuration1>& lhs,
const time_point<TClock, TDuration2>& rhs)
ETL_NOEXCEPT
```
**Description**
Less-than-equal operator
---
```cpp
template <typename TClock, typename TDuration1, typename TDuration2>
ETL_CONSTEXPR14
bool operator >(const time_point<TClock, TDuration1>& lhs,
const time_point<TClock, TDuration2>& rhs)
ETL_NOEXCEPT
```
**Description**
Greater-than operator
---
```cpp
template <typename TClock, typename TDuration1, typename TDuration2>
ETL_CONSTEXPR14
bool operator >=(const time_point<TClock, TDuration1>& lhs,
const time_point<TClock, TDuration2>& rhs)
ETL_NOEXCEPT
```
**Description**
Greater-than-equal operator
---
```cpp
template <typename TClock, typename TDuration1, typename TDuration2>
[[nodiscard]] constexpr auto operator <=>(const etl::chrono::time_point<TClock, TDuration1>& lhs,
const etl::chrono::time_point<TClock, TDuration2>& rhs)
noexcept
```
**Description**
Spaceship operator
C++20
## etl::common_type specialisation
```cpp
template <typename TClock, typename TDuration1, typename TDuration2>
struct common_type<etl::chrono::time_point<TClock, TDuration1>,
etl::chrono::time_point<TClock, TDuration2>>
```
**Description**
Defines type, which is the common type of two `etl::chrono::time_point`.

View File

@ -0,0 +1,16 @@
---
title: "Weekdays"
weight: 100
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono](https://en.cppreference.com/w/cpp/chrono.html)
{{< /callout >}}
Classes that represent weekdays.
`etl::chrono::weekday`
`etl::chrono::weekday_indexed`
`etl::chrono::weekday_last`

View File

@ -0,0 +1,386 @@
---
title: "weekday"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::weekday](https://en.cppreference.com/w/cpp/chrono/weekday.html)
{{< /callout >}}
A class representing a weekday.
```cpp
class weekday
```
## Construction
```cpp
ETL_CONSTEXPR
weekday()
ETL_NOEXCEPT
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR
explicit weekday(unsigned value)
ETL_NOEXCEPT
```
**Description**
Construct from `unsigned`.
---
```cpp
ETL_CONSTEXPR14
weekday(const etl::chrono::sys_days& sd)
ETL_NOEXCEPT
```
**Description**
Construct from `sys_days`.
---
```cpp
ETL_CONSTEXPR14
weekday(const etl::chrono::local_days& sd)
ETL_NOEXCEPT
```
**Description**
Construct from `local_days`.
---
```cpp
ETL_CONSTEXPR14
weekday(const etl::chrono::weekday& other)
ETL_NOEXCEPT
```
**Description**
Copy constructor.
## Tests
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
bool ok() const
ETL_NOEXCEPT
```
**Return**
`true` if the weekday is valid
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
bool is_weekend() const
ETL_NOEXCEPT
```
**Return**
`true` if the weekday is a Saturday or Sunday.
## Assignment
```cpp
ETL_CONSTEXPR14
etl::chrono::weekday& operator =(const etl::chrono::weekday& rhs)
ETL_NOEXCEPT
```
**Description**
Assignment operator
## Access
```cpp
ETL_CONSTEXPR14
int c_encoding() const
ETL_NOEXCEPT
```
**Description**
Gets the value of the weekday using C encoding.
---
```cpp
ETL_CONSTEXPR14
int iso_encoding() const
ETL_NOEXCEPT
```
**Description**
Gets the value of the weekday using ISO encoding.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::weekday_indexed operator[](unsigned index) const
ETL_NOEXCEPT
```
**Description**
Index operator, from index.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::weekday_last operator[](etl::chrono::last_spec last) const
ETL_NOEXCEPT
```
**Description**
Index operator, from `etl::chrono::last_spec`.
## Increment/decrement
```cpp
ETL_CONSTEXPR14
etl::chrono::weekday& operator ++()
ETL_NOEXCEPT
```
**Description**
Pre-increment operator.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::weekday operator ++(int)
ETL_NOEXCEPT
```
**Description**
Post-increment operator.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::weekday& operator --()
ETL_NOEXCEPT
```
**Description**
Pre-decrement operator.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::weekday operator --(int)
ETL_NOEXCEPT
```
**Description**
Post-decrement operator.
## Mathematical operators
```cpp
ETL_CONSTEXPR14
etl::chrono::weekday& operator +=(const etl::chrono::weekdays& ms)
ETL_NOEXCEPT
```
**Description**
Plus-equals operator adding `etl::chrono::weekdays`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::weekday& operator -=(const etl::chrono::weekdays& ms)
ETL_NOEXCEPT
```
**Description**
Minus-equals operator subtracting `etl::chrono::weekdays`.
## Constants
```cpp
ETL_NODISCARD
static
ETL_CONSTEXPR14
etl::chrono::weekday min()
ETL_NOEXCEPT
```
**Description**
The minimum weekday value for which `ok()` will return true.
---
```cpp
ETL_NODISCARD
static
ETL_CONSTEXPR14
etl::chrono::weekday max()
ETL_NOEXCEPT
```
**Description**
The maximum weekday value for which `ok()` will return true.
## Non-member mathematical operators
```cpp
ETL_CONSTEXPR14
etl::chrono::weekday operator +(const etl::chrono::weekday& m,
const etl::chrono::weekdays& ms)
ETL_NOEXCEPT
```
**Description**
Add `etl::chrono::weekdays` to `etl::chrono::weekday`.
**Return**
`etl::chrono::weekday`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::weekday operator +(const etl::chrono::weekdays& ms,
const etl::chrono::weekday& m)
ETL_NOEXCEPT
```
**Description**
Add `etl::chrono::weekday` to `etl::chrono::weekdays`.
**Return**
`etl::chrono::weekday`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::weekday operator -(const etl::chrono::weekday& m,
const etl::chrono::weekdays& ms)
ETL_NOEXCEPT
```
**Description**
Subtract `etl::chrono::weekdays` from `etl::chrono::weekday`.
**Return**
`etl::chrono::weekday`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::weekday operator -(const etl::chrono::weekdays& ms,
const etl::chrono::weekday& m)
ETL_NOEXCEPT
```
**Description**
Subtract `etl::chrono::weekday` from `etl::chrono::weekdays`.
**Return**
`etl::chrono::weekdays`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::weekdays operator -(const etl::chrono::weekday& m1,
const etl::chrono::weekday& m2) ETL_NOEXCEPT
```
**Description**
Subtract `etl::chrono::weekday` from `etl::chrono::weekday`.
**Return**
`etl::chrono::weekdays`.
## Non-member comparison operators
```cpp
ETL_CONSTEXPR14
bool operator ==(const etl::chrono::weekday& m1,
const etl::chrono::weekday& m2)
ETL_NOEXCEPT
```
**Description**
Equality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator !=(const etl::chrono::weekday& m1,
const etl::chrono::weekday& m2)
ETL_NOEXCEPT
```
**Description**
Inequality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <(const etl::chrono::weekday& m1,
const etl::chrono::weekday& m2)
ETL_NOEXCEPT
```
**Description**
Less-than operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <=(const etl::chrono::weekday& m1,
const etl::chrono::weekday& m2)
ETL_NOEXCEPT
```
**Description**
Less-than-or-equal operator.
---
```cpp
ETL_CONSTEXPR14
bool operator >(const etl::chrono::weekday& m1,
const etl::chrono::weekday& m2)
ETL_NOEXCEPT
```
**Description**
Greater-than operator.
---
```cpp
ETL_CONSTEXPR14
bool operator >=(const etl::chrono::weekday& m1,
const etl::chrono::weekday& m2)
ETL_NOEXCEPT
```
**Description**
Greater-than-or-equal operator.
---
```cpp
[[nodiscard]] inline constexpr
auto operator <=>(const etl::chrono::weekday& m1,
const etl::chrono::weekday& m2)
noexcept
```
**Description**
Spaceship operator.
C++20
## Defined weekdays
```cpp
etl::chrono::Monday
etl::chrono::Tuesday
etl::chrono::Wednesday
etl::chrono::Thursday
etl::chrono::Friday
etl::chrono::Saturday
etl::chrono::Sunday
```
## Hash
```cpp
template <>
struct hash<etl::chrono::weekday>
```
**Description**
Hash function for `etl::chrono::weekday`.

View File

@ -0,0 +1,127 @@
---
title: "weekday_indexed"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::weekday_indexed](https://en.cppreference.com/w/cpp/chrono/weekday_last.html)
{{< /callout >}}
A class representing an indexed weekday.
```cpp
class weekday_indexed
```
## Construction
```cpp
ETL_CONSTEXPR
weekday_indexed()
ETL_NOEXCEPT
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR14
weekday_indexed(const etl::chrono::weekday& wd, unsigned index)
ETL_NOEXCEPT
```
**Description**
Construct from `weekday` and `index`.
---
```cpp
ETL_CONSTEXPR14
weekday_indexed(const etl::chrono::weekday_indexed& other)
ETL_NOEXCEPT
```
**Description**
Copy constructor.
## Tests
ETL_NODISCARD
ETL_CONSTEXPR14
bool ok() const
ETL_NOEXCEPT
**Return**
`true` if the weekday_indexed is valid
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
bool is_weekend() const
ETL_NOEXCEPT
```
**Return**
`true` if the `weekday_indexed` is a `Saturday` or `Sunday`.
## Assignment
```cpp
ETL_CONSTEXPR14
etl::chrono::weekday_indexed& operator =(const etl::chrono::weekday_indexed& rhs)
ETL_NOEXCEPT
```
**Description**
Assignment operator
## Access
```cpp
ETL_CONSTEXPR14
etl::chrono::weekday weekday() const
ETL_NOEXCEPT
```
**Description**
Gets the weekday.
---
```cpp
ETL_CONSTEXPR14
unsigned index() const
ETL_NOEXCEPT
```
**Description**
Gets the index.
## Non-member comparison operators
```cpp
ETL_CONSTEXPR14
bool operator ==(const etl::chrono::weekday_indexed& m1,
const etl::chrono::weekday_indexed& m2)
ETL_NOEXCEPT
```
**Description**
Equality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator !=(const etl::chrono::weekday_indexed& m1,
const etl::chrono::weekday_indexed& m2)
ETL_NOEXCEPT
```
**Description**
Inequality operator.
## Hash
```cpp
template <>
struct hash<etl::chrono::weekday_indexed>
```
**Description**
Hash function for `etl::chrono::weekday_indexed`.

View File

@ -0,0 +1,107 @@
---
title: "weekday_last"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::weekday_last](https://en.cppreference.com/w/cpp/chrono/weekday_last.html)
{{< /callout >}}
A class representing the last day of a weekday.
```cpp
class weekday_last
```
## Construction
```cpp
ETL_CONSTEXPR
weekday_last()
ETL_NOEXCEPT
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR14
weekday_last(const etl::chrono::weekday& wd)
ETL_NOEXCEPT
```
**Description**
Construct from weekday and index.
---
```cpp
ETL_CONSTEXPR14
weekday_last(const etl::chrono::weekday_last& other)
ETL_NOEXCEPT
```
**Description**
Copy constructor.
---
## Tests
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
bool ok() const
ETL_NOEXCEPT
```
**Return**
`true` if the weekday_last valid.
## Assignment
```cpp
ETL_CONSTEXPR14
etl::chrono::weekday_last& operator =(const etl::chrono::weekday_last& rhs)
ETL_NOEXCEPT
```
**Description**
Assignment operator
## Access
```cpp
ETL_CONSTEXPR14
etl::chrono::weekday weekday() const
ETL_NOEXCEPT
```
**Description**
Gets the weekday.
## Non-member comparison operators
```cpp
ETL_CONSTEXPR14
bool operator ==(const etl::chrono::weekday_last& m1,
const etl::chrono::weekday_last& m2)
ETL_NOEXCEPT
```
**Description**
Equality operator.
---
ETL_CONSTEXPR14
bool operator !=(const etl::chrono::weekday_last& m1,
const etl::chrono::weekday_last& m2)
ETL_NOEXCEPT
**Description**
Inequality operator.
## Hash
```cpp
template <>
struct hash<etl::chrono::weekday_last>
```
**Description**
Hash function for `etl::chrono::weekday_last`.

View File

@ -0,0 +1,17 @@
---
title: "Years"
weight: 100
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono](https://en.cppreference.com/w/cpp/chrono.html)
{{< /callout >}}
Classes that represent years.
`etl::chrono::year`
`etl::chrono::year_month`
`etl::chrono::year_month_day`
`etl::chrono::year_month_day_last`

328
docs/chrono/year/year.md Normal file
View File

@ -0,0 +1,328 @@
---
title: "year"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::year](https://en.cppreference.com/w/cpp/chrono/year.html)
{{< /callout >}}
A class representing a year.
```cpp
class year
```
## Member types
`rep` The internal representation.
## Construction
```cpp
ETL_CONSTEXPR
year()
ETL_NOEXCEPT
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR
explicit year(unsigned value)
ETL_NOEXCEPT
```
**Description**
Construct from unsigned.
---
```cpp
ETL_CONSTEXPR14
year(const etl::chrono::year& other)
ETL_NOEXCEPT
```
**Description**
Copy constructor.
## Tests
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
int compare(const etl::chrono::year& other) const
ETL_NOEXCEPT
```
**Description**
Compare day with another.
if `year < other`, returns `-1`
else if `year > other`, returns `1`
else returns `0`
## Assignment
```cpp
ETL_CONSTEXPR14
etl::chrono::year& operator =(const etl::chrono::year& rhs)
ETL_NOEXCEPT
```
**Description**
Assignment operator
## Increment / decrement
```cpp
ETL_CONSTEXPR14
etl::chrono::year& operator ++()
ETL_NOEXCEPT
```
**Description**
Pre-increment operator.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year operator ++(int)
ETL_NOEXCEPT
```
**Description**
Post-increment operator.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year& operator --()
ETL_NOEXCEPT
```
**Description**
Pre-decrement operator.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year operator --(int)
ETL_NOEXCEPT
```
**Description**
Post-decrement operator.
## Mathematical operators
```cpp
ETL_CONSTEXPR14
etl::chrono::year& operator +=(const etl::chrono::years& ys)
ETL_NOEXCEPT
```
**Description**
Plus-equals operator adding etl::chrono::years.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year& operator -=(const etl::chrono::years& ys)
ETL_NOEXCEPT
```
**Description**
Minus-equals operator subtracting etl::chrono::years.
## Tests
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
bool ok() const
ETL_NOEXCEPT
```
**Description**
Returns true if the year is within the valid -32767 to 32767 range.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
bool is_leap() const
ETL_NOEXCEPT
```
**Description**
Returns true if the year is a leap year.
## Constants
```cpp
ETL_NODISCARD
static
ETL_CONSTEXPR14
etl::chrono::year min()
ETL_NOEXCEPT
```
**Description**
The minimum year value for which ok() will return true.
---
```cpp
ETL_NODISCARD
static
ETL_CONSTEXPR14
etl::chrono::year max()
ETL_NOEXCEPT
```
**Description**
The maximum year value for which ok() will return true.
## Conversion
```cpp
ETL_CONSTEXPR14
operator int() const
ETL_NOEXCEPT
```
**Description**
Conversion operator to `unsigned int`.
## Non-member mathematical operators
```cpp
ETL_CONSTEXPR14
etl::chrono::year operator +(const etl::chrono::year& y,
const etl::chrono::years& ys)
ETL_NOEXCEPT
```
**Description**
Add `etl::chrono::years` to `etl::chrono::year`.
**Return**
`etl::chrono::year`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year operator +(const etl::chrono::years& ys,
const etl::chrono::year& y)
ETL_NOEXCEPT
```
**Description**
Add `etl::chrono::year` to `etl::chrono::years`.
**Return**
`etl::chrono::year`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year operator -(const etl::chrono::year& y,
const etl::chrono::years& ys)
ETL_NOEXCEPT
```
**Description**
Subtract `etl::chrono::years` from `etl::chrono::year`.
**Return**
`etl::chrono::year`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year operator -(const etl::chrono::years& ys,
const etl::chrono::year& y)
ETL_NOEXCEPT
```
**Description**
Subtract `etl::chrono::year` from `etl::chrono::years`.
**Return**
`etl::chrono::years`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::years operator -(const etl::chrono::year& y1,
const etl::chrono::year& y2) ETL_NOEXCEPT
```
**Description**
Subtract `etl::chrono::year` from `etl::chrono::year`.
**Return**
`etl::chrono::years`.
## Non-member comparison operators
```cpp
ETL_CONSTEXPR14
bool operator ==(const etl::chrono::year& y1,
const etl::chrono::year& y2)
ETL_NOEXCEPT
```
**Description**
Equality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator !=(const etl::chrono::year& y1,
const etl::chrono::year& y2)
ETL_NOEXCEPT
```
**Description**
Inequality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <(const etl::chrono::year& y1,
const etl::chrono::year& y2)
ETL_NOEXCEPT
```
**Description**
Less-than operator.
---
```cpp
ETL_CONSTEXPR14
bool operator <=(const etl::chrono::year& y1,
const etl::chrono::year& y2)
ETL_NOEXCEPT
```
**Description**
Less-than-or-equal operator.
---
```cpp
ETL_CONSTEXPR14
bool operator >(const etl::chrono::year& y1,
const etl::chrono::year& y2)
ETL_NOEXCEPT
```
**Description**
Greater-than operator.
---
```cpp
ETL_CONSTEXPR14
bool operator >=(const etl::chrono::year& y1,
const etl::chrono::year& y2)
ETL_NOEXCEPT
```
**Description**
Greater-than-or-equal operator.
---
```cpp
[[nodiscard]] inline constexpr
auto operator <=>(const etl::chrono::year& y1,
const etl::chrono::year& y2)
noexcept
```
**Description**
Spaceship operator.
C++20
## Hash
```cpp
template <typename TRep, typename TPeriod>
struct hash<etl::chrono::year>
```
**Description**
Hash function for `etl::chrono::year`.

View File

@ -0,0 +1,214 @@
---
title: "year_month"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::year_month](https://en.cppreference.com/w/cpp/chrono/year_month.html)
{{< /callout >}}
A class representing a year and month.
```cpp
class year_month
```
## Construction
```cpp
ETL_CONSTEXPR
year_month()
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR14
year_month(const etl::chrono::year& y,
const etl::chrono::month& m)
ETL_NOEXCEPT
```
**Description**
Construct from month and day.
## Access
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::year year() const
ETL_NOEXCEPT
```
**Return**
The year.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::month month() const
ETL_NOEXCEPT
```
**Return**
The month.
## Tests
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
bool ok() const
ETL_NOEXCEPT
```
**Return**
`true` if the year and month is within the valid limits.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
int compare(const etl::chrono::year_month& other) const
ETL_NOEXCEPT
```
**Description**
If `y < other.y` return `-1`
If `y > other.y` return `1`
If `m < other.m` return `-1`
If `m > other.m` return `1`
Else return `0`
## Non-member mathematical operators
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month operator +(const etl::chrono::year_month& ym,
const etl::chrono::years& dy)
```
**Description**
Adds `etl::chrono::years`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month operator +(const etl::chrono::years& dy,
const etl::chrono::year_month& ym)
ETL_NOEXCEPT
```
**Description**
Adds `etl::chrono::years`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month operator +(const etl::chrono::year_month& ym,
const etl::chrono::months& dm)
ETL_NOEXCEPT
```
**Description**
Adds `etl::chrono::months`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month operator +(const etl::chrono::months& dm,
const etl::chrono::year_month& ym)
ETL_NOEXCEPT
```
**Description**
Adds `etl::chrono::months`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month operator -(const etl::chrono::year_month& ym,
const etl::chrono::years& dy)
ETL_NOEXCEPT
```
**Description**
Subtracts `etl::chrono::years`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month operator -(const etl::chrono::year_month& ym,
const etl::chrono::months& dm)
ETL_NOEXCEPT
```
**Description**
Subtracts `etl::chrono::months`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::months operator -(const etl::chrono::year_month& ym1,
const etl::chrono::year_month& ym2)
ETL_NOEXCEPT
```
**Description**
Subtracts `etl::chrono::year_month`.
## Non-member comparison operators
```cpp
ETL_CONSTEXPR14
bool operator ==(const etl::chrono::year_month& lhs,
const etl::chrono::year_month& rhs)
ETL_NOEXCEPT
```
**Description**
Equality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator !=(const etl::chrono::year_month& lhs,
const etl::chrono::year_month& rhs)
ETL_NOEXCEPT
```
**Description**
Inequality operator.
---
```cpp
[[nodiscard]] friend constexpr
auto operator <=>(const etl::chrono::year_month& lhs,
const etl::chrono::year_month& rhs)
ETL_NOEXCEPT
```
**Description**
Spaceship operator
C++20
---
```
ETL_CONSTEXPR14
int compare(const year_month& other) const
ETL_NOEXCEPT
```
**Description**
Compare year_month with another.
if `month < other.month`, returns `-1`
else if `month > other.month`, returns `1`
else if `day < other.day`, returns `-1`
else if `day > other.day`, returns `1`
else returns `0`;
## Hash
template <typename TRep, typename TPeriod>
struct hash<etl::chrono::year_month>
**Description**
Hash function for `etl::chrono::year_month`.

View File

@ -0,0 +1,277 @@
---
title: "year_month_day"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::year_month_day](https://en.cppreference.com/w/cpp/chrono/year_month_day.html)
{{< /callout >}}
A class representing a year, month, and day.
```cpp
class year_month_day
```
## Construction
```cpp
ETL_CONSTEXPR year_month_day()
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR14
year_month_day(const etl::chrono::year& y,
const etl::chrono::month& m,
const etl::chrono::day& d)
ETL_NOEXCEPT
```
**Description**
Construct from `month` and `day`.
---
```cpp
ETL_CONSTEXPR14
year_month_day(const etl::chrono::year_month_day_last& ymdl)
ETL_NOEXCEPT
```
**Description**
Construct from `year_month_day_last`.
---
```cpp
ETL_CONSTEXPR14
year_month_day(const etl::chrono::sys_days& sd)
ETL_NOEXCEPT
```
**Description**
Construct from `sys_days`.
---
```cpp
ETL_CONSTEXPR14
year_month_day(const etl::chrono::local_days& ld)
ETL_NOEXCEPT
```
**Description**
Construct from `local_days`.
## Access
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::year year() const
ETL_NOEXCEPT
```
**Return**
The year.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::month month() const
ETL_NOEXCEPT
```
**Return**
The month.
---
```
ETL_NODISCARD
ETL_CONSTEXPR14 etl::chrono::day day() const
ETL_NOEXCEPT
```
**Return**
The day.
## Tests
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
bool ok() const
ETL_NOEXCEPT
```
**Return**
`true` if the year and month is within the valid limits.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
int compare(const etl::chrono::year_month_day& other) const
ETL_NOEXCEPT
```
**Description**
Compare `year_month_day` with another.
if `year < other.year`, returns `-1`
else if `year > other.year`, returns `1`
if `month < other.month`, returns `-1`
else if `month > other.month`, returns `1`
else if `day < other.day`, returns `-1`
else if `day > other.day`, returns `1`
else returns `0`
## operators
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day& operator +=(const etl::chrono::years& dy)
ETL_NOEXCEPT
```
**Description**
Adds `etl::chrono::years`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day& operator +=(const etl::chrono::months& dm)
ETL_NOEXCEPT
```
**Description**
Adds `etl::chrono::months`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day& operator -=(const etl::chrono::years& dy)
ETL_NOEXCEPT
```
**Description**
Subtracts `etl::chrono::years`.
---
```
ETL_CONSTEXPR14
etl::chrono::year_month_day& operator -=(const etl::chrono::months& dm)
ETL_NOEXCEPT
```
**Description**
Subtracts `etl::chrono::months`.
## Non-member operators
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day operator +(const etl::chrono::year_month_day& ym,
const etl::chrono::years& dy)
```
**Description**
Adds `etl::chrono::years`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day operator +(const etl::chrono::years& dy,
const etl::chrono::year_month_day& ym)
ETL_NOEXCEPT
```
**Description**
Adds `etl::chrono::years`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day operator +(const etl::chrono::year_month_day& ym,
const etl::chrono::months& dm)
ETL_NOEXCEPT
```
**Description**
Adds `etl::chrono::months`.
---
```
ETL_CONSTEXPR14
etl::chrono::year_month operator +(const etl::chrono::months& dm,
const etl::chrono::year_month_day& ym)
ETL_NOEXCEPT
```
**Description**
Adds `etl::chrono::months`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month operator -(const etl::chrono::year_month_day& ym,
const etl::chrono::years& dy)
ETL_NOEXCEPT
```
**Description**
Subtracts `etl::chrono::years`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month operator -(const etl::chrono::year_month_day& ym,
const etl::chrono::months& dm)
ETL_NOEXCEPT
```
**Description**
Subtracts `etl::chrono::months`.
## Non-member comparison operators
```cpp
ETL_CONSTEXPR14
bool operator ==(const etl::chrono::year_month_day& lhs,
const etl::chrono::year_month_day& rhs)
ETL_NOEXCEPT
```
**Description**
Equality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator !=(const etl::chrono::year_month_day& lhs,
const etl::chrono::year_month_day& rhs)
ETL_NOEXCEPT
```
**Description**
Inequality operator.
---
```cpp
[[nodiscard]] friend constexpr
auto operator <=>(const etl::chrono::year_month_day& lhs,
const etl::chrono::year_month_day& rhs)
ETL_NOEXCEPT
```
**Description**
Spaceship operator
C++20
## Hash
```cpp
template <>
struct hash<etl::chrono::year_month_day>
```
**Description**
Hash function for `etl::chrono::year_month_day`.

View File

@ -0,0 +1,251 @@
---
title: "year_month_day_last"
---
{{< callout type="info">}}
Header: `chrono.h`
From: `20.41.0`
Similar to: [std::chrono::year_month_day_last](https://en.cppreference.com/w/cpp/chrono/year_month_day_last.html)
{{< /callout >}}
A class representing a year, month and last day.
```cpp
class year_month_day_last
```
## Construction
```cpp
ETL_CONSTEXPR year_month_day_last()
```
**Description**
Default constructor.
---
```cpp
ETL_CONSTEXPR14
year_month_day(const etl::chrono::year& y,
const etl::chrono::month_day_last& mdl)
ETL_NOEXCEPT
```
**Description**
Construct from month and day.
---
```cpp
ETL_CONSTEXPR14
year_month_day(const etl::chrono::year_month_day_last& ymdl)
ETL_NOEXCEPT
```
**Description**
Construct from `year_month_day_last`.
## Access
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::year year() const
ETL_NOEXCEPT
```
**Return**
The year.
---
```coo
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::month month() const
ETL_NOEXCEPT
```
**Return**
The month.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::month_day_last month_day_last() const
ETL_NOEXCEPT
```
**Returns**
The month.
## Tests
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
bool ok() const
ETL_NOEXCEPT
```
**Return**
`true` if the year and month is within the valid limits.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
int compare(const etl::chrono::year_month_day_last& other) const
ETL_NOEXCEPT
```
**Description**
Compare `year_month_day` with another.
if `year < other.year`, returns `-1`
else if `year > other.year`, returns `1`
if `month < other.month`, returns `-1`
else if `month > other.month`, returns `1`
else returns `0`
## operators
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day_last& operator +=(const etl::chrono::years& dy)
ETL_NOEXCEPT
```
Adds `etl::chrono::years`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day_last& operator +=(const etl::chrono::months& dm)
ETL_NOEXCEPT
```
**Description**
Adds `etl::chrono::months`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day_last& operator -=(const etl::chrono::years& dy)
ETL_NOEXCEPT
```
**Description**
Subtracts `etl::chrono::years`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day_last& operator -=(const etl::chrono::months& dm)
ETL_NOEXCEPT
```
**Description**
Subtracts `etl::chrono::months`.
## Non-member operators
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day_last operator +(const etl::chrono::year_month_day_last& ym,
const etl::chrono::years& dy)
```
**Description**
Adds `etl::chrono::years`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day_last operator +(const etl::chrono::years& dy,
const etl::chrono::year_month_day_last& ym)
ETL_NOEXCEPT
```
**Description**
Adds `etl::chrono::years`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day_last operator +(const etl::chrono::year_month_day_last& ym,
const etl::chrono::months& dm)
ETL_NOEXCEPT
```
**Description**
Adds `etl::chrono::months`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day_last operator +(const etl::chrono::months& dm,
const etl::chrono::year_month_day_last& ym)
ETL_NOEXCEPT
```
**Description**
Adds `etl::chrono::months`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_last operator -(const etl::chrono::year_month_day_last& ym,
const etl::chrono::years& dy)
ETL_NOEXCEPT
```
**Description**
Subtracts `etl::chrono::years`.
---
```cpp
ETL_CONSTEXPR14
etl::chrono::year_month_day_last operator -(const etl::chrono::year_month_day& ym,
const etl::chrono::months& dm)
ETL_NOEXCEPT
```
**Description**
Subtracts `etl::chrono::months`.
## Non-member comparison operators
```cpp
ETL_CONSTEXPR14
bool operator ==(const etl::chrono::year_month_day_last& lhs,
const etl::chrono::year_month_day_last& rhs)
ETL_NOEXCEPT
```
**Description**
Equality operator.
---
```cpp
ETL_CONSTEXPR14
bool operator !=(const etl::chrono::year_month_day_last& lhs,
const etl::chrono::year_month_day_last& rhs)
ETL_NOEXCEPT
```
**Description**
Inequality operator.
---
```cpp
[[nodiscard]] friend constexpr
auto operator <=>(const etl::chrono::year_month_day& lhs,
const etl::chrono::year_month_day& rhs)
ETL_NOEXCEPT
```
**Description**
Spaceship operator.
C++20
## Hash
```cpp
template <>
struct hash<etl::chrono::year_month_day_last>
```
**Description**
Hash function for `etl::chrono::year_month_day_last`.

6
docs/codecs/_index.md Normal file
View File

@ -0,0 +1,6 @@
---
title: "Codecs"
weight: 100
---
Encoder and decoder algorithms.

313
docs/codecs/base64.md Normal file
View File

@ -0,0 +1,313 @@
---
title: "Base64"
---
{{< callout type="info">}}
Headers:
`base64.h` Common definitions
`base64_encoder.h` Encoder class
`base64_decoder.h` Decoder class
From: `20.38.4`
{{< /callout >}}
Encodes and decodes data to and from Base64 format.
## Encode
**Input -> pointer/length : Output -> pointer/length**
```cpp
template <typename T>
ETL_CONSTEXPR14
static
size_t encode(const T* input, size_t input_length,
char* output, size_t output_length)
```
**Description**
Transforms the input data described by input and input_length to Base64 format to be stored in output output_length.
Enabled if `etl::is_integral<T>` is `true` and `etl::integral_limits<T>::bits == 8`.
**Return**
The length of the encoded data.
**Error**
If output_length is not large enough to hold the encoded data then an `etl::base64_overflow` is raised.
---
**Input -> pointer/length : Output -> string**
```cpp
template <typename T>
ETL_CONSTEXPR14
static
size_t encode(const T* input, size_t input_length,
etl::istring& output)
```
**Description**
Transforms the input data described by input and input_length to Base64 format to be stored in output.
Enabled if `etl::is_integral<T>` is `true` and `etl::integral_limits<T>::bits == 8`.
The output string must have capacity of at least `etl::base64::encode_size(input)`.
**Return**
The length of the encoded data.
**Error**
If output_length is not large enough to hold the encoded data then an `etl::base64_overflow` is raised.
---
**Input -> pointer/pointer : Output -> pointer/pointer**
```cpp
template <typename T>
ETL_CONSTEXPR14
static
size_t encode(const T* input_begin, const T* input_end,
char* output_begin, char* output_end)
```
**Description**
Transforms the input data described by input_begin and input_end to Base64 format to be stored in output_begin to output_end.
Enabled if `etl::is_integral<T>` is `true` and `etl::integral_limits<T>::bits == 8`.
**Return**
The length of the encoded data.
**Error**
If the output buffer is not large enough to hold the encoded data then an `etl::base64_overflow` is raised.
---
**Input -> pointer/pointer : Output -> string**
```cpp
template <typename T>
ETL_CONSTEXPR14
static
size_t encode(const T* input_begin, const T* input_end,
etl::istring& output)
```
**Description**
Transforms the input data described by input_begin and input_end to Base64 format to be stored in output.
Enabled if `etl::is_integral<T>` is `true` and `etl::integral_limits<T>::bits == 8`.
The output string must have capacity of at least `etl::base64::encode_size(input)`.
**Return**
The length of the encoded data.
**Error**
If the output buffer is not large enough to hold the encoded data then an `etl::base64_overflow` is raised.
---
**Input -> span : Output -> span**
```cpp
template <typename T, size_t Length1, size_t Length2>
ETL_CONSTEXPR14
static
size_t encode(const etl::span<const T, Length1>& input_span,
const etl::span<char, Length2>& output_span)
```
**Description**
Transforms the input data described by input_span to Base64 format to be stored in output_span.
Enabled if etl::is_integral<T> is true and etl::integral_limits<T>::bits == 8.
**Return**
The length of the encoded data.
**Error**
If the output span is not large enough to hold the encoded data then an etl::base64_overflow is raised.
---
**Input -> span : Output -> string**
```cpp
template <typename T, size_t Length>
ETL_CONSTEXPR14
static
size_t encode(const etl::span<const T, Length>& input_span,
etl::istring& output)
```
**Description**
Transforms the input data described by input_span to Base64 format to be stored in output.
Enabled if etl::is_integral<T> is true and etl::integral_limits<T>::bits == 8
The output string must have capacity of at least etl::base64::encode_size(input).
**Return**
The length of the encoded data.
**Error**
If the output span is not large enough to hold the encoded data then an etl::base64_overflow is raised.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
static
size_t encode_size(size_t input_length)
```
**Return**
Returns the size of the output buffer required to encode the specified input data length.
## Decode
**Input -> pointer/length : Output -> pointer/length**
```cpp
template <typename T>
ETL_CONSTEXPR14
static
size_t decode(const char* input, size_t input_length,
T* output, size_t output_length)
```
**Description**
Transforms the Base64 format input data described by input and input_length to by output and output_length.
Enabled if `etl::is_integral<T>` is `true` and `etl::integral_limits<T>::bits == 8`.
**Return**
The length of the decoded data.
**Error**
If `output_length` is not large enough to hold the decoded data then an `etl::base64_overflow` is raised.
---
**Input -> pointer/pointer: Output -> pointer/pointer**
```cpp
template <typename T>
ETL_CONSTEXPR14
static
size_t decode(const char* input_begin, const char* input_end,
T* output_begin, T* output_end)
```
**Description***
Transforms the Base64 format input data described by `input_begin` and `input_end` to `output_begin` and `output_end`.
Enabled if `etl::is_integral<T>` is `true` and `etl::integral_limits<T>::bits == 8`.
**Return**
The length of the decoded data.
**Error**
If the output buffer is not large enough to hold the decoded data then an `etl::base64_overflow` is raised.
---
**Input -> span: Output -> span**
```cpp
template <typename T, size_t Length1, size_t Length2>
ETL_CONSTEXPR14
static
size_t decode(const etl::span<const char, Length1>& input_span,
const etl::span<T, Length2>& output_span)
```
**Description**
Transforms the Base64 format input data described by input_span to output_span.
Enabled if `etl::is_integral<T>` is `true` and `etl::integral_limits<T>::bits == 8`.
**Return**
The length of the decoded data.
**Error**
If the output span is not large enough to hold the decoded data then an `etl::base64_overflow` is raised.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
static
size_t decode_size(const char* input, size_t input_length)
```
**Return**
The size of the output buffer required to decode the specified input Base64 data length.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
static
size_t decode_size(const char* input_begin, const char* input_end)
```
**Return**
The size of the output buffer required to decode the specified input Base64 data length.
---
```cpp
ETL_NODISCARD
ETL_CONSTEXPR14
static
size_t decode_size(etl::span<const char> input)
```
**Return**
The size of the output buffer required to decode the specified input Base64 data length.
## Examples
### Encode
```cpp
const etl::array<int8_t, 12> input =
{
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20,
0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21 // "Hello World!"
};
etl::string<20> encoded;
size_t encoded_size = etl::base64::encode(input.data(), input.size(),
encoded.data(), encoded.size());
encoded.resize(encoded_size);
// encoded == "OycDQy37KCphrg=="
```
---
*For C++14 or above*
```cpp
const etl::array<int8_t, 12> input =
{
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20,
0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21 // "Hello World!"
};
constexpr size_t length = etl::base64::encode_size(input.size());
etl::string<length> output;
output.uninitialized_resize(output.capacity());
etl::base64::encode(input.data(), input.size(), output.data(), output.size());
// output == "OycDQy37KCphrg=="
```
---
### Decode
```cpp
const etl::string<16> encoded = "OycDQy37KCphrg==";
etl::vector<int8_t, 20> output;
size_t decoded_size = etl::base64::decode(encoded.data(), encoded.size(),
output.data(), output.size());
output.resize(decoded_size);
// output == { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20,
// 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21 };
```
---
*For C++14 or above*
```cpp
// "OycDQy37KCphrg=="
constexpr const etl::array<char, 16> input =
{
0x4F, 0x79, 0x63, 0x44, 0x51, 0x79, 0x33, 0x37,
0x4B, 0x43, 0x70, 0x68, 0x72, 0x67, 0x3D, 0x3D
};
constexpr size_t length = etl::base64::decode_size(input.data(), input.size());
etl::vector<int8_t, length> output;
etl::base64::decode(input.data(), input.size(), output.data(), output.size());
// output == { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20,
// 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21 };
```

View File

@ -1,8 +1,14 @@
---
title: Manchester encoding and decoding
weight: 1
---
Efficient Manchester encoding and decoding of data. The Manchester code represents a data bit as a sequence of a 'high' and a 'low' value. In software this translates to a conversion from one to two bits, or in a practical situation, from `n` bytes to `n*2` bytes.
{{< callout type="info">}}
Header: `manchester.h`
Support: `20.45.0`
{{< /callout >}}
Efficient Manchester encoding and decoding of data. The Manchester code represents a data bit as a sequence of a 'high' and a 'low' values. In software this translates to a conversion from one to two bits, or in a practical situation, from `n` bytes to `n*2` bytes.
## See also
@ -58,13 +64,11 @@ Comparing all 8 bit pairs in a 16-bit word is done as follows.
Most traditional ways to Manchester encode data consist of a loop over all bits and a nested if-statement to check the value of the current bit. This approach does not scale well to increasing number of bits. The algorithm implemented here contains no conditional code and scales well. Doubling the number of processed bits per step (the chunk size) adds a single row to the bit duplication table. Because of the lack of loops and conditional code, this algorithm is likely to perform better than traditional ones on simple processors or when compiler optimization is disabled. On modern, powerful processors with caches and advanced optimization possibilities this algorithm may not show much benefit. In any case, the performance of the algorithm depends heavily on the processor type, compiler and compiler (optimization) settings.
## API Reference
### Classes
## Classes
Classes `etl::manchester` and `etl::manchester_inverted` contain static functions for encoding, decoding and validity checking. It is not necessary to instantiate objects of these classes.
#### etl::manchester
### etl::manchester
```cpp
typedef manchester_base<private_manchester::manchester_type_normal> manchester;
@ -72,7 +76,7 @@ typedef manchester_base<private_manchester::manchester_type_normal> manchester;
Manchester encoder using normal encoding (no inversion).
#### etl::manchester_inverted
### etl::manchester_inverted
```cpp
typedef manchester_base<private_manchester::manchester_type_inverted> manchester_inverted;
@ -80,9 +84,9 @@ typedef manchester_base<private_manchester::manchester_type_inverted> manchester
Manchester encoder using inverted encoding.
### Encoding Functions
## Encoding Functions
#### Encode single value
### Encode single value
```cpp
template <typename TDecoded>
@ -91,21 +95,21 @@ static ETL_CONSTEXPR14 typename encoded<TDecoded>::type encode(TDecoded decoded)
Encodes a single value using Manchester encoding.
**Parameters:**
**Parameters**
- `decoded`: The value to encode (`uint8_t`, `uint16_t`, or `uint32_t`)
`decoded`: The value to encode (`uint8_t`, `uint16_t`, or `uint32_t`)
**Returns:**
**Returns**
- The Manchester encoded value (twice the bit width of input)
The Manchester encoded value (twice the bit width of input)
**Example:**
**Example**
```cpp
uint16_t encoded = etl::manchester::encode(0x55);
```
#### Encode range
### Encode range
```cpp
template <typename TChunk = uint_least8_t>
@ -115,16 +119,16 @@ static ETL_CONSTEXPR14 void encode(etl::span<const uint_least8_t> decoded,
Encodes a span of data using the specified chunk size.
**Parameters:**
**Parameters**
- `decoded`: Source data to encode
- `encoded`: Destination for encoded data (must be twice the size of `decoded`)
`decoded`: Source data to encode
`encoded`: Destination for encoded data (must be twice the size of `decoded`)
**Template Parameters:**
**Template Parameters**
- `TChunk`: Chunk size for encoding (`uint8_t`, `uint16_t` or `uint32_t`)
`TChunk`: Chunk size for encoding (`uint8_t`, `uint16_t` or `uint32_t`)
**Example:**
**Example**
```cpp
std::array<uint8_t, 4> data = {0x12, 0x34, 0x56, 0x78};
@ -138,51 +142,56 @@ etl::manchester::encode(data, encoded_data1);
etl::manchester::encode<uint32_t>(data, encoded_data2);
```
### Decoding Functions
## Decoding Functions
#### Decode single value
### Decode single value
```cpp
template <typename TEncoded>
static ETL_CONSTEXPR14 typename decoded<TEncoded>::type decode(TEncoded encoded)
```
**Description**
Decodes a single Manchester encoded value.
**Parameters:**
**Parameters**
- `encoded`: The encoded value to decode (`uint16_t`, `uint32_t`, or `uint64_t`)
`encoded`: The encoded value to decode (`uint16_t`, `uint32_t`, or `uint64_t`)
**Returns:**
**Returns**
- The Manchester decoded value (half the bit width of input)
The Manchester decoded value (half the bit width of input)
**Example:**
**Example**
```cpp
uint8_t decoded = etl::manchester::decode(0x5A5A);
```
---
#### Decode range
### Decode range
```cpp
template <typename TChunk = typename private_manchester::encoded<uint_least8_t>::type>
static ETL_CONSTEXPR14 void decode(etl::span<const uint_least8_t> encoded,
etl::span<uint_least8_t> decoded)
template <typename TChunk =
typename private_manchester::encoded<uint_least8_t>::type>
static ETL_CONSTEXPR14
void decode(etl::span<const uint_least8_t> encoded,
etl::span<uint_least8_t> decoded)
```
Decodes a span of Manchester encoded data.
**Parameters:**
**Parameters**
- `encoded`: Source data to decode
- `decoded`: Destination for decoded data (must be half the size of `encoded`)
`encoded`: Source data to decode
`decoded`: Destination for decoded data (must be half the size of `encoded`)
**Template Parameters:**
**Template Parameters**
- `TChunk`: Chunk type for decoding (`uint16_t`, `uint32_t`, or `uint64_t`)
`TChunk`: Chunk type for decoding (`uint16_t`, `uint32_t`, or `uint64_t`)
**Example:**
**Example**
```cpp
std::array<uint8_t, 8> encoded = {/* ... */};
@ -196,9 +205,9 @@ etl::manchester::decode(encoded, decoded1);
etl::manchester::decode<uint64_t>(encoded, decoded2);
```
### Validation Functions
## Validation Functions
#### Single value
### Single value
```cpp
template <typename TChunk>
@ -207,53 +216,53 @@ static ETL_CONSTEXPR14 bool is_valid(TChunk encoded)
Validates that a single value contains valid Manchester encoded data.
**Parameters:**
**Parameters**
- `encoded`: The encoded value to validate
`encoded`: The encoded value to validate
**Returns:**
**Returns**
- `true` if the value contains valid Manchester encoded data, `false` otherwise
`true` if the value contains valid Manchester encoded data, `false` otherwise
**Example:**
**Example**
```cpp
bool valid = etl::manchester::is_valid(0x5A5A);
```
#### Range
### Range
```cpp
static ETL_CONSTEXPR14 bool is_valid(etl::span<const uint_least8_t> encoded)
static
ETL_CONSTEXPR14
bool is_valid(etl::span<const uint_least8_t> encoded)
```
Validates that a range contains valid Manchester encoded data.
**Parameters:**
**Parameters**
- `encoded`: The range of encoded data to validate
`encoded`: The range of encoded data to validate
**Returns:**
**Returns**
- `true` if all data is valid Manchester encoding, `false` otherwise
`true` if all data is valid Manchester encoding, `false` otherwise
**Example:**
**Example**
```cpp
std::array<uint8_t, 8> encoded_data = {/* ... */};
bool valid = etl::manchester::is_valid(encoded_data);
```
## Supported Types
## Input/chunk types for encoding
### Input/chunk types for encoding
`uint8_t` → `uint16_t` (if 8-bit types are supported)
`uint16_t` → `uint32_t`
`uint32_t` → `uint64_t` (if 64-bit types are supported)
- `uint8_t` → `uint16_t` (if 8-bit types are supported)
- `uint16_t` → `uint32_t`
- `uint32_t` → `uint64_t` (if 64-bit types are supported)
## Input/chunk types for decoding
### Input/chunk types for decoding
- `uint16_t` → `uint8_t` (if 8-bit types are supported)
- `uint32_t` → `uint16_t`
- `uint64_t` → `uint32_t` (if 64-bit types are supported)
`uint16_t` → `uint8_t` (if 8-bit types are supported)
`uint32_t` → `uint16_t`
`uint64_t` → `uint32_t` (if 64-bit types are supported)

View File

@ -0,0 +1,6 @@
---
title: "Views"
weight: 100
---
View like containers.

View File

@ -0,0 +1,373 @@
---
title: "array_view"
---
{{< callout >}}
Header: `array_view.h`
Since: All versions
Similar to: [gsl::array_view](https://learn.microsoft.com/en-us/previous-versions/cpp/parallel/amp/reference/array-view-class)
{{< /callout >}}
This class implements a view in to a range of a C array, `etl::array`, `std::array`, `etl::vector` and `std::vector`.
It will support construction from any class that supports data() and size() member functions as well as plain C arrays.
If `ETL_ARRAY_VIEW_IS_MUTABLE` is defined, then the contents of the view are mutable.
The view is non-mutable by default, which is the opposite to the behaviour in 17.5.0 or earlier.
```cpp
etl::array_view<typename T>
```
## Template deduction guides
**C++17 and above**
```cpp
template <typename TArray>
etl::array_view(TArray& a)
-> etl::array_view<typename TArray::value_type>;
```
```cpp
template <typename TIterator>
etl::array_view(const TIterator begin_, const TIterator end_)
-> etl::array_view<etl::remove_pointer_t<TIterator>>;
```
```cpp
template <typename TIterator, typename TSize>
etl::array_view(const TIterator begin_, const TSize size_)
-> etl::array_view<etl::remove_pointer_t<TIterator>>;
```
## Examples
```cpp
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array_view view1{ data };
etl::array_view view2{ data.begin(), data.end() };
etl::array_view view3{ data.begin(), data.size() };
etl::array_view view4{ view1 };
```
## Member types
`value_type`
`size_type`
`difference_type`
`reference`
`const_reference`
`pointer`
`const_pointer`
`iterator`
`const_iterator`
`reverse_iterator`
`const_reverse_iterator`
## Constructors
```cpp
ETL_CONSTEXPR array_view()
```
**Description**
Default constructor.
---
```cpp
template <typename TArray>
ETL_CONSTEXPR explicit array_view(TArray& a)
```
**Description**
Construct from array or vector like class.
---
```cpp
template <typename TIterator>
ETL_CONSTEXPR array_view(TIterator begin_, TIterator end_)
```
**Description**
Construct from an iterator or pointer range.
---
```cpp
template <typename TIterator, typename TSize>
ETL_CONSTEXPR array_view(TIterator begin_, TSize size_)
```
**Description**
Construct from a start and size
---
```cpp
template<const size_t ARRAY_SIZE>
ETL_CONSTEXPR explicit array_view(T(&begin_)[ARRAY_SIZE])
```
**Description**
Construct from a compile time sized C array.
---
```cpp
ETL_CONSTEXPR array_view(const array_view& other)
```
**Description**
Copy constructor.
## Modifiers
```cpp
template <typename TIterator>
void assign(TIterator begin_, TIterator end_)
```
**Description**
Assigns begin and end of the supplied range.
Does not copy the elements in the range.
---
```cpp
template <typename TIterator, typename TSize>
void assign(TIterator begin_, TSize size_)
```
**Description**
Assign from a start iterator and length.
Does not copy the elements in the range.
---
```cpp
void remove_prefix(size_type n)
```
**Description**
Shrinks the view from the front.
A value of `n` larger than the array will result in undefined behaviour.
---
```cpp
void remove_suffix(size_type n)
```
**Description**
Shrinks the view from the back.
A value of `n` larger than the array will result in undefined behaviour.
---
```cpp
void fill(value_type value)
```
*Introduced:* `20.24.0`
**Description**
Fill the underlying array with value.
## Element access
Mutable access is only possible by defining the macro `ETL_ARRAY_VIEW_IS_MUTABLE`.
In this case, `reference`, `pointer`, `iterator` and `reverse_iterator` are defined as their `const` counterparts.
```cpp
reference at(size_t i)
const_reference at(size_t i) const
```
**Description**
Gets a reference or const reference to the indexed element.
Emits an `etl::array_view_uninitialised` if the view is not initialised.
Emits an `etl::array_view_bounds` if the index is not in range.
If asserts or exceptions are not enabled then undefined behaviour occurs.
**Parameters**
`i` The index.
**Returns**
A reference or const reference to the indexed element
---
```cpp
reference operator[](size_t i)
const_reference operator[](size_t i) const
```
**Description**
Gets a reference or const reference to the indexed element.
**Returns**
A reference or const reference to the indexed element.
Undefined behaviour if the `array_view` is empty.
---
```cpp
reference front()
const_reference front() const
```
**Description**
Gets a reference or const reference to the first element.
**Returns**
A reference or const reference to the first element.
Undefined behaviour if the `array_view` is empty.
---
```cpp
reference back()
const_reference back() const
```
**Description**
Gets a reference or const reference to the last element.
**Returns**
A reference or const reference to the last element.
Undefined behaviour if the `array_view` is empty.
---
```cpp
pointer data()
const_pointer data() const
```
**Description**
Gets a pointer or const pointer to the first element.
**Returns**
A pointer or const pointer to the first element.
Equal to `end()` if the array_view is empty.
## Iterators
```cpp
iterator begin()
const_iterator begin() const
const_iterator cbegin() const
```
**Description**
Returns an iterator to the beginning of the array view.
---
```cpp
iterator end()
const_iterator end() const
const_iterator cend() const
```
**Description**
Returns an iterator to the end of the array view.
---
```cpp
iterator rbegin()
const_iterator rbegin() const
const_iterator crbegin() const
```
**Description**
Gets a reverse iterator to the beginning of the array view.
---
```cpp
iterator rend()
const_iterator rend() const
const_iterator crend() const
```
**Description**
Gets a reverse iterator to the end of the array view.
---
Capacity
```cpp
bool empty() const
```
**Description**
Returns true if the size of the array view is zero, otherwise false.
---
```cpp
size_t size() const
```
**Description**
Returns the size of the view.
---
```
C++size_t max_size() const
```
**Description**
Returns the maximum possible size of the view.
---
## Non-member functions
**Lexicographically comparisons**
```cpp
operator ==
```
**Description**
`true` if the contents of the lists are equal, otherwise `false`.
---
```cpp
operator !=
```
**Description**
`true` if the contents of the lists are not equal, otherwise `false`.
---
```cpp
operator <
```
**Description**
`true` if the contents of the lhs are lexicographically less than the contents of the rhs, otherwise `false`.
---
```cpp
operator <=
```
**Description**
`true` if the contents of the lhs are lexicographically less than or equal to the contents of the rhs, otherwise `false`.
---
```cpp
operator >
```
**Description**
`true` if the contents of the lhs are lexicographically greater than the contents of the rhs, otherwise `false`.
---
```cpp
operator >=
```
**Description**
`true` if the contents of the lhs are lexicographically greater than or equal to the contents of the rhs, otherwise `false`.
## Hash
There are specialisations of `etl::hash` for `array_view`.
## Example
```cpp
etl::array<int, 10> data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
typedef etl::array_view<int> View;
View view(data.begin() + 2, data.end() - 2);
void Print(const View& view)
{
for (size_t i = 0; i < view.size(); ++i)
{
std::cout << view[i] << " ";
}
}
Print(view); // Prints "3 4 5 6 7 8"
size_t hashvalue = etl::hash<View>()(view);
```

View File

@ -0,0 +1,266 @@
---
title: "array_wrapper"
---
{{< callout >}}
Header: `array_wrapper.h`
Since: All versions
{{< /callout >}}
This class implements a zero cost C++ interface around a const or non-const C array. It presents the same API as std::array.
It allows legacy C data to be more easily integrated with C++ interfaces and be accessed in a less error prone fashion.
If C++11 or above is supported then most functions can be 'constexpr'.
---
## Member types
`value_type`
`size_type`
`difference_type`
`reference`
`value_type`
`reference`
`const_reference`
`pointer`
`const_pointer`
`iterator`
`const_iterator`
`reverse_iterator`
`const_reverse_iterator`
## Member constants
**May be used as indexes in to the array.**
`SIZE =` Size of the array
`MAX_SIZE = SIZE`
`FRONT = 0`
`BACK = SIZE - 1`
`BEGIN = 0`
`END = SIZE`
`RBEGIN = SIZE - 1`
`REND = -1`
## Element access
```cpp
T& at(size_t i)
```
```cpp
ETL_CONSTEXPR const T& at(size_t i) const
```
**Description**
Returns a reference or const reference to the indexed element.
Emits an `etl::array_wrapper_bounds` if the index isout of range of the array.
If asserts or exceptions are not enabled then undefined behaviour occurs.
---
```cpp
T& operator[](size_t i)
```
```cpp
ETL_CONSTEXPR const T& operator[](size_t i) const
```
**Description**
Returns a reference or const reference to the indexed element.if the index is out of range of the array then undefined behaviour occurs.---
---
```cpp
T& front()
```
```cpp
ETL_CONSTEXPR const T& front() const
```
**Description**
Returns a reference or const reference to the first element.---
---
```cpp
T& back()
```
```cpp
ETL_CONSTEXPR const T& back() const
```
**Description**
Returns a reference or const reference to the last element.---
---
```cpp
T* data()
```
```cpp
ETL_CONSTEXPR const T* data() const
```
**Description**
Returns a pointer or const pointer to the array.---Modifiers
---
```cpp
void fill(parameter_t value)
```
**Description**
Fill a non-cost array with the value.---
---
```cpp
template <typename T, T(&ARRAYOTHER)[SIZE_]>
void swap(etl::array_wrapper<T, SIZE_, ARRAYOTHER>& other)
```
**Description**
Swaps the array contents with another.---Iterators
---
```cpp
ETL_CONSTEXPR iterator begin()
```
```cpp
ETL_CONSTEXPR const_iterator begin() constETL_CONSTEXPR const_iterator cbegin() const
```
**Description**
Returns an iterator to the beginning of the array.---
---
```cpp
ETL_CONSTEXPR iterator end()
```
```cpp
ETL_CONSTEXPR const_iterator end() constETL_CONSTEXPR const_iterator cend() const
```
**Description**
Returns an iterator to the end of the array.---
---
```cpp
ETL_CONSTEXPR iterator rbegin()
```
```cpp
ETL_CONSTEXPR const_reverse_iterator rbegin() const
```
```cpp
ETL_CONSTEXPR const_reverse_iterator crbegin() const
```
**Description**
Returns a reverse iterator to the beginning of the array.---
---
```cpp
ETL_CONSTEXPR iterator rend()
```
```cpp
ETL_CONSTEXPR const_reverse_iterator rend() constETL_CONSTEXPR const_reverse_iterator crend() const
```
**Description**
Returns a reverse iterator to the end of the array.---Capacity
---
```cpp
ETL_CONSTEXPR size_t size() const
```
**Description**
Returns the size of the view.---
---
```cpp
ETL_CONSTEXPR size_t max_size() const
```
**Description**
Returns the maximum possible size of the view.---Non-member functions
## Lexicographically comparisons
`operator ==`
**Returns**
`true` if the contents of the array views are equal, otherwise `false`.
`operator !=`
**Returns**
`true` if the contents of the array views are not equal, otherwise `false`.
`operator <`
**Returns**
`true` if the contents of the lhs are lexicographically less than the
contents of the rhs, otherwise `false`.
`operator <=`
**Returns**
`true` if the contents of the lhs are lexicographically less than or equal to the
contents of the rhs, otherwise `false`.
`operator >`
**Returns**
`true` if the contents of the lhs are lexicographically greater than the
contents of the rhs, otherwise `false`.
`operator >=`
**Returns**
`true` if the contents of the lhs are lexicographically greater than or equal to the
contents of the rhs, otherwise `false`
## Swap
```cpp
template <typename T, std::size_t SIZE, T(&ARRAYL)[SIZE], T(&ARRAYR)[SIZE]>
void swap(etl::array_wrapper<T, SIZE, ARRAYL>& lhs,
etl::array_wrapper<T, SIZE, ARRAYR>& rhs)
```
**Description**
Swaps the array contents of two arrays.
## Hash
There is a specialisation for `etl::hash` for `array_wrapper`.
## Macros
A macro is defined to ease the use of the class.
```cpp
ETL_ARRAY_WRAPPER(type, array);
```
**Example**
```cpp
// The address of the array MUST be deducible at compile time.
int cdata = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
typedef ETL_ARRAY_WRAPPER(int, cdata) Data;
// All instances of 'Data' access the SAME array.Data data;
void Print(Data data)
{
Data::const_iterator itr = data.begin();
while (itr != data.end())
{
std::cout << *itr++ << " ";
}
}
Print(data); // Prints "1 2 3 4 5 6 7 8 9 10"
size_t hashvalue = etl::hash<Data>()(data);
// Using indexes
int firstElement = data[Data::FRONT];
int lastElement = data[Data::BACK];
// Using forward indexes
for (int i = Data::BEGIN; i < Data::END; ++i)
{
std::cout << data[i] << " ";
}
// Using reverse indexes
for (int i = Data::RBEGIN; i < Data::REND; --i)
{
std::cout << data[i] << " ";
}
```

View File

@ -0,0 +1,291 @@
---
title: "multi_range"
---
A lightweight, chainable range system that simulates nested loops over multiple ranges, with customisable stepping and end conditions.
`etl::multi_range<T>` is a composable range-iteration helper that can chain multiple ranges to produce nested-loop style iteration. It lets you build “outer/inner” ranges and iterate across all combinations, while customizing stepping and termination logic.
Each range is defined as an `etl::multi_range` which may be linked to create nested multiple ranges.
```cpp
template <typename T>
class multi_range
```
All multi_range<T> classes derive from `imulti_range`.
By default, each call to next() will invoke either the forward_step or reverse_step types.
If the type is an arithmetic or pointer type then the default stepper will be automatically selected, dependent on the first and last parameters. If not, the default will be `forward_step`.
If a custom stepper for the type is required, then it may be defined in the constructor.
By default, each call to `completed()` will invoke `not_equal_compare` against the terminating range value. If a custom incrementor for the type is required, then it may be defined in the constructor.
## Types
`value_type`
The type of the range.
`const_reference`
The const reference type of the range.
---
`step_type`
Pure abstract base.
Inherit from this to define custom step functionality.
`forward_step`
A pre-defined step type that calls the type's `operator++()`.
This is the default step type if the type is arithmetic or random access iterator and the range is ascending, or the type is not an arithmetic or pointer.
`forward_step_by`
A pre-defined step type that calls the type's `operator+=()`.
The constructor requires the step value to add.
`reverse_step`
A pre-defined step type that calls the type's `operator--()`.
This is the default step type if the type is arithmetic or random access iterator and the range is descending.
`reverse_step_by`
A pre-defined step type that calls the type's `operator-=()`.
The constructor requires the step value to subtract.
---
`compare_type`
Pure abstract base.
Inherit from this to define custom compare functionality.
`not_equal_compare`
A pre-defined step type that calls etl::not_equal_to.
This is the default compare type.
`less_than_compare`
A pre-defined step type that calls `etl::less`.
`greater_than_compare`
A pre-defined step type that calls `etl::greater`.
## Constructor
```cpp
multi_range(value_type start,
value_type last)
```
**Description**
Initialises the loop where start is the initial value and last is the terminate value.
---
```cpp
multi_range(value_type first,
value_type last,
step_type& stepper)
```
**Description**
Initialises the loop where start is the initial value and last is the terminate value.
stepper will be called to increment the current range value.
---
```cpp
multi_range(value_type first,
value_type last,
compare_type& compare)
```
**Description**
Initialises the loop where start is the initial value and last is the terminate value.
compare will be called to compare with the terminating value.
---
```cpp
multi_range(value_type first,
value_type last,
step_type& stepper,
compare_type& compare)
```
**Description**
Initialises the loop where start is the initial value and last is the terminate value.
stepper will be called to increment the current range value.
compare will be called to compare with the terminate value.
## Modifiers
The nested ranges may be constructed in a variety of ways.
```cpp
imulti_range& append(imulti_range& inner_ranges)
```
**Description**
Appends inner loop(s) to the current range(s).
If the current range, **A**, is linked to ranges **B** & **C** in the order **A** -> **B** -> **C** and the new linked ranges are **D** -> **E**,
`A.append(D)` will result in **A** -> **B** -> **C** -> **D** -> **E**.
---
```cpp
imulti_range& insert(imulti_range& inner_ranges)
```
**Description**
Inserts inner range(s) after the current range.
If the current range, **A**, is linked to ranges **B** & **C** in the order **A** -> **B** -> **C** and the new linked ranges are **D** -> **E**,
`A.insert(D)` will result in **A** -> **D** -> **E** -> **B** -> **C**.
---
```cpp
void detach()
```
**Description**
Unlinks this range from its inner ranges.
---
```cpp
void detach_all()
```
**Description**
Unlinks this range and all its inner ranges from each other.
## Access
```cpp
const_reference value() const;
```
**Description**
Gets a const reference to the current value
---
```cpp
const_reference begin() const;
```
**Description**
Gets a const reference to the first value
---
```cpp
const_reference end() const;
```
**Description**
Gets a const reference to the terminate value
---
```cpp
bool completed() const
```
**Description**
Returns true if the range, and all of its inner ranges, have completed.
---
```cpp
size_t number_of_ranges() const
```
**Description**
Returns the number of linked ranges, starting from this.
For linked ranges **A** -> **B** -> **C** -> **D** -> **E**, `B.number_of_ranges()` returns `4`.
---
```cpp
size_t number_of_iterations()
```
**Description**
Returns the total number of iterations for all linked ranges, starting from this.
For linked ranges **A** -> **B** -> **C** -> **D** -> **E**, and a range size of `5` for each one,
`B.number_of_iterations()` returns `625` (`5 * 5 * 5 * 5`).
This function is not const as it must simulate the running of all of the nested ranges.
## Operations
```cpp
void start()
```
**Description**
Resets the range, and all its linked inner ranges to the starting conditions, with each range reset to its begin value.
---
```cpp
void next()
```
**Description**
Moves to the next iteration of the nested range.
---
## Example
```cpp
using Iterator = std::forward_list<std::string>::const_iterator;
// Less Than compare type
using LessThanCompare = etl::multi_range<const short*>::less_than_compare;
// Decrementing step type
using DecrementPtr = etl::multi_range<const short*>::reverse_step;
using Outer = etl::multi_range<int>; // Incrementing int
using Middle = etl::multi_range<const short*>; // Decrementing const short*
using Inner = etl::multi_range<Iterator>; // Incrementing const_iterator
const short data[4] = { 0, 1, 2, 3 };
std::forward_list<std::string> strings =
{
"zero", "one", "two", "three"
};
LessThanCompare lessThan;
DecrementPtr decrementPtr;
// Setup the loops.
Outer outer(0, 4, lessThan);
Middle middle(data + 3, data - 1, decrementPtr);
Inner inner(strings.begin(), strings.end());
outer.append(middle).append(inner);
size_t n_outer_loops = outer.number_of_loops(); // == 3
size_t n_middle_loops = middle.number_of_loops(); // == 2
size_t n_inner_loops = inner.number_of_loops(); // == 1
size_t n_outer_iterations = outer.number_of_iterations(); // == 64
size_t n_middle_iterations = middle.number_of_iterations(); // == 16
size_t n_inner_iterations = inner.number_of_iterations(); // == 4
// Create const references to the loop values.
const int& value_outer = outer.value();
const short*& value_middle = middle.value();
const Iterator& value_inner = inner.value();
// Iterate through the nested loops.
int i = 0;
for (outer.start(); !outer.completed(); outer.next())
{
std::cout << "Iteration " << i++ << " : "
<< "Outer = " << value_outer << " : "
<< "Middle = " << *value_middle << " : "
<< "Inner = " << *value_inner
<< "\n";
}
// Just iterate through the two nested loops.
i = 0;
for (middle.start(); !middle.completed(); middle.next())
{
std::cout << "Iteration " << i++ << " : "
<< "Middle = " << *value_middle << " : "
<< "Inner = " << *value_inner
<< "\n";
}
```

View File

@ -0,0 +1,189 @@
---
title: "multi_span"
---
{{< callout >}}
Header: `multi_span.h`
{{< /callout >}}
This class implements a span of a range of spans.
Allows implementation of Scatter/Gather to multiple buffers or ports.
Iterating through the `multi_span` will iterate through the collection of spans consecutively.
The list of spans must be in a contiguous list, such as an array or vector.
```cpp
etl::multi_span<typename T>
```
Where `T` is the element type of the spans.
## Member types
```cpp
element_type T
value_type remove_cv<T>::type
size_type size_t
difference_type ptrdiff_t
reference value_type&
const_reference const value_type&
pointer value_type*
const_pointer const value_type*
iterator Forward iterator <20.39.5
Bidirectional iterator >=20.39.5
const_iterator Constant Forward iterator <20.39.5
Constant bidirectional iterator >=20.39.5
reverse_iterator ETL_OR_STD::reverse_iterator<iterator>
const_reverse_iterator ETL_OR_STD::reverse_iterator<const_iterator>
span_type etl::span<T>
span_list_type etl::span<const span_type>
```
## Constructors
ETL_CONSTEXPR multi_span(span_list_type span_list)
**Description**
Construct from a span of spans.
---
template <typename TContainer>
ETL_CONSTEXPR multi_span(TContainer& a) ETL_NOEXCEPT
**Description**
Construct from a container of spans.
---
template <typename TContainer>
ETL_CONSTEXPR multi_span(const TContainer& a) ETL_NOEXCEPT
**Description**
Construct from a const container of spans.
---
template <typename TIterator>
ETL_CONSTEXPR multi_span(TIterator begin, TIterator end)
**Description**
Construct from a range of spans.
---
template <typename TIterator>
ETL_CONSTEXPR multi_span(TIterator begin, size_t length)
**Description**
Construct from a range of spans.
---
ETL_CONSTEXPR multi_span(const multi_span& other)
**Description**
Copy constructor.
## Access
```cpp
ETL_CONSTEXPR14 multi_span& operator =(const multi_span& other) ETL_NOEXCEPT
```
**Description**
Assign from a other `multi_span`.
## Iterators
```cpp
ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
```
**Description**
Returns an iterator to the beginning of the span.
---
```cpp
ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
```
**Description**
Returns an iterator to the end of the span.
---
```cpp
ETL_CONSTEXPR iterator cbegin() const ETL_NOEXCEPT
```
**Description**
Returns a const iterator to the beginning of the span.
From: `20.39.5`
---
```cpp
ETL_CONSTEXPR iterator cend() const ETL_NOEXCEPT
```
**Description**
Returns a const iterator to the end of the span.
From: `20.39.5`
---
```cpp
ETL_CONSTEXPR iterator rbegin() const ETL_NOEXCEPT
```
**Description**
Returns a reverse iterator to the beginning of the span.
From: `20.39.5`
---
```cpp
ETL_CONSTEXPR iterator rend() const ETL_NOEXCEPT
```
**Description**
Returns a reverse iterator to the end of the span.
From: `20.39.5`
---
```cpp
ETL_CONSTEXPR iterator crbegin() const ETL_NOEXCEPT
```
**Description**
Returns a const reverse iterator to the beginning of the span.
From: `20.39.5`
---
```cpp
ETL_CONSTEXPR iterator crend() const ETL_NOEXCEPT
```
**Description**
Returns a const reverse iterator to the end of the span.
From: `20.39.5`
## Capacity
```cpp
ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
```
**Description**
Returns true if the size of the multi_span is zero, otherwise false.
---
```cpp
ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
```
**Description**
Returns the size of the multi_span.
---
```cpp
ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
```
**Description**
Returns the size of the multi_span in bytes.
---
```cpp
ETL_CONSTEXPR size_t size_spans() const ETL_NOEXCEPT
```
**Description**
Returns the number of the spans.

View File

@ -0,0 +1,361 @@
---
title: "poly_span"
---
{{< callout >}}
Header: `poly_span.h`
From: `20.31.0`
{{< /callout >}}
Polymorphic span.
This class implements a view in to a contiguous range through a base type.
```cpp
etl::poly_span<typename TBase, size_t Extent = etl::dynamic_extent>
```
## Template deduction guides
C++17
```cpp
template <typename TIterator>
poly_span(const TIterator begin, const TIterator end)
->poly_span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
```
```cpp
template <typename TIterator, typename TSize>
poly_span(const TIterator begin, const TSize size)
->poly_span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
```
```cpp
template <typename T, size_t N>
poly_span(T(&)[N])
-> poly_span<T, N>;
```
```cpp
template <typename T, size_t N>
poly_span(etl::array<T, N>&)
-> poly_span<T, N>;
```
```cpp
template <typename T, size_t N>
poly_span(const etl::array<T, N>&)
-> poly_span<const T, N>;
```
```cpp
template <typename T, size_t N>
poly_span(std::array<T, N>&)
->poly_span<T, N>;
```
```cpp
template <typename T, size_t N>
poly_span(const std::array<T, N>&)
->poly_span<const T, N>;
```
## Member types
```cpp
element_type T
value_type remove_cv<T>::type
size_type size_t
difference_type ptrdiff_t
reference value_type&
const_reference const value_type&
pointer value_type*
const_pointer const value_type*
iterator Random access iterator
reverse_iterator ETL_OR_STD::reverse_iterator<iterator>
```
## Constructors
```cpp
ETL_CONSTEXPR poly_span() ETL_NOEXCEPT
```
---
```cpp
template <typename TIterator, typename TSize>
ETL_CONSTEXPR poly_span(const TIterator begin, const TSize size) ETL_NOEXCEPT
```
**Description**
Static asserts if `etl::iterator_traits<TIterator>::iterator_category` is not `random_access_iterator_tag`
or `etl::iterator_traits<TIterator>::value_type` is not the same as, or not derived from `TBase`.
---
```cpp
template <typename TIterator>
ETL_CONSTEXPR poly_span(const TIterator begin, const TIterator end)
```
**Description**
Static asserts if `etl::iterator_traits<TIterator>::iterator_category` is not `random_access_iterator_tag`
or `etl::iterator_traits<TIterator>::value_type` is not the same as, or not derived from `TBase`.
---
```cpp
template<typename U, size_t N>
ETL_CONSTEXPR poly_span(U(&begin_)[N]) ETL_NOEXCEPT
```
**Description**
Static asserts if `N` is greater than `Extent` or `etl::iterator_traits<TIterator>::value_type` is not the same as, or not derived from `TBase`.
---
```cpp
template <typename U, size_t N>
ETL_CONSTEXPR poly_span(etl::array<U, N>& a) ETL_NOEXCEPT
```
**Description**
Static asserts if `N` is greater than `Extent` or `etl::iterator_traits<TIterator>::value_type` is not the same as, or not derived from `TBase`.
---
```cpp
template <typename U, size_t N>
ETL_CONSTEXPR poly_span(const etl::array<U, N>& a) ETL_NOEXCEPT
```
**Description**
Static asserts if `N` is greater than `Extent` or `etl::iterator_traits<TIterator>::value_type` is not the same as, or not derived from `TBase`.
---
```cpp
template <typename U, size_t N>
ETL_CONSTEXPR poly_span(std::array<U, N>& a) ETL_NOEXCEPT
```
**Description**
Enabled if `ETL_USING_CPP11` and `ETL_USING_STL` are `true`.
Static asserts if `N` is greater than `Extent` or `etl::iterator_traits<TIterator>::value_type` is not the same as, or not derived from `TBase`.
---
```cpp
template <typename U, size_t N>
ETL_CONSTEXPR poly_span(const std::array<U, N>& a) ETL_NOEXCEPT
```
**Description**
Enabled if `ETL_USING_CPP11` and `ETL_USING_STL` are `true`.
Static asserts if `N` is greater than `Extent` or `etl::iterator_traits<TIterator>::value_type` is not the same as, or not derived from `TBase`.
---
```cpp
ETL_CONSTEXPR poly_span(const poly_span& other)
```
**Description**
Copy constructor.
## Access
```cpp
ETL_CONSTEXPR reference operator[](size_t i) const
```
**Description**
Returns a reference to the indexed element.
Index out of range results in undefined behaviour.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
```
**Description**
Returns a reference to the first element.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
```
**Description**
Returns a reference to the last element.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
```
**Description**
Returns a pointer to the first element.
---
```cpp
ETL_CONSTEXPR14 poly_span& operator =(const poly_span& other) ETL_NOEXCEPT
```
**Description**
Assign from a other span
---
```cpp
template <typename UBase>
ETL_CONSTEXPR14 poly_span& operator =(const poly_span<UBase, Extent>& other) ETL_NOEXCEPT
```
**Description**
Assign from a other span.
---
```cpp
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT> first() const
```
**Description**
Returns a span consisting of the first `COUNT` elements of the current span.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> last(size_t count) const
```
**Description**
Returns a span consisting of the last count elements of the current span.
---
```cpp
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT> last() const
```
**Description**
Returns a span consisting of the last `COUNT` elements of the current span
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> first(size_t count) const
```
**Description**
Returns a span consisting of the first count elements of the current span.
---
```cpp
template <const size_t OFFSET, size_t COUNT = etl::dynamic_extent>
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const
```
**Description**
Returns a subspan consisting of the range starting at `OFFSET` for `COUNT` elements of the current span.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const
```
**Description**
Returns a subspan consisting of the range starting at `offset` for `count` elements of the current span.
## Iterators
```cpp
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
```
**Description**
Returns an iterator to the beginning of the span.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
```
**Description**
Returns an iterator to the end of the span.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR iterator rbegin() const ETL_NOEXCEPT
```
**Description**
Returns a reverse iterator to the beginning of the span.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR iterator rend() const ETL_NOEXCEPT
```
**Description**
Returns a reverse iterator to the end of the span.
## Capacity
```cpp
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
```
**Description**
Returns true if the size of the span is zero, otherwise false.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
```
**Description**
Returns the size of the span.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
```
**Description**
Returns the size of the span in bytes.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR size_t size_of_element() const ETL_NOEXCEPT
```
**Description**
Returns the size of the elements pointed to by the span, in bytes.
## Non-member functions
### Hash
There is a specialisation of `etl::hash` for `etl::poly_span`.
---
### Example
```cpp
struct Base
{
virtual ~Base() {}
virtual void Print() const = 0;
};
struct Derived : Base
{
Derived(int i_)
: i(i_)
{
}
void Print() const override
{
std::cout << "Derived " << i << "\n";
}
int i;
};
etl::array data{ Derived(1), Derived(2), Derived(3), Derived(4) };
etl::poly_span<Base> ps{ data };
for (const Base& b : ps)
{
b.Print();
}
```

View File

@ -0,0 +1,410 @@
---
title: "span"
---
{{< callout >}}
Header: `span.h`
Similar to: `std::span`
{{< /callout >}}
This class implements a view in to a range of a C array, `etl::array`, `std::array`, `etl::vector` and `std::vector`.
It will support construction from any class that supports `data()` and `size()` member functions as well as plain C arrays.
From: `20.34.0`
The ETL's span adds the ability to access circular iterators that will loop through the span when the beginning or end is reached.
```cpp
etl::span<typename T, size_t Extent = etl::dynamic_extent>
```
## Template deduction guides
C++17
```cpp
template <typename TIterator>
span(const TIterator begin, const TIterator end)
->span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
```
```cpp
template <typename TIterator, typename TSize>
span(const TIterator begin, const TSize size)
->span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
```
```cpp
template <typename T, size_t N>
span(T(&)[N])
-> span<T, N>;
```
```cpp
template <typename T, size_t N>
span(etl::array<T, N>&)
-> span<T, N>;
```
```cpp
template <typename T, size_t N>
span(const etl::array<T, N>&)
-> span<const T, N>;
```
```cpp
template <typename T, size_t N>
span(std::array<T, N>&)
->span<T, N>;
```
```cpp
template <typename T, size_t N>
span(const std::array<T, N>&)
->span<const T, N>;
```
### Examples
```cpp
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::span span1{ data };
etl::span span2{ data.begin(), data.end() };
etl::span span3{ data.begin(), data.size() };
etl::span span4{ span1 };
int c_array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::span span5{ c_array };
```
## Member types
```cpp
element_type T
value_type remove_cv<T>::type
size_type size_t
difference_type ptrdiff_t
reference value_type&
const_reference const value_type&
pointer value_type*
const_pointer const value_type*
iterator A random access iterator
reverse_iterator A reverse random access iterator
circular_iterator A circular random access iterator 20.34.0
circular_reverse_iterator A reverse circular random access iterator 20.34.0
```
## Constructors
```cpp
ETL_CONSTEXPR span()
```
**Description**
Default constructor.
---
```cpp
template <typename TIterator>
ETL_CONSTEXPR span(TIterator begin, TIterator end)
```
**Description**
Construct from an iterator or pointer range.
---
```cpp
template <typename TIterator, typename TSize>
ETL_CONSTEXPR span(TIterator begin, TSize size)
```
**Description**
Construct from a start and size
---
```cpp
template<const size_t ARRAY_SIZE>
ETL_CONSTEXPR explicit span(element_type(&begin)[ARRAY_SIZE])
```
**Description**
Construct from a compile time sized C array.
---
```cpp
template <typename U, size_t N>
ETL_CONSTEXPR span(etl::array<U, N>& a) ETL_NOEXCEPT
```
**Description**
Construct from an ETL array.
---
```cpp
template <typename U, size_t N>
ETL_CONSTEXPR span(const etl::array<U, N>& a) ETL_NOEXCEPT
```
**Description**
Construct from a const ETL array.
---
```cpp
template <typename U, size_t N>
ETL_CONSTEXPR span(std::array<U, N>& a) ETL_NOEXCEPT
```
**Description**
Enabled if `ETL_USING_CPP11` and `ETL_USING_STL` are `true`.
Construct from an STL array.
---
```cpp
template <typename U, size_t N>
ETL_CONSTEXPR span(const std::array<U, N>& a) ETL_NOEXCEPT
```
**Description**
Enabled if `ETL_USING_CPP11` and `ETL_USING_STL` are `true`.
Construct from a const STL array.
---
```cpp
ETL_CONSTEXPR span(const span& other) ETL_NOEXCEPT
```
**Description**
Copy constructor.
---
```cpp
template <typename U, size_t N>
ETL_CONSTEXPR span(const etl::span<U, N>& other) ETL_NOEXCEPT
```
## Access
```cpp
ETL_CONSTEXPR reference operator[](size_t i) const
```
**Description**
Returns a reference to the indexed element.
Index out of range results in undefined behaviour.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
```
**Description**
Returns a reference to the first element.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
```
**Description**
Returns a reference to the last element.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
```
**Description**
Returns a pointer to the first element.
---
```cpp
ETL_CONSTEXPR14 span& operator =(const span& other) ETL_NOEXCEPT
```
**Description**
Assign from a other span
---
```cpp
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> first() const
```
**Description**
Returns a span consisting of the first `COUNT` elements of the current span
---
```cpp
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> last() const
```
**Description**
Returns a span consisting of the last `COUNT` elements of the current span
---
```cpp
template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, E> subspan() const
```
**Description**
Returns a subspan consisting of the range starting at `OFFSET` for `COUNT` elements of the current span
## Iterators
```cpp
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
```
**Description**
Returns an iterator to the beginning of the span.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT
```
**Description**
Returns a circular iterator to the beginning of the span.
From: `20.34.0`
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
```
**Description**
Returns an iterator to the end of the span.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR iterator rbegin() const ETL_NOEXCEPT
```
**Description**
Returns a reverse iterator to the beginning of the span.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR reverse_circular_iterator rbegin_circular() const ETL_NOEXCEPT
```
**Description**
Returns a reverse circular iterator to the beginning of the span.
From: `20.34.0`
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR iterator rend() const ETL_NOEXCEPT
```
**Description**
Returns a reverse iterator to the end of the span.
## Capacity
```cpp
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
```
**Description**
Returns `true` if the size of the span is zero, otherwise `false`.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
```
**Description**
Returns the size of the span.
---
```cpp
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
```
**Description**
Returns the size of the span in bytes.
## Non-member functions
```cpp
template <typename T1, size_t N1, typename T2, size_t N2>
ETL_NODISCARD
ETL_CONSTEXPR
bool operator ==(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs) ETL_NOEXCEPT
```
**Description**
Compare two spans for equality.
Returns true if they both point to the same range of data.
From: `20.35.12`
---
```cpp
template <typename T1, size_t N1, typename T2, size_t N2>
ETL_NODISCARD
ETL_CONSTEXPR
bool operator !=(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs) ETL_NOEXCEPT
```
**Description**
Compare two spans for inequality.
Returns true if they don't both point to the same range of data.
From: `20.35.12`
---
```cpp
template <typename T1, size_t N1, typename T2, size_t N2>
bool equal(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs)
```
**Description**
Equality function.
Performs a comparision of the range values.
Returns `true` if one of the following are `true`
1. Both spans are empty.
2. They both point to the same range of data.
3. The values in the two ranges are equal.
From: `20.35.12`
## Hash
There is a specialisation of etl::hash for etl::span
### Example
**Iterating through a span and subspan.**
```cpp
etl::array<int, 10> data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
using View = etl::span<int>;
View view(data.begin() + 2, data.end() - 2);
void Print(const View& view)
{
for (size_t i = 0; i < view.size(); ++i)
{
std::cout << view[i] << " ";
}
}
Print(view); // Prints "3 4 5 6 7 8"
auto subview = view.subspan<2, 3>();
Print(subview); // Prints "5 6 7"
size_t hashvalue = etl::hash<View>()(view);
```
**Looping a span.**
```cpp
etl::array<int, 10> data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
using View = etl::span<int>;
View view(data.begin(), data.end());
View::circular_iterator itr = view.begin_circular();
// Loop through the data for 1000 iterations.
for (int i; i < 1000; ++i)
{
Print(*itr++);
}
```

66
docs/containers/_index.md Normal file
View File

@ -0,0 +1,66 @@
---
title: "Containers"
weight: 100
---
## Containers
The library defines a set of containers that have been specially tailored for embedded systems. They have a maximum capacity fixed at compile time and make no calls to `malloc`/`free` or `new`/`delete`. They are completely deterministic.
Most container types have been designed to mimic, as far as possible, those found in the STL. Some do not have direct STL equivalents.
As the storage for all of the container types is allocated as a contiguous block, they are extremely cache friendly.
**Note:**
Unlike the STL, the ETL's `vector<bool>` really *is* a container and actually *does* contains `bool`.
If you require a compact Boolean container then `etl::bitset` may be more appropriate.
## Intrusive containers
There are intrusive versions of certain containers. These do not store copies of the inserted values, but link to the original objects. Certain types of intrusive container require that the stored object derives from an intrusive link.
Most intrusive containers do not have a maximum fixed capacity.
See here for more information.
To eliminate code bloat, most container templates utilise 'hoisting' where functionality, independent of the size and/or type, is separated out in to base classes.
For example, `vector<int, 5>` and `vector<int, 10>` will share code from `ivector<int>`.
`vector<int, 5>`, `vector<float, 7>` and `vector<int, 10>` will all share code from `vector_base`.
The `i` prefixed container types may be used as size independent pointer or reference types for all sizes of thederived type.
```cpp
etl::vector<int, 5> vector1;
etl::vector<int, 10> vector2;
etl::ivector<int>* pvector;
pvector = &vector1;pvector->push_back(3);
pvector = &vector2;pvector->push_back(4);
```
## Move semantics and rvalue references
The following containers support rvalue references and move semantics.
`vector`
`deque`
`list`
`forward_list`
`flat_set`
`flat_multiset`
`flat_map`
`flat_multimap`
*This list may be out of date*.
## Differences from the STL containers
As the containers have a fixed capacity, most also implement `full()` and `available()` member functions.
Most of the containers allocate their storage from an internal instance of `etl::pool`.
Because of this the containers have a certain set of attributes that differ from the standard library.
- The storage for all containers is contiguous, thereby enhancing cache hits.
- No heap memory is used; no OS or user supplied memory management is required.
- Non-static containers declared locally within functions will store their contents on the stack.
- Copying or swapping a container is not a low cost action, as all of the contents will be copied.
## Notes
Although the containers utilise inheritance, like the STL containers, they are not intended to be used
polymorphically, unless enabled by a compile time macros `ETL_POLYMORPHIC_XXX`.

View File

@ -0,0 +1,6 @@
---
title: "Arrays"
weight: 100
---
Array like containers.

Some files were not shown because too many files have changed in this diff Show More