Embedded Template Library (ETL)

repository·master·Indexed 25 days ago

https://github.com/etlcpp/etl

A C++ template library for resource-constrained embedded systems that provides STL-like containers and utilities without dynamic memory allocation. It ensures deterministic behavior through fixed-capacity containers, is compatible with C++03 and later, and includes specialized features for binary manipulation, CRC calculations, and embedded frameworks like finite state machines and task scheduling.

Tokens
208.2K
Snippets
385
Records
1.3K
Agent score
74%

What's inside ETL

  1. Overview of the Embedded Template Library (ETL)

    master

    The Embedded Template Library (ETL) is a C++ template library designed specifically for embedded systems. It serves as a complementary solution to the C++ Standard Template Library (STL), focusing on deterministic behavior and resource constraints.

    Key Characteristics:

    • No Dynamic Memory Allocation: The library avoids the heap entirely. All storage is allocated at compile-time or on the stack, ensuring memory requirements are predictable.
    • Fixed-Capacity Containers: Provides STL-like containers where maximum sizes are defined at compile-time.
    • Header-Only: No separate compilation is required; all functionality is provided via header files.
    • No STL Dependency: Designed to operate independently of the C++ Standard Template Library.
    • C++ Compatibility: Compatible with any compiler supporting C++03 or later. It backports many C++11/14/17/20/23 features for use in older C++03 environments.
    • Low Overhead: Does not require Runtime Type Information (RTTI) and uses virtual functions sparingly.
  2. Use etl::set for fixed-capacity sets

    master

    etl::set is a fixed-capacity container similar to std::set. It uses etl::less or a user-provided comparison method as the default key comparison. It inherits from etl::iset, which can be used as a size-independent pointer or reference type.

    Header: set.h

    etl::set<typename T, const size_t SIZE, TKeyCompare = etl::less>
  3. Use etl::tuple

    master

    etl::tuple is a fixed-size collection of heterogeneous values, similar to std::tuple. It is available via the tuple.h header (since version 20.41.0).

    In C++17 and above, you can use template deduction guides to initialize a tuple without explicitly specifying types, or use etl::make_tuple to create one.

  4. Use etl::flat_set

    master

    A etl::flat_set is a fixed-capacity associative container based on a sorted vector. It provides O(log N) search complexity but O(N) insertion and erasure complexity. It is ideal for tables that are searched frequently but updated only occasionally. It uses etl::less as the default comparison method.

    Header: flat_set.h

    Template Signature:

    etl::flat_set<typename T, size_t SIZE, TKeyCompare = etl::less>

    Note: etl::flat_set inherits from etl::iflat_set<T, TKeyCompare>, which can be used as a size-independent pointer or reference type.

  5. Use etl::flat_map for associative lookups

    master

    A etl::flat_map is a fixed-capacity associative container based on a sorted vector. It is optimized for scenarios where the table is searched frequently but updated occasionally.

    Performance Characteristics:

    • Search: O(log N)
    • Insertion/Erasure: O(N)

    Key Details:

    • Header: flat_map.h
    • Default comparison: etl::less
    • It inherits from etl::iflat_map, which can be used as a size-independent pointer or reference type.
    • If the map is full during insertion, it emits etl::flat_map_full. If a key is not found during at() access, it emits etl::flat_map_out_of_range (if exceptions/asserts are enabled).
    etl::flat_map<typename TKey, typename TMapped, size_t SIZE, TKeyCompare = etl::less>
  6. Use etl::intrusive_forward_list

    master

    etl::intrusive_forward_list is an intrusive singly-linked list, similar to std::forward_list. It requires a value type TValue that is derived from a link type TLink. This allows the list to manage elements without allocating additional memory for nodes, as the link metadata is stored within the objects themselves.

    Header: intrusive_forward_list.h

  7. Use delegate_service to bridge C-style events and C++ handlers

    master

    The delegate_service template class facilitates the integration of 'C' style events (like interrupt vectors) with C++ handlers. It provides an abstraction layer between low-level events and application-specific handlers. Handlers can be global functions, static member functions, lambdas, or functors.

    Delegates are identified by an id. The valid range of IDs is defined by Range and Offset template parameters. If an unused ID is called, the service will either do nothing or call a registered unhandled delegate.

    Header: delegate_service.h

  8. Use the bresenham_line pseudo-container

    master

    The etl::bresenham_line<T> is a pseudo-container that generates coordinates on a line between two points using the Bresenham line algorithm. It provides an STL-like API and acts as a forward iterator type container.

    Note: The iterator only supports pre-increment.

    Include the header bresenham_line.h to use this feature. The template parameter T represents the coordinate element type.

    etl::bresenham_line<typename T>
  9. Use etl::poly_span for polymorphic views

    master

    The etl::poly_span class provides a view into a contiguous range of elements through a base type. This allows you to treat a collection of derived objects as a span of their common base class.

    Header: poly_span.h (Available from version 20.31.0)

    Template Signature:

    etl::poly_span<typename TBase, size_t Extent = etl::dynamic_extent>
    • TBase: The base type used to view the elements.
    • Extent: The number of elements in the span. Defaults to etl::dynamic_extent for dynamic sizes.
    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<Derived, 4> data{ Derived(1), Derived(2), Derived(3), Derived(4) };
    
    // Create a polymorphic span of Base objects from an array of Derived objects
    etl::poly_span<Base> ps{ data };
    
    for (const Base& b : ps)
    {
      b.Print();
    }
  10. Use etl::multimap

    master

    A etl::multimap is a fixed-capacity container that allows multiple elements to have the same key. It is similar to std::multimap but uses a fixed size defined at compile time. It inherits from etl::imap, meaning an etl::imap can be used as a size-independent pointer or reference type for any etl::multimap instance.

    Header: multimap.h
    Default Comparator: etl::less

    Template Signature:

    etl::multimap<typename TKey, typename TMapped, const size_t SIZE, TKeyCompare = etl::less>
  11. Use callback_timer for software timers

    master

    The etl::callback_timer is a software timer class capable of managing up to 254 timers. Each timer can be configured as either a single-shot or a repeating timer. Timers are driven by calling tick(uint32_t count), which should typically be performed in a high-priority interrupt routine. The callback function is executed in the same context as the tick call.

    Note: This class is superseded. For new projects, consider using etl::callback_timer_atomic or etl::callback_timer_locked.