ETLCPP / etl

Embedded Template Library
https://www.etlcpp.com
MIT License
2.05k stars 373 forks source link

etl::span with own class #750

Closed MickroC closed 10 months ago

MickroC commented 10 months ago

I've just tried to update from 20.18.1 to 20.38.0.

Giving the following example code:

#include "span.h"
struct Data {
    size_t size() const {return 0;}
    int* data() const {return nullptr;}
};
Data data;
etl::span<int> test(data);

With 20.18.1, this code is valid.

With 20.38.0, etl::span uses type traits and rejects Data instances (no valid contructor found).

I understand the intention of using type traits, so I am not sure about calling this a bug, but in my case it limits the usage of etl::span. Is it possible to provide a less restrictive etl::span constructor or how do I have to change Data to be accepted?

jwellbelove commented 10 months ago

The way that etl::span worked before was not compliant with the API of std::span and caused issues where the incorrect constructor would be selected in certain circumstances. Additional checks to enable the correct constructor were added, which is why your code doesn't compile now.

To use the 'construct from container' constructor you must ensure that your struct/class contains a definition of value_type.

struct Data {
    using value_type = int;
    size_t size() const {return 0;}
    int* data() const {return nullptr;}
};
Data data;
etl::span<int> test(data);
jwellbelove commented 10 months ago

When using your own containers with the STL or ETL it is often useful to define the standard set of types.

struct Data {
    using value_type      = int;
    using pointer         = value_type*;
    using const_pointer   = const value_type*;
    using reference       = value_type&;
    using const_reference = const value_type&;
    using iterator        = value_type*;
    using const_iterator  = const value_type*;
    using size_type       = size_t;

    size_type size() const {return 0;}
    pointer data() {return nullptr;}
    const_pointer data() const {return nullptr;}
};