Latest documentation updates

This commit is contained in:
John Wellbelove 2026-03-25 19:47:59 +00:00
parent da8831eaae
commit bd193d6108
23 changed files with 2382 additions and 55 deletions

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.

View File

@ -4,6 +4,10 @@ title: "Embedded Template Library"
---
{{< callout type="warning">}}
**This documentation is still under development, and very much incomplete.**
{{< /callout >}}
{{< callout emoji="❓">}}
### [Is the ETL free?]({{< ref "Is the ETL free.md" >}})
{{< /callout >}}

View File

@ -7,7 +7,7 @@ weight: 1
{{< callout type="info">}}
Header: `delegate.h`
Support: `20.45.0`
Supported: `20.45.0`
Similar to: [std::function](https://en.cppreference.com/w/cpp/utility/functional/function.html)
{{< /callout >}}

View File

@ -7,7 +7,7 @@ weight: 1
{{< callout type="info">}}
Header: `inplace_function.h`
Support: `20.45.0`
Supported: `20.45.0`
Similar to: [std::function](https://en.cppreference.com/w/cpp/utility/functional/function.html)
{{< /callout >}}
@ -78,8 +78,6 @@ etl::inplace_function_uninitialized
**Description**
Thrown (via `ETL_ASSERT`) when invoked without a target.
---
## Member Types
```C++
@ -87,11 +85,15 @@ function_type
```
**Description**
---
```C++
return_type
```
**Description**
---
```C++
argument_types
```
@ -134,8 +136,6 @@ Assignment from function pointer.
**Description**
Assignment from lambda/functor.
---
## Invocation
```C++
@ -182,7 +182,7 @@ Invokes the target or a fallback callable.
bool is_valid() const
```
**Returns**
Returns `true` if there is a valid callable.
`true` if there is a valid callable.
---
@ -194,7 +194,7 @@ explicit operator bool() const
**Parameters**
**Returns**
Returns the result of `is_valid()`
The result of `is_valid()`
## Modifiers
@ -208,7 +208,7 @@ Clears any stored callable.
None
**Returns**
Void.
`void`
---
@ -223,9 +223,7 @@ Swaps with another inplace_function.
None
**Returns**
Void.
---
'void`
## Storage Introspection
@ -239,7 +237,7 @@ Interogates the internal storage size.
None
**Returns**
Returns the size of the internal storage.
The size of the internal storage.
---
@ -253,7 +251,7 @@ Interogates the internal storage alignment.
None
**Returns**
Returns the alignment of the internal storage.
The alignment of the internal storage.
## Compile-Time Binding (No Payload)
@ -409,24 +407,3 @@ If the callable object is larger than `Object_Size` or requires stricter alignme
`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.

View File

@ -1,3 +1,60 @@
---
title: "Containers"
---
## 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 havedirect 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 containersThere are intrusive versions of certain containers. These do not store copies of the inserted values, but link to theoriginal 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 sizeand/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.
```C++
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
(except for externally buffered vectors which will use a simple pointer copy).
## 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`.

300
docs/containers/array.md Normal file
View File

@ -0,0 +1,300 @@
---
title: "array"
weight: 1
---
---
{{< callout type="">}}
Header: `array.h`
Supported: All versions
Similar to: [std::array](https://en.cppreference.com/w/cpp/container/array.html)
{{< /callout >}}
A fixed capacity array.
Adds additional members functions, `assign`, `insert` & `erase`.
```C++
etl::array<typename T, const size_t SIZE>
```
See also
[array_view]()
## Template deduction guides
**C++17 and above**
```C++
template <typename... T>
etl::array(T...)
```
### Example
```C++
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
```
Defines data as an array of 'int', of length '10', containing the supplied data.
## Make template
**C++11 and above**
```C++
template <typename T, typename... TValues>
constexpr auto make_array(TValues&&... values)
```
### Example
```C++
auto data = etl::make_array<int>(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
```
## Member types
`value_type`
`size_type`
`difference_type`
`reference`
`const_reference`
`pointer`
`const_pointer`
`iterator`
`const_iterator`
`reverse_iterator`
`const_reverse_iterator`
'etl::array' iterators are random access.
## Static Constants
```C++
SIZE
```
**Description**
The size of the array.
## Constructor
```C++
etl::array<int, 10> data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
```
**Description**
Default or copy constructs each element.
Can be initialised like a C array.
## Element access
```C++
T& at(size_t i)
const T& at(size_t i) const
```
**Description**
Returns a reference or const reference to the indexed element. Emits an etl::array_out_of_range if the index is not in range.
If asserts or exceptions are not enabled then an out of range index results in undefined behaviour.
---
```C++
T& operator[](size_t i)
const T& operator[](size_t i) const
```
**Description**
Returns a reference or const reference to the indexed element.
An out of range index results in undefined behaviour.
---
```C++
T& front()
const T& front() const
```
**Description**
Returns a reference or const reference to the first element.
---
```C++
T& back()
const T& back() const
```
**Description**
Returns a reference or const reference to the last element.
## Iterators
```C++
iterator begin()
const_iterator begin() const
const_iterator cbegin() const
```
**Description**
Returns an iterator to the beginning of the array.
---
```C++
iterator end()
const_iterator end() const
const_iterator cend() const
```
**Description**
Returns an iterator to the end of the array.
---
```C++
iterator rbegin()
const_iterator rbegin() const
const_iterator crbegin() const
```
**Description**
Returns a reverse iterator to the beginning of the array.
---
```C++
iterator rend()
const_iterator rend() const
const_iterator crend() const
```
**Description**
Returns a reverse iterator to the end of the array.
## Capacity
```C++
bool empty() const
```
**Description**
Returns true if the size of the array is zero, otherwise false.
---
```C++
size_t size() const
```
**Description**
Returns the size of the array.
---
```C++
size_t max_size() const
```
**Description**
Returns the maximum possible size of the array.
## Modifiers
```C++
void fill(T value)
```
**Description**
Fills the array with value.
## ETL Extensions
```C++
template <typename TIterator>
void assign(TIterator first, const TIterator last)
```
```C++
template <typename TIterator>
void assign(TIterator first, const TIterator last, parameter_t value)
```
**Description**
Assigns a range of values to the array. The second form set uninitialised elements to value.
If the range is larger than the array then the extra data is ignored.
If the range is smaller than the array then the unused array elements are left unmodified.
---
```C++
iterator insert_at(size_t position, parameter_t value)
iterator insert(const_iterator position, parameter_t value)
```
**Description**
Inserts a value into the array at the specified position, shifting elements to make room.
Elements may be truncated if they are shifted off the end of the array.
---
```C++
template <typename TIterator>
iterator insert_at(size_t position, TIterator first, const TIterator last)
```
**Description**
`position` is not checked for validity.
---
```C++
template <typename TIterator>
iterator insert(const_iterator position, TIterator first, const TIterator last)
```
**Description**
Inserts a range of values into the array at the specified position, shifting elements to make room.
Elements may be truncated if they are shifted off the end of the array.
The range may be larger than the capacity of the array. Excess elements will be ignored.
---
```C++
iterator erase_at(size_t position)
iterator erase_at(size_t position, parameter_t value)
iterator erase(const_iterator position)
iterator erase(const_iterator position, parameter_t value)
```
**Description**
Erases an element at the specified position, shifting elements into the space.
The value parameter variants initialise the unused elements with value, while the others leave them unchanged.
position is not checked for valid range.
---
```C++
iterator erase_range(size_t first, size_t last)
iterator erase_range(size_t first, size_t last, parameter_t value)
iterator erase(const_iterator first, const_iterator last)
iterator erase(const_iterator first, const_iterator last, parameter_t value)
```
**Description**
Erases a range, shifting elements into the space.
The value parameter variants initialise the unused elements with value, while the others leave them unchanged.
first/last are not checked for valid range.
## Non-member functions
**Lexicographically comparisons**
`operator ==`
**Returns**
`true` if the contents of the arrays are equal, otherwise `false`.
`operator !=`
**Returns**
`true` if the contents of the arrays 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`.

View File

@ -0,0 +1,359 @@
---
title: "array_view"
---
---
{{< callout type="info">}}
Header: `array_view.h`
Supported: 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.
```C++
etl::array_view<typename T>
```
## Template deduction guides
**C++17 and above**
```C++
template <typename TArray>
etl::array_view(TArray& a)
-> etl::array_view<typename TArray::value_type>;
```
```C++
template <typename TIterator>
etl::array_view(const TIterator begin_, const TIterator end_)
-> etl::array_view<etl::remove_pointer_t<TIterator>>;
```
```C++
template <typename TIterator, typename TSize>
etl::array_view(const TIterator begin_, const TSize size_)
-> etl::array_view<etl::remove_pointer_t<TIterator>>;
```
## Examples
```C++
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
```C++
ETL_CONSTEXPR array_view()
```
**Description**
Default constructor.
---
```C++
template <typename TArray>
ETL_CONSTEXPR explicit array_view(TArray& a)
```
**Description**
Construct from array or vector like class.
---
```C++
template <typename TIterator>
ETL_CONSTEXPR array_view(TIterator begin_, TIterator end_)
```
**Description**
Construct from an iterator or pointer range.
---
```C++
template <typename TIterator, typename TSize>
ETL_CONSTEXPR array_view(TIterator begin_, TSize size_)
```
**Description**
Construct from a start and size
---
```C++
template<const size_t ARRAY_SIZE>
ETL_CONSTEXPR explicit array_view(T(&begin_)[ARRAY_SIZE])
```
**Description**
Construct from a compile time sized C array.
---
```C++
ETL_CONSTEXPR array_view(const array_view& other)
```
**Description**
Copy constructor.
## Modifiers
```C++
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.
---
```C++
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.
---
```C++
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.
---
```C++
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.
---
```C++
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.
```C++
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
---
```C++
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.
---
```C++
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.
---
```C++
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.
---
```C++
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
```C++
iterator begin()
const_iterator begin() const
const_iterator cbegin() const
```
**Description**
Returns an iterator to the beginning of the array view.
---
```C++
iterator end()
const_iterator end() const
const_iterator cend() const
```
**Description**
Returns an iterator to the end of the array view.
---
```C++
iterator rbegin()
const_iterator rbegin() const
const_iterator crbegin() const
```
**Description**
Gets a reverse iterator to the beginning of the array view.
---
```C++
iterator rend()
const_iterator rend() const
const_iterator crend() const
```
**Description**
Gets a reverse iterator to the end of the array view.
---
Capacity
```C++
bool empty() const
```
**Description**
Returns true if the size of the array view is zero, otherwise false.
---
```C++
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**
`operator ==`
**Returns**
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`.
## Hash
There are specialisations of `etl::hash` for `array_view`.
## Example
```C++
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,268 @@
---
title: "array_wrapper"
---
---
{{< callout type="">}}
Header: `array_wrapper.h`
Supported: 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
```C++
T& at(size_t i)
```
```C++
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.
---
```C++
T& operator[](size_t i)
```
```C++
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.---
---
```C++
T& front()
```
```C++
ETL_CONSTEXPR const T& front() const
```
**Description**
Returns a reference or const reference to the first element.---
---
```C++
T& back()
```
```C++
ETL_CONSTEXPR const T& back() const
```
**Description**
Returns a reference or const reference to the last element.---
---
```C++
T* data()
```
```C++
ETL_CONSTEXPR const T* data() const
```
**Description**
Returns a pointer or const pointer to the array.---Modifiers
---
```C++
void fill(parameter_t value)
```
**Description**
Fill a non-cost array with the value.---
---
```C++
template <typename T, T(&ARRAYOTHER)[SIZE_]>
void swap(etl::array_wrapper<T, SIZE_, ARRAYOTHER>& other)
```
**Description**
Swaps the array contents with another.---Iterators
---
```C++
ETL_CONSTEXPR iterator begin()
```
```C++
ETL_CONSTEXPR const_iterator begin() constETL_CONSTEXPR const_iterator cbegin() const
```
**Description**
Returns an iterator to the beginning of the array.---
---
```C++
ETL_CONSTEXPR iterator end()
```
```C++
ETL_CONSTEXPR const_iterator end() constETL_CONSTEXPR const_iterator cend() const
```
**Description**
Returns an iterator to the end of the array.---
---
```C++
ETL_CONSTEXPR iterator rbegin()
```
```C++
ETL_CONSTEXPR const_reverse_iterator rbegin() const
```
```C++
ETL_CONSTEXPR const_reverse_iterator crbegin() const
```
**Description**
Returns a reverse iterator to the beginning of the array.---
---
```C++
ETL_CONSTEXPR iterator rend()
```
```C++
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
---
```C++
ETL_CONSTEXPR size_t size() const
```
**Description**
Returns the size of the view.---
---
```C++
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
```C++
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.
```C++
ETL_ARRAY_WRAPPER(type, array);
```
**Example**
```C++
// 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,154 @@
---
title: "bip_buffer_spsc_atomic"
---
---
{{< callout type="">}}
Header: `bip_buffer_spsc_atomic.h`
Supported: 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.
```C++
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
```C++
etl::bip_buffer_spsc_atomic<typename T,
size_t SIZE,
size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>();
```
## Capacity
```C++
bool empty() const
```
**Description**
Returns `true` if the size of the circular buffer is zero, otherwise `false`.
---
```C++
bool full() const
```
**Description**
Returns `true` if the size of the circular buffer is `SIZE`, otherwise `false`.
---
```C++
size_t size() const
```
**Description**
Returns the size of the circular buffer.
---
```C++
size_t max_size() const
```
**Description**
Returns the maximum possible size of the circular buffer.
---
```C++
size_t capacity() const
```
**Description**
Returns the maximum possible size of the circular buffer.
---
```C++
size_t available() const
```
**Description**
Returns the remaining available capacity in the circular buffer.
## Modifiers
```C++
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`).
```C++
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`.
---
```C++
etl::span<T> write_reserve(size_type max_reserve_size)
```
**Description**
Reserves a memory area for writing up to the `max_reserve_size`.
---
```C++
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`.
---
```C++
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`
---
```C++
void clear()
```
**Description**
Clears the buffer, destructing any elements that haven't been read.

422
docs/containers/bitset.md Normal file
View File

@ -0,0 +1,422 @@
---
title: "bitset"
---
---
{{< callout type="">}}
Header: `bitset.h`
Supported: 20.33.0
Similar to: [std::bitset](https://en.cppreference.com/w/cpp/utility/bitset.html)
{{< /callout >}}
This is the new default bitset implementation, from 20.33.0 onwards.
For the older version, see [etl::bitset (legacy)]().
A fixed capacity bitset.
Has a number of extensions over std::bitset. Can be considered similar to an array of bool.
Internally defined buffers
```C++
etl::bitset<size_t N>
etl::bitset<size_t N, typename TElement>
```
Externally defined buffers from `20.34.0`
```C++
etl::bitset_ext<size_t N>
etl::bitset_ext<size_t N, typename TElement>
```
The template parameters will determine whether the bitset uses a common implementation or one of four fixed sized
implementations.
Note: `etl::ibitset` is no longer a reference type for any size `etl::bitset`.
---
`etl::bitset<size_t N>` and `etl::bitset_ext<size_t N>` on their own will use `unsigned char` as the underlying element type and the operations will be implemented by the generic protected member functions in `etl::ibitset`.
---
```C++
etl::bitset<size_t N, typename TElement>
```
```C++
etl::bitset_ext<size_t N, typename TElement>
```
Specifying a type for `TElement` will override the default element type and define it as the *unsigned* type of `TElement`.
**Specialisations for maximum efficiency**
There are specialisations for when the required number of bits matches the number of bits in the element type.
These specialisations are considerably faster and more efficient.
```C++
etl::bitset<8, uint8_t>
etl::bitset<16, uint16_t>
etl::bitset<32, uint32_t>
etl::bitset<8, uint64_t>
```
`any()`, `none()` and `all()` are overloaded in these specialisations to allow a mask to be specified, so that a bitset that requires less bits than the element type may still use the most efficient implementation.
```C++
etl::bitset<8, uint8_t> bst; // But only want to use 6 bits.
bool any = bst.any(0x3F); // Check the lower 6 bits.
```
## Types
| Type | |
| - | - |
|`span_type` | A mutable span type. |
|`const_span_type`| A non-mutable span type. |
|`element_type` | The type used as the internal storage for a bitset. By default, this is unsigned char. |
|`buffer_type` | The type used as the to define the external buffer. Defined in etl::bitset_ext only. 20.34.0 |
## Constants
All `npos` values are equivalent.
```C++
etl::bitset_constants::npos
```
```C++
etl::bitset<>::npos
```
```C++
template <size_t Size, typename TElement>
etl::bitset<Size, TElement>::npos
```
`Number_Of_Elements`
`Bits_Per_Element`
`Allocated_Bits`
`All_Set_Element`
`All_Clear_Element`
From: 20.38.11
`Storage_Model` `etl::bitset_storage_model::Single` or `etl::bitset_storage_model::Multi`
## Constructors
The initial state of the bitset is all clear (`false`).
```C++
etl::bitset();
etl::bitset(unsigned long value);
etl::bitset(const char* str);
etl::bitset(const wchar_t* str);
etl::bitset(const char16_t* str);
etl::bitset(const char32_t* str);
```
**Description**
The bitset is either default constructed, initialised with a numeric value, or a text string of zeros and ones.
---
```C++
etl::bitset_ext(element_type* pbuffer);
etl::bitset_ext(unsigned long value, element_type* pbuffer);
etl::bitset_ext(const char* str, element_type* pbuffer);
etl::bitset_ext(const wchar_t* str, element_type* pbuffer);
etl::bitset_ext(const char16_t* str, element_type* pbuffer);
etl::bitset_ext(const char32_t* str, element_type* pbuffer);
```
**Description**
The bitset is either default constructed, initialised with a numeric value, or a text string of zeros and ones.
A pointer to the external must b supplied that is large enough to hold the bitset.
The buffer may be defined as follows:-
```C++
using Bitset = etl::bitset_ext<32>;
Bitset::element_type buffer[Bitset::Number_Of_Elements];
```
From: 20.34.0
---
```C++
etl::bitset_ext(buffer_type& buffer);
etl::bitset_ext(unsigned long value, buffer_type& buffer);
etl::bitset_ext(const char* str, buffer_type& buffer);
etl::bitset_ext(const wchar_t* str, buffer_type& buffer);
etl::bitset_ext(const char16_t* str, buffer_type& buffer);
etl::bitset_ext(const char32_t* str, buffer_type& buffer);
```
**Description**
The bitset is either default constructed, initialised with a numeric value, or a text string of zeros and ones.
A n external must b supplied that is large enough to hold the bitset.
The buffer may be defined as follows:-
```C++
using Bitset = etl::bitset_ext<32>;
Bitset::buffer_type buffer;
```
From: 20.34.0
## Modifiers
```C++
etl::bitset& set();
```
**Description**
Set all bits.
---
```C++
etl::bitset& set(element_type value);
```
**Description**
20.34.0
Set the bits to value.
Valid when the bitset width matches the element type width.
---
```C++
etl::bitset& set(const char* str);
etl::bitset& set(const wchar_t* str);
etl::bitset& set(const char16_t* str);
etl::bitset& set(const char32_t* str);
```
**Description**
Set with a text string of `0` and `1` characters.
---
```C++
etl::bitset& set(size_t position, bool value = true);
```
**Description**
Set a position to a one or zero, default one.
---
```C++
etl::bitset& reset();
```
**Description**
Reset all bits.
---
```C++
etl::bitset& reset(size_t position);
```
**Description**
Set a position to a zero.
---
```C++
etl::bitset& from_string(const char*);
etl::bitset& from_string(const wchar_t*);
etl::bitset& from_string(const char16_t*);
etl::bitset& from_string(const char32_t*);
```
**Description**
Alias of set.
The bitset is built from a string of `0` and `1` characters.
## Access
```C++
template <typename T>
T value() const
```
**Description**
Returns the value corresponding to the bitset.
`T` specifies the integral type to convert to.
---
```C++
unsigned long to_ulong() const
unsigned long long to_ullong() const
```
**Description**
Functions for compatibility with the STL.
Calls value<unsigned long>() or value<unsigned long long>().
If the type is too small to contain the bitset size, a compile time error will result.
---
```C++
template <typename TString>
TString to_string(typename TString::value_type zero = typename TString::value_type('0'),
typename TString::value_type one = typename TString::value_type('1')) const
```
Returns the value as a string of `0` and `1` characters.
If the string type is not large enough to contain the digits then an `etl::bitset_string_too_small` is emitted.
---
```C++
span_type span()
const_span_type span() const
```
**Description**
Returns an `etl::span` of the underlying binary data.
The span is ordered LSB to MSB.
---
```C++
template <typename T>
ETL_CONSTEXPR14
T extract(size_t position, size_t length = etl::integral_limits<T>::bits) const
```
**Description**
Extract an integral value from an arbitrary position and length.
Run time position and length.
---
```C++
template <typename T, size_t Position, size_t Length = etl::integral_limits<T>::bits>
ETL_CONSTEXPR14
T extract() const
```
**Description**
Extract an integral value from an arbitrary position and length.
Compile time position and length.
From: 20.38.11
For C++11 and above
---
```C++
template <typename T, size_t Position, size_t Length>
T extract() const
```
**Description**
Extract an integral value from an arbitrary position and length.
Compile time position and length.
20.38.11
For C++98/03
## Bit access
```C++
bool operator[](size_t position) const
```
**Description**
Returns the boolean state of the indexed bit.
position is not checked for validity.
---
```C++
size_t count() const
```
**Description**
Returns the number of set bits.
---
```C++
size_t size() const
```
**Description**
Returns the number of bits supported by this bitset.
---
```C++
bool test(size_t position) const
```
**Description**
Returns the boolean state of the indexed bit.
position is not checked for validity.
---
```C++
bool any() const
```
**Description**
Returns true if any of the bits are set, otherwise false.
```C++
bool any(element_type mask) const
```
**Description**
Only enabled for bitsets that fit within one element.
Returns true if any of the bits are set, after the mask has been applied, otherwise false.
Valid when the bitset width matches the element type width.
20.34.0
---
```C++
bool none() const
```
**Description**
Returns true if none of the bits are set, otherwise false.
```C++
bool none(element_type mask) const
```
**Description**
Only enabled for bitsets that fit within one element.
Returns true if none of the bits are set, after the mask has been applied, otherwise false.
Valid when the bitset width matches the element type width.
20.34.0
---
```C++
bool all() const
```
**Description**
Returns true if al of the bits are set, otherwise false.
```C++
bool all(element_type mask) const
```
**Description**
Only enabled for bitsets that fit within one element.
Returns true if al of the bits are set, after the mask has been applied, otherwise false.
Valid when the bitset width matches the element type width.
20.34.0
---
```C++
size_t find_first(bool state) const
```
**Description**
Returns the position of the first bit in the specified state. If not found then returns bitset<>::npos.
---
```C++
size_t find_next(bool state, size_t position) const
```
**Description**
Returns the position of the next bit in the specified state, starting from position. If not found then returns bitset<>::npos.
position is not checked for validity.
## Bit operations
```C++
bitset<size_t Size>& operator &= (const bitset<size_t Size>& rhs);
bitset<size_t Size>& operator |= (const bitset<size_t Size>& rhs);
bitset<size_t Size>& operator ^= (const bitset<size_t Size>& rhs);
bitset<size_t Size>& operator <<= (size_t shift);
bitset<size_t Size>& operator >>= (size_t shift);
bool operator == (const bitset<size_t Size>& rhs);
bool operator != (const bitset<size_t Size>& rhs);
```
## Non-member functions
```C++
void swap(etl::bitset<Size>& lhs, etl::bitset<Size>& rhs)
```
**Description**
Swaps the contents of the two bitsets.
The bitsets must be the same size.

View File

@ -0,0 +1,12 @@
---
title: "indirect_vector"
---
---
{{< callout type="info">}}
Header: `vector.h`
Supported: All versions
Similar to: [std::vectr](https://en.cppreference.com/w/cpp/container/vector.html)
{{< /callout >}}

12
docs/containers/vector.md Normal file
View File

@ -0,0 +1,12 @@
---
title: "vector"
---
---
{{< callout type="info">}}
Header: `vector.h`
Supported: All versions
Similar to: [std::vectr](https://en.cppreference.com/w/cpp/container/vector.html)
{{< /callout >}}

View File

@ -1,3 +0,0 @@
---
title: "vector"
---

View File

@ -112,5 +112,3 @@ p {
color: black !important;
background-color: white !important;
}

View File

@ -0,0 +1,38 @@
---
title: "Arduino"
weight: 5
---
---
This page describes the issue specific to using the ETL with the Arduino platform.
The Arduino version of the ETL may be downloaded either through the Arduino IDE's library manager, or the ZIP fileavailable from the GitHub repository.
To alleviate possible header name clashes, the ETL headers are accessed via the `etl` sub-directory.
For the Arduino IDE you must also include `Embedded_Template_Library.h`, otherwise the IDE will not believe that the library exists! This is not necessary if you are using PlatformIO.
If you wish to identify the Arduino board then `Embedded_Template_Library.h` will define `ARDUINO_BOARD` as a literal string. If the board cannot be recognised then this will be set to "Unknown".
You must also define `ETL_NO_STL` if you are not using the STL.
```C++
#define ETL_NO_STL
#include <Arduino>
#include <Embedded_Template_Library.h> // Mandatory for Arduino IDE only
#include <etl/vector.h> // Use the ETL's vector class
String board(ARDUINO_BOARD);
void setup()
{
}
void loop()
{
}
```

View File

@ -0,0 +1,87 @@
---
title: "Compilers"
weight: 3
---
---
The library is intended to be used on multiple platforms and devices. Not every single combination ofcompiler/IDE/device/library template have been, or can realistically be, checked. A set of profiles have been created for the most popular setups.
If you have issues porting the library to your platform then contact me, and I will do my best to resolve anyincompatibilities.
If you have no issues, or have solved it by yourself then please [let me know](https://github.com/ETLCPP/etl/issues) so that I may add information about it to this page.
## Visual Studio
Has been compiled under VS2019 and VS2022.
No known issues.
## GCC
Has been compiled under GNU GCC on Windows & Linux.
No known issues, apart from early versions of GCC that may need to define the macro `__STDC_LIMIT_MACROS` in the project properties.
## Keil
**uVision ARM**
Define the macro `__STDC_LIMIT_MACROS` in the project properties.
Compiled with version 5 & 6 ARM compilers.
No known issues.
## TI Code ComposerMPS430
Define the macro `__STDC_LIMIT_MACROS` in the project properties.
In TI projects you have the choice between EABI and COFF file formats.
There is a known issue with the COFF format when creating static libraries that use templates. You may find that the linker will complain about 'undefined symbols'.
The only known workaround is to declare a dummy type in the main application that uses the template with the same parameter types.
e.g.
If your static library uses `etl::vector<MyType, N>` then declare a dummy type `etl::vector` of the same type in the application.
## IAR Embedded Workbench
**AVR Compiler**
**ARM**
Define the macro `__STDC_LIMIT_MACROS` in the project properties.No known issues.
## Segger Embedded Studio
**ARM**
If using STLPort then the macro `ETL_STLPORT` must be defined in the profile.
## Greenhills
**ARM**
No known issues.
## Zephyr OS
The ETL uses 'placement new'.
To enable this from Zephyr you need to add the following to `proj.conf`.
`CONFIG_LIB_CPLUSPLUS=yCONFIG_NEWLIB_LIBC=y`
## avr-gcc 9.2
If you are using `-std=c++2a` you will find the compiler complaining aboutredeclaration of C++ built-in type `char8_t` `[-fpermissive]`
Add this to your `etl_profile.h` or define it in the project properties.
`#define ETL_NO_SMALL_CHAR_SUPPORT 0`
You may also want to define `#define ETL_CPP20_SUPPORTED 0`
## Arduino
**Arduino IDE**
**Visual Studio with Visual Micro extension**
The Arduino programming platform is not supplied with an implementation of the STL. The ETL can use of somefeatures of the STL to compile, and therefore either one must be acquired or the project is compiled with `ETL_NO_STL` defined.
A suitable STL implementation may be downloaded from the Arduino library resource; It is called **ArduinoSTL**.
Add `#include <ArduinoSTL.h>` to the start of every file that uses the ETL.
Remember to add the directory to the include path.
The alternative option is to compile with `ETL_NO_STL` defined, if the STL is not used in your project.
Partially tested for Zero, Uno, Yún, Mega, Industrial 101 and Leonardo boards using `test_embedded_compile.cpp`
### Issues
**Zero**
**Arduino101**
**TinyTile**
`<algorithm>` must be edited to move the template function iter_swap before the declaration of swap_ranges.The template class variant will not currently compile unless the header file is either renamed or the include path somehow altered, as the platform also defines a header named `variant.h`.
**Duo**
Fails to find `ArduinoSTL.h` even though it is present.
If `ArduinoSTL.h` is removed, then fails with printf has not been declared.
**General**
It may be necessary to add the following lines to the beginning of the file.
```C++
#undef min
#undef max
```

View File

@ -0,0 +1,245 @@
---
title: "Contributing to the ETL"
weight: 6
---
---
Thanks for considering a contribution! Heres what you need to know before opening a pull request:
If you are thinking of adding a new feature then raise this on the GitHub Issues page for discussion as the maintainers and users of the ETL may have questions or suggestions.
It is possible that the maintainer of the ETL or another contributor is already working on the same or a related feature.
Take a look through our current issues and see if anything sparks your interest!
Although the majority of the library has been written by me, I'm always open to contributions from other people. There are always a number of features and enhancements that either I'd like to see, or have been suggested by other users, but I only have a finite amount of time to give.
I accept contributions both big and small; If you have an idea for a funky non-standard container that you think would complement the library, then let us know. If you just want to add an enhancement to an existing class, tell us about that too.
This is a very friendly project and I'm not going to start shouting at you if I see issues with your idea or code. If there is a problem then we can have a dialog about what should be changed.
Feel free to argue your case.
There are always a number of issues outstanding that could usefully be taken up whole, or in part, by someone else.
## Project Style
I care about code style and will flag issues in review, but I promise to be constructive about it, not aggressive. With that said, here are a few design rules I ask you to adhere to.
### Public API
The style of the public API of the class should mirror that of the STL.
### Class and function names
Lower case class and function names, separated by an underscore.
`funky_container`
`do_something`
### Nameing convension
Use the same naming convention as the STL.
If appropriate for the class, a set of `typedef`s should often be present to define types such as...
`type`
`value`
`value_type`
`size_type`
`pointer`
`const_pointer`
`reference`
If the code is only for C++11 and above you may use the more modern `using` syntax.
### Similarity to the STL
If a function does something similar to that in a standard class in the STL then use the same terminology.
`push_back`
`insert_after`
`erase`
`assign`
`clear`
`size`
### C++ standards
If a feature is only implementable for a certain C++ standard or above, wrap the code in
`#if #endif`, with one of the following:-
`ETL_USING_CPP11` For C++11 or above
`ETL_USING_CPP14` For C++14 or above
`ETL_USING_CPP17` For C++17 or above
`ETL_USING_CPP20` For C++20 or above
`ETL_USING_CPP23` For C++23 or above
i.e.
```C++
#if ETL_USING_CPP11
...
#endif
```
### Macros
Macros should use `THIS_STYLE`.
### Constants
Constants should use `This_Style`.
### Namespace
All ETL classes are to be within the `etl` namespace.
### Private functionality
All classes private to the ETL should reside in a nested namespace prefixed with `private_`
```C++
namespace etl
{
namespace private_funky_container
{
struct helper
{
//…
};
}
class funky_container
{
private_funky_container::helper helper;
};
}
```
### Naming
Use descriptive names for internal variables and functions.
### Comments
Use comments to summarise or explain blocks of code that may be difficult to quickly understand.
### 8 bit types
Avoid using `int8_t` or `uint8_t`.
Some processors such as DSPs do not support 8 bit values. Use `int_least_8_t` and `uint_least8_t` in their place.
If `int8_t` or `uint8_t` must be used then surround the code with
```C++
#if ETL_USING_8BIT_TYPES
#endif
```
### 64 bit types
If `int64_t` or `uint64_t` must be used
Then surround the code with
```C++
#if ETL_USING_64BIT_TYPES
#endif
```
### Bit lengths
Never assume the bit length of a type.
If the bit length is important then either use a type from stdint.h or interrogate the type for its size.
### Mininmum and maximum values
Never assume the minimum or maximum values for a type.
Use `etl::numberic_limits` or `etl::inyegral_limits` to look them up.
### Compile time asserts
Where ever possible, add `ETL_STATIC_ASSERT` to catch errors at compile time, rather than runtime.
### Run time asserts
Use the ETL macros to report runtime errors.
This will ensure that the correct code is generated for the user selected error reporting method.
`ETL_ASSERT(!full(), ETL_ERROR(stack_full));`
### Constructors
Align the initialisation of member variables in constructors as below.
```C++
class my_new_class
{
public:
my_new_class(int a_, int b_, int c_)
: a(a_)
, b(b_)
, c(c_)
{
}
};
```
### Layout
When possible, try to tabluate the initialisation of multiple variables. It's a lot easier to read.
Don't be too strict about it, if it would result in giant amounts of whitespace.
```C++
int count = 0;
double divisor = 1.234;
etl::string<10> name = "Default";
etl::string_view view(name, begin(), name.end());
etl::intrusive_forward_list<data_link_type> quite_long_variable_name(data1, data2, data3);
```
### ETL errors
ETL errors are packaged in exception structures. Do not get confused with this terminology, it does not mean that it will *always* be thrown as an exception. It may just be passed as a parameter to an error handler.
```C++
class stack_exception : public exception
{
public:
stack_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
: exception(reason_, file_name_, line_number_)
{
}
};
class stack_full : public stack_exception
{
public:
stack_full(string_type file_name_, numeric_type line_number_)
: stack_exception(ETL_ERROR_TEXT("stack:full", ETL_STACK_FILE_ID"A"), file_name_, line_number_)
{
}
};
```
Define the file id in `file_error_numbers.h`
`#define ETL_STACK_FILE_ID "33"`
## Unit Tests
Every class or function that is in the library must be unit tested. Do not submit your code unless you have a full set of tests that exercise as much of the functionality as you can possibly think of. Make sure that you cover all of the corner cases.
There is a project file for VS2022 for C++14, 17, 20, 23, and bash scripts that run the tests for C++11, 14, 17, 20, 23 under Linux with GCC and Clang.
## Bash Scripts
There are bash scripts to test the ETL under Linux.
These scripts are run from the test directory.
| `run-tests.sh` | Runs the set of unit tests with various options and compilers. |
| -------------- | ------------------------------------------------------------------------------ |
| Syntax | `./runtests.sh <C++ Standard> <Optimisation> <Threads> <Sanitizer> <Compiler>` |
| C++ Standard | 11, 14, 17, 20, or 23 (mandatory argument) |
| Optimisation | 0, 1, 2 or 3. Default = 0 |
| Threads | Number of threads to use. Default = 4 |
| Sanitizer | s enables sanitizer checks, n disables. Default disabled |
| Compiler | gcc or clang. Default All compilers |
| `run-syntax-checks.sh` | Runs the set of header files through the compilers to test syntax correctness. |
| ---------------------- | ------------------------------------------------------------------------------ |
| Syntax | `./runtests.sh <C++ Standard> <Threads>` |
| C++ Standard | a, 03, 11, 14, 17, 20, or 23. a = All standards |
| Threads | Number of threads to use. Default = 4 |
| Compiler | gcc or clang. Default = All compilers |
## Pull Requests
If you wish to create a pull request to the ETL repository on GitHub then create your changes in a branch that is based on `master`. When you think you have completed your modifications then raise a pull request.
When opening a new pull request, ensure that you include the following information.
- Is this brand new functionality, an enhancement to existing code?
- If it is a bug fix, What problem are you solving? Give an example of how to reproduce it.
- If it is a new feature or enhancement, what will be the benefit to the ETL or user of the library?
- If you are adding or modifying a feature, add *new* unit tests that test that feature.
- If you are fixing a bug, add a unit test that *fails* before the bug fix is implemented.
- Do not initiate a pull request until *all* of the units tests pass. See above for information on project files and test scripts.
- Branches should be based on the branch `master`.
`development` can change quite frequently, so I will rebase the your PR against it before merging.
- For formatting help, you can use `clang-format`, or the convenience wrapper `treefmt`. See also [Source formatting]({{% ref "source-formatting.md" %}}).
- Update the relevent documentation markdown file, found in `etl/docs`.

View File

@ -0,0 +1,21 @@
---
title: "Header guards"
weight: 6
---
---
The ETL as a default uses `#include` headers guards.
If you wish, you can convert them to using `#pragma once`.
## Install guardonce
`python3 -m pip install guardonce`
## Modify all of the headers
Navigate to `etl/scripts`
To change from `#include` guard to `#pragma once`
`./convert_headers_to_use_once.bat`
To change from `#pragma` once to `#include guard`
`./convert_headers_to_use_guards.bat`

View File

@ -0,0 +1,48 @@
---
title: "No STL"
weight: 2
---
---
It is possible to use the ETL without any reliance on the STL —
This can be achieved by defining the project wide macro `ETL_NO_STL`.
When this macro is defined then the ETL will used its own reverse engineered versions of traits and algorithms.
These traits and algorithms are available to the user of the ETL, regardless of whether the STL is used or not.
When the STL is used, then, for the most part, the ETL will merely act as a wrapper around the STL definitions.
For STL/ETL compatibility, some algorithms and classes in the ETL will use an STL or ETL defined version of a class. For example, if you are using the STL then a function using or returning a pair will use a std::pair.On the other hand, when `ETL_NO_STL` is defined, an `etl::pair` is used.
If you wish your code to be able to compiler both with and without the STL, then you would use the `ETL_OR_STD` namespace macro, which resolves to either `std` or `etl`.
If the C++ level of your compiler does not support a particular algorithm (e.g. C++03 compiler and `std::sorted_until`), then the ETL will revert to its own version.
## Using pair, move, iterator tags or reverse_iterator + others
When `ETL_NO_STL` is defined then the ETL will use its own versions, otherwise the STL versions will be used. This will affect the return types of certain functions.e.g. `etl::equal_range` will return `ETL_OR_STD::pair` which resolves to either `std::pair` or `etl::pair` ETL types and functions which are not defined in the ETL namespace when the STL is in use :-
`pair`
`make_pair`
`reverse_iterator`
`input_iterator_tag`
`output_iterator_tag`
`forward_iterator_tag`
`bidirectional_iterator_tag`
`random_access_iterator_tag`
`begin`
`cbegin`
`rbegin`
`crbegin`
`end`
`cend`
`rend`
`crend`
`size`
`swap`
## Note
The ETL is not intended to be a complete clone of the STL.
The ETL's version of STL features is not exhaustive, and many features are missing.
That said, if there is an STL feature missing from the No STL option, then feel free to add it yourself and generate a pull request.

View File

@ -1,16 +1,18 @@
---
title: "Setup"
weight: 1
---
---
This page describes the steps needed to integrate the ETL with your project.
The ETL requires no special installation. Just copy or clone the GitHub project into an appropriate directory.
For additional information pertaining to compilers, see this page.
For additional information pertaining to compilers, see [this page](https://www.etlcpp.com/compilers.html).
The ETL does not depend on the STL, but can use the algorithms and definitions from it, if the project does.
This is controlled by the ETL_NO_STL macro. If this macro is defined in the profile then the ETL will use its own reverse engineered versions.
See No STL
This is controlled by the ETL_NO_STL macro. If this macro is defined in the profile then the ETL will use its own reverse engineered versions.
See [No STL]().
## User defined files
The user may create a file named `etl_profile.h` that exists in the include path for the project.
@ -54,17 +56,18 @@ There is a WSL Ubuntu image for running unit tests on Windows Subsystem for Linu
## Arduino
The ETL is available through the Arduino library manager.
## Missing <new>
**Missing `new`**
The Arduino is often not supplied with a definition of the header `<new>` causing compilation to fail.
One option, if you have this problem, is to define your own empty header `new`.
## STL
The Arduino programming platform is not supplied with an implementation of the STL. Probably the best option for Arduino users to define ETL_NO_STL which will allow the ETL to be compiled without the standard library.
The Arduino programming platform is not supplied with an implementation of the STL. Probably the best option for Arduino users to define `ETL_NO_STL` which will allow the ETL to be compiled without the standard library.
If `ETL_NO_STL` is not defined then one must be acquired.
A suitable STL implementation may be downloaded from the Arduino library resource. It is called ArduinoSTL.
Add `#include <ArduinoSTL.h>` to the start of every file that uses the ETL.
A suitable STL implementation may be downloaded from the Arduino library resource. It is called **ArduinoSTL**.
Add `#include <ArduinoSTL.h>` to the start of every file that uses the ETL.
Remember to add the directory to the include path.
## PlatformIO

183
docs/page-template.md Normal file
View File

@ -0,0 +1,183 @@
---
title: "Page Template"
draft: true
weight: 1
---
---
{{< callout type="info">}}
Header: `my_class.h`
Supported: `xx.yy.zz`
Similar to: [Some similar in the STL](https://en.cppreference.com/w/cpp/stl_header.html)
{{< /callout >}}
A short description of the code this document is about.
```C++
The signature of the class, struct, or function
```
## Template Parameters
```C++
TParameter1
```
**Description**
A description the the TParameter1 template parameter.
---
```C++
TParameter1
```
**Description**
A description the the TParameter1 template parameter.
## Exceptions
```C++
etl::your_firt_exception_type
```
**Description**
Description of what the exception indicates.
## Member Types
```C++
`first_member_type`
```
**Description**
The first member type
```C++
return_type
```
**Description**
`The second class member type`
```C++
argument_types
```
**Description**
## Constructors
`my_class()`
**Description**
Default constructor.
**Parameters**
`void`
---
`my_class(const my_class&)`
**Description**
Copy constructor.
**Parameters**
Const reference to etl::my_class.
---
`my_class(my_class&&)`
**Description**
Move constructor.
**Parameters**
rvalue reference to etl::my_class.
## Invocation
```C++
int operator(float f)
```
**Description**
Invokes the function operator.
**Parameters**
`f` The floating point parameter.
**Returns**
An integer calculated from the float.
---
```C++
int calculate(float f)
```
**Description**
Calculates an integer from a float.
**Parameters**
`f` The floating point parameter.
**Returns**
An integer calculated from the float.
## Observers
```C++
bool is_valid() const
```
**Returns**
`true` if the object is valid.
## Modifiers
```C++
void clear()
```
**Description**
Clears the object.
**Parameters**
None
**Returns**
`void`
---
```C++
void swap(my_class& other)
```
**Description**
Swaps with another my_class object.
**Parameters**
A reference to another my_class object.
**Returns**
`void`
## Example
```C++
#include "etl/my_class.h"
etl::my_class my_object1;
etl::my_class my_object2;
int main()
{
my_object1.swap(my_object2);
if (my_object.is_valid())
{
return my_object1(1.23f);
}
else
{
return 0;
}
}
```
## Notes
Some other notes about `etl::my_class`.

View File

@ -13,10 +13,7 @@ html:not(.dark) h3,
html:not(.dark) h4
{
color: green !important;
}
html:not(.dark) h4 code {
color: black !important;
border-bottom: 1px solid darkgrey !important;
}
html:not(.dark) p {
@ -98,7 +95,8 @@ html.dark h2 {
html.dark h3,
html.dark h4 {
color: lightgreen !important;
color: lightgreen !important;
border-bottom: 1px solid rgb(76, 76, 76) !important;
}
html.dark p {
@ -186,8 +184,8 @@ html.dark .content p.red-text {
h1 {
font-family: Roboto, sans-serif !important;
font-style: normal !important;
font-weight: normal !important;
font-style: i !important;
font-weight: 500 !important;
margin-top: 0.5em !important;
margin-bottom: 0.0em !important;
}
@ -283,7 +281,7 @@ p {
font-style: normal !important;
font-weight: normal !important;
font-size: 110% !important;
margin-top: 1em !important;
margin-top: 1em !important;
}