Further, switching internal member from array_view to span to
be closer to standard, and more constexpr friendly.
Also adjusting to C++11 template syntax.
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
Besides, remove unused ASAN_OPTIONS from github workflows.
Further, activate sanitizers for C++23 workflows, at the places
where we also activated -O3 optimization. Not activating everywhere
for CI efficiency reasons for now.
Note that the sanitizers are activated on clang C++23 workflows
only, since there is a remaining issue with GCC in delegate_cpp11.
* Update _index.md
* Update _index.md
* Cherry pick the Docker fixes for PowerPC (#1563)
Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com>
* Fixed building and unit tests run under XCode 2027 Beta 6 (AppleClang 21.0.0.21000333):
- Compilation failures:
- `etl::ideque::iterator::operator[]` index type should be `difference_type` (instead of `size_t`).
- random-access `etl::poly_span::iterator` is missing `operator[]`.
- Unit tests failures of `test_multimap` suit:
- fixed `equal_range`-related tests to properly verify result range (via new `Check_Equal` overload helper).
- fixed `find`-related tests to not depend on particular order of `second` values (via new `Check_ContainsPair` helper). See note 1,2) at [cppreference](https://cppreference.com/cpp/container/multimap/find) about order.
* PR review fixes.
---------
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com>
mutex_freertos.h unconditionally included the vanilla FreeRTOS header
layout (FreeRTOS.h and semphr.h at the include root). On ESP-IDF, and
therefore Arduino-ESP32 as well since it's built on top of ESP-IDF,
these headers are nested one level deeper under freertos/, so the
unconditional include fails to compile on any ESP32 target with
ETL_TARGET_OS_FREERTOS defined.
Use __has_include to try the standard path first, fall back to the
ESP-IDF nested path, and fail with a clear #error if neither is found,
rather than a mysterious "file not found" from the compiler.
Also resolves a pre-existing include-style inconsistency in this file:
the old code mixed "FreeRTOS.h" (quotes) with <semphr.h> (angle
brackets). All includes now uniformly use angle brackets.
* Topic/optional monadic operations
* topic/optional-monadic-operations:
- added and_then, or_else, and transform to etl::optional with unit tests
- added is_optional to optional.h, used in and_then and or_else to ensure that the returned type is an optional
- implemented as ref-qualified overloads with C++11 compatible trailing return types, following the etl::expected implementation
* Convert to C++11 style type traits
* Coderabbit changes
Constrain transform before forming etl::optional<U>.
Remove references from monadic result types.
* clang-format updates
---------
Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com>
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
* Adopt the Library Fundamentals TS make_array design for the sequence factories
make_array, make_deque, make_vector, make_list, make_forward_list and
make_indirect_vector now follow the Library Fundamentals TS
std::experimental::make_array design: a defaulted leading template
parameter selects the element type explicitly, falling back to the
decayed common type of the arguments when it is not supplied. A shared
trait (etl::private_make::element_type) performs the selection lazily,
so common_type is not instantiated when the element type is explicit.
This fixes the explicit-element-type calling style for the four
common-type factories, where make_vector<char>(lvalue) never compiled:
the explicit argument pinned the first pack parameter to char, making
it a char&& that no lvalue can bind to. It also gives make_array and
make_deque the deduced form (e.g. make_array(1, 2L) is array<long, 2>)
for free. All arguments are converted with static_cast, as in the
make_array const-lvalue fix, so const-qualified lvalues and narrowing
initialisers work in both forms.
Intentional behaviour change: an explicit element type now converts
every argument instead of pinning only the first. make_vector<char>(0,
1, ...) previously produced vector<int> - the explicit char affected
only the first argument and the element type was still the common type
- and now produces vector<char>. test_make_vector documented the old
behaviour and has been updated.
The keyed set and map factories are unchanged: their key/mapped types
are separate mandatory template parameters ahead of a fully-deduced
pack, so the explicit-type style already works, and retrofitting
deduction there would interact with the defaulted comparator/hash
parameters.
Adds explicit-element-type tests for the four common-type factories
(const/non-const lvalues plus narrowing initialisers) and
deduced-element-type tests for make_array and make_deque, and updates
the four documented signatures.
* Address review comments on the make_xxx factory design
- Forward same-type arguments in the make_xxx factories instead of
casting them. static_cast produced a prvalue that, before C++17, had
to be materialised through the move constructor, rejecting
copyable-but-non-movable element types. The new
private_make::convert helper forwards arguments that already have
the element type and static_casts the rest.
- Drop ETL_NOEXCEPT from make_array: conversions can throw, and the
other factories do not declare it.
- Remove the redundant etl::decay in element_type<void, ...>;
etl::common_type already decays its arguments.
- Stop leaking the etl::private_make implementation namespace into the
documented factory signatures.
* Add a test for make_array with an explicit element type and no arguments
etl::make_array<int>() produces an empty etl::array<int, 0> and now has
a regression test. A call with neither an element type nor arguments
remains ill-formed, matching the Library Fundamentals TS: there is
nothing to deduce the element type from. The array documentation now
states this explicitly.
---------
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
Co-authored-by: Roland Reichwein <Roland.Reichwein@bmw.de>
* Update _index.md
* Update _index.md
* Cherry pick the Docker fixes for PowerPC (#1563)
Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com>
* Update expected documentation to reflect the current state of the code
* Fix code blocks for expected class section
* Change wording slightly
* make changes ala coderabbitai
* Fixed typos
---------
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com>
* Make etl_profile Incompatible by Default
* Configure etl_profile for CI Execution of Tests
* Update _index.md
* Update _index.md
* Cherry pick the Docker fixes for PowerPC (#1563)
Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com>
---------
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
Co-authored-by: Roland Reichwein <Roland.Reichwein@bmw.de>
Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com>
In specific situations there might be the need to enforce that a method
is not inlined or always inlined (when using e.g. raw assembly).
Therefore, we provide two macros ETL_NO_INLINE and ETL_ALWAYS_INLINE.
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
When forcing to feed into value_types it has to be an
ETL_OR_STD::pair<const K, V>, but when you want to use CTAD on the pairs the
const is missing and the assert triggers.
ETL_ASSERT_OR_RETURN_VALUE tried to return ETL_NULLPTR from functions
returning references, which cannot be initialized from nullptr. Use
plain ETL_ASSERT instead, matching the other operator*() overloads.
Add regression test for dereferencing const and temporary expected.
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
* Fixed make_array rejecting const-qualified lvalues of the element type
make_array forwarded each argument as T (the element type) rather than
as its own deduced type. etl::forward<T> accepts only a non-const T& or
a T&&, and a T&& cannot bind to a reference-related const lvalue, so
any call passing a const-qualified lvalue of type T failed to compile:
static const char c = 42;
etl::make_array<char>(c, c); // error: would lose const qualifier
Arguments of *other* types slipped through via temporary
materialisation, which is why the existing conversion and move tests
never caught it.
Forward each argument as its own deduced type and convert explicitly
with static_cast<T>. The explicit conversion is required rather than
plain forwarding: function parameters are not constant expressions, so
narrowing initialisers such as make_array<char>(0, 1) - which the old
code accepted and the tests cover - would otherwise be rejected by the
braced initialiser list.
Adds regression tests for const/non-const lvalues of the element type
and for constexpr evaluation. Verified with clang 22 (C++14/17/20) and
GCC 14 (C++11/20); existing conversion and move-only patterns still
compile.
* Fixed make_deque rejecting const-qualified lvalues of the element type
make_deque had the same defect fixed for make_array in the previous
commit: it forwarded each argument as T (the element type) rather than
as its own deduced type. etl::forward<T> accepts only a non-const T& or
a T&&, and a T&& cannot bind to a reference-related const lvalue, so
any call passing a const-qualified lvalue of type T failed to compile:
static const char c = 42;
etl::make_deque<char>(c, c); // error: would lose const qualifier
An audit of all other make_xxx container factories found no further
instances - they forward each argument as its own deduced pack type,
which is the correct idiom.
Forward each argument as its own deduced type and convert explicitly
with static_cast<T>. The explicit conversion keeps narrowing
initialisers such as make_deque<char>(0, 1) - which the old code
accepted and test_make_deque covers - working, which plain forwarding
into the braced initialiser list would reject.
Adds a regression test for const/non-const lvalues of the element type.
No constexpr test, unlike make_array: etl::deque is not a literal type,
so make_deque cannot be evaluated at compile time. Verified with
clang 22 (C++14/17/20); the new test fails to compile before the fix
and passes after, and all 101 deque tests pass.
* Added narrowing-conversion regression tests for make_array and make_deque
Review feedback on the make_deque fix: the const-lvalue regression test
only passes arguments that already have the element type, so nothing
exercises the static_cast<T> conversion that keeps narrowing
initialisers working. If the implementation regressed to plain
forwarding into the braced initialiser list, narrowing calls such as
make_deque<char>(0, 1) would fail to compile.
make_array already covered narrowing from int literals via
test_make_array, but neither container covered conversion from
const-qualified lvalues of a different type (const int narrowed to
char), which combines both dimensions of the fix.
Adds a matching test to each container covering int literals plus
const/non-const int lvalues, all narrowed to char. Verified with
clang 22 (C++17): 102 deque and 53 array tests pass.
* Added const-lvalue regression tests for the remaining make_xxx factories
Review feedback on the make_array/make_deque fixes asked whether the
same defect - rejecting const-qualified lvalue arguments by forwarding
each argument as the element type rather than as its own deduced type -
exists in the other make_xxx container factories. The audit found that
it does not: the other factories forward each argument as its own
deduced pack type. These tests pin that down explicitly for every
remaining factory, mirroring the make_array and make_deque regression
tests:
- make_vector, make_forward_list, make_indirect_vector (element type
deduced via common_type): const/non-const char lvalues, element type
checked.
- make_set, make_multiset, make_flat_set, make_flat_multiset,
make_unordered_set, make_unordered_multiset: const/non-const lvalues
of the key type.
- make_map, make_multimap, make_flat_map, make_flat_multimap,
make_unordered_map, make_unordered_multimap: const/non-const lvalues
of the pair type.
make_reference_flat_* are excluded: they cannot currently be
instantiated at all (no initializer_list constructor exists in the
reference containers), which is reported separately.
Verified with clang 22 (C++17): all 15 test suites pass (996 tests).
* Added make_forward_list parity tests matching the make_list fixes
Checked whether the make_list defect - taking its argument pack by
value, costing an extra move per lvalue argument - also applies to
make_forward_list. It does not: make_forward_list already takes its
pack by forwarding reference, as make_vector does. No header change is
needed.
Adds the two tests that accompanied the make_list fix so that
forward_list has the same coverage and the same regression detector:
- test_make_forward_list_common_type_from_mixed_types, confirming the
element type deduction through common_type.
- test_make_forward_list_argument_copy_and_move_counts, an
instrumented type counting copy/move constructions. This is the test
that fails if the pack ever regresses to by-value (one extra move
per lvalue argument). The exact move counts are C++17-only, as
before C++17 the non-guaranteed return elision may add a move per
element.
Verified with clang 22 (C++17): all 67 forward_list tests pass.
---------
Co-authored-by: Roland Reichwein <Roland.Reichwein@bmw.de>
Add unsigned char/const unsigned char span overloads to byte_stream_reader
to match byte_stream_writer, resolving overload ambiguity (#1533). Add
tests covering span construction for both classes.
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
ireference_flat_map::lower_bound/upper_bound/equal_range searched over
its own bidirectional iterator/const_iterator, forcing etl::distance/
advance into an O(n) fallback even though the underlying lookup_t
(etl::ivector<value_type*>) is random access. Add pointer overloads to
the Compare functor and search directly over lookup.begin()/end(),
wrapping the result back into iterator/const_iterator.
Fixes#1518
Do the same for:
* reference_flat_multimap.h
* reference_flat_multiset.h
* reference_flat_set.h
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
* Add span deduction guide for types with data() and size().
This enables span construct with type deduction from containers which support
.data() and .size(), primarily vector.
---------
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
* Add explicit static_cast in binary.h
This silences implicit conversion warnings on
the 16- and 32-bit binary_interleave return values.
* Fix copy constructor and copy assignment in alignment.h
---------
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
The two-type etl::common_type specialization recursed with
decay<T2> twice when either argument was not already decayed,
so etl::common_type_t<long&, int&> yielded int instead of long.
Recurse with decay<T1> and decay<T2>, matching the cppreference
sample implementation, and add regression tests comparing
against std::common_type for reference-type arguments.
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
* Corrected the documented make_xxx factory signatures and examples
The Make template sections across the container documentation had
drifted from the implementations, largely through copy-paste:
- map.md, multimap.md and flat-multimap.md all documented
make_flat_map; multiset.md documented make_set; flat-multiset.md
documented make_flat_set; unordered-multimap.md documented
make_unordered_map. Names and examples now match each container.
- Every signature omitted the C++11-required trailing return type
despite the sections being labelled C++11 and above; several also
used a parameter name (TValues) that did not match any template
parameter, and the unordered map headers were missing a comma.
- forward-list.md documented a make_array-style signature with an
explicit element type; the real function deduces the element type as
the common type of the arguments, as documented for make_list.
- The flat_set/flat_multiset template headers were missing the
variadic parameter pack, and their examples passed a braced list to
a variadic function, which does not compile; set.md used TKeyCompare
where the implementation uses TCompare.
- deque.md and the reference container docs were missing code fences.
- Updated the four reference_flat_* function. However these functions
cannot be instantiated at all (the reference containers have no
initializer_list constructor, since one would dangle by design), so
the documented examples have never compiled.
Every remaining documented example verified to compile with clang 22
(C++17) against the current headers.
* Fixed C++17-only syntax in factory examples and flagged the non-compilable ones
Review feedback on the make_xxx documentation examples:
- All the map-family factory examples are labelled C++11 and above but
constructed their pairs with class template argument deduction
(etl::pair{0, 1}), which requires C++17. The pairs in the make_flat_map,
make_flat_multimap, make_map, make_multimap, make_unordered_map,
make_unordered_multimap, make_reference_flat_map and
make_reference_flat_multimap examples now name their template arguments
explicitly. The template deduction guide examples are unchanged, as
those sections are labelled C++17 and above. Verified with clang 22 in
C++14 mode, which, like C++11, has no deduction guides.
- The four make_reference_flat_* examples are now preceded by a warning
callout stating that they do not currently compile: the functions
cannot be instantiated because the reference containers have no
initializer_list constructor. The examples themselves are retained,
rewritten to pass named lvalues rather than temporaries, since the
reference containers store references to external objects and the
temporaries would dangle even if the functions compiled. The defect
is being reported separately.
---------
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
make_list was the only make_xxx container factory taking its argument
pack by value rather than by forwarding reference, costing an extra
move per lvalue argument: each lvalue was copy-constructed into the
parameter and then moved into the initializer_list backing array,
where the forwarding-reference signature copies it there directly.
Rvalue prvalue arguments count the same either way in practice, as
copy elision constructs them directly into the by-value parameter.
Change the pack to T&&..., matching make_vector, make_forward_list and
make_indirect_vector. The deduced reference types decay through
common_type, so the element type deduction is unchanged.
Adds tests for const/non-const lvalues of the element type (guarding
against the forward<T> defect fixed for make_array and make_deque),
mixed-type common_type deduction, and an instrumented type counting
copy/move constructions, which fails with the by-value signature (one
extra move per lvalue argument) and passes with the fix.
Also corrects the make_list documentation, which described a
make_array-style signature with an explicit element type parameter
that never matched the implementation.
Verified with clang 22 (C++17): all 93 list tests pass; C++14/20
syntax checks pass.
Note: mixed-type lvalue arguments are affected by a separate
pre-existing defect in etl::common_type (its two-type specialization
recurses with decay<T2> twice instead of decay<T1>, decay<T2>), which
already affects the other common_type-based factories and is being
fixed separately.
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
* Fix missing operator[] for iota_iterator and repeat_iterator
The iterators of etl::ranges::iota_view and etl::ranges::repeat_view are
random access iterators but they did not define any operator[]. This did
not cause any issues when using mutable views since the implementation
of operator[] provided by view_interface for random access views was
hidden by another implementation using etl::advance. However, this was
not the case for 'operator[] const', which resulted in a build error
when using constant views.
This commit ensures that the operator[] implementation for random access
views is no longer hidden by another implementation in view_interface,
and adds operator[] to both iterators.
* Fix sign conversion error on operator[] for some views
The operator[] definitions provided by view_interface were accepting
size_t arguments. This was causing a compile-time warning
(Wsign-conversion) for the random access views using an iterator with a
signed difference type. This has been observed on etl::ranges::iota_view
and etl::ranges::repeat_view.
No test is added since the tests provided by the previous commit already
produce the warning, causing a build error.
---------
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
PR #1422 deleted the only file in .devcontainer/context/
(reinstall-cmake.sh) as unused, which silently removed the directory
itself since git doesn't track empty ones. Every devcontainer.json
under .devcontainer/ (root and all compiler variants) references this
path as its Docker build context, so opening the project in a dev
container now fails immediately with:
ERROR: failed to build: unable to prepare context: path
".../.devcontainer/context" not found
Add a .gitkeep placeholder to keep the directory present in git so
the build context resolves again.
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>