A C++ template library for embedded applications
MIT licensed
Designed and
maintained by
John Wellbelove

Get Involved



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 me know. If you just want to add an enhancement to an existing class, tell me 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 we can have a dialog about what I think should change. Feel free to argue your case.

I am the dictator of what goes in to the ETL (but I see myself as a very benevolent dictator).  

 

There are a number of jobs outstanding at the time of writing that could usefully be taken up whole, or in part, by someone else.

 

GitHub

If you wish to create a pull request to the ETL repository on GitHub then create your changes in a feature or hotfix branch that is based on master. When you think you have completed your modifications then raise a pull request.
If the change is in relation to an issue, prefix the issue number to the branch name.

#123-fix-foobar-algorithm

Project Style
I don't want to be any sort of style Nazi, but there are a few design rules that I ask you to try to adhere to.

 

  • The style of the public API of the class should mirror that of the STL.

  • Lower case class and function names, separated by an underscore.

    funky_container
    do_something

  • Use the same naming convention as the STL.

  • If appropriate for the class, a set of typedefs 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.

  • 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

  • Add C++03 and C++11 'emplace' functions to the rest of the ETL containers.

  • Add C++11 variadic 'emplace' functions to all containers, selected by a pre-processor switch for
    ETL_USING_CPP11

  • Add a 'fast clear' option for all containers of types with trivial destructors.

  • All ETL classes are to be within the etl namespace.

  • All classes private to the ETL shoud reside in a nested namespace prefixed with private_

    namespace etl
    {
      namespace private_funky_container
      {
        struct helper
        {
          //…
        };
      }

      class funky_container
      {
        private_funky_container::helper helper;
      };
    }

  • Use descriptive names for internal variables and functions.

  • Use comments to summarise or explain blocks of code that may be difficult to quickly understand.

  • If your code relies on features from C++11 or above then wrap the code in conditional compilation macros.

    #if ETL_USING_CPP11
    ...
    #endif

  • 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
    #if ETL_USING_8BIT_TYPES
    #endif

  • If int64_t or uint64_t must be used then surround the code with
    #if ETL_USING_64BIT_TYPES
    #endif

  • 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.

  • In a similar vein to 7, Never assume the minimum or maximum values for a type. Use type traits to look them up.

  • Where ever possible, add STATIC_ASSERT to catch errors at compile time, rather than runtime.

  • 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));

  • 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.

    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 not such thing as too many tests. There are such things as useless tests.

 

Try to test your code on as many compilers as practicable.
The CI scripts on Github test the ETL using Visual Studio (Windows), GCC & CLang (Linux)