Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Type Safe C++? - LOL! :-)

Type Safe C++? - LOL! :-)

So called "strong types", genuinely type safe alternatives to "typedef:s" are often seen as a way to prevent bugs, but they can also be used to improve clarity in your code, and even increase performance. It is underappreciated how strong the type safety guarantees in C++ are, because it takes knowledge and a bit of discipline to make use of it.

In this session, I give motivating examples for why strong types are good, and present some of the techniques for creating them. The simplest techniques requires no library support, but I will also show some more sophisticated solutions from open source libraries available on github. We will go through what happens with both production code and test code when you use them, and also discuss the pros and cons of the different approaches.

Björn Fahller

April 14, 2018
Tweet

More Decks by Björn Fahller

Other Decks in Programming

Transcript

  1. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 1/144
    Type Safe C++? - LOL! :-)
    Björn Fahller

    View Slide

  2. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 2/144
    Type Safe C++? - LOL! :-)
    Björn Fahller

    View Slide

  3. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 3/144
    Type Safe C++? - LOL! :-)
    What is type safety?

    View Slide

  4. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 4/144
    What is type safety?
    type safety (Noun)
    the extent to which a programming language
    discourages or prevents type errors
    -- Wiktionary

    View Slide

  5. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 5/144
    A type safe system discourages or prevents...

    ... use of one type when another is intended

    ... operations that do not make sense

    ... use of values outside the defined space

    View Slide

  6. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 6/144

    Introduction to type safety

    Type safety in C++

    Simple library solution for strong types

    Sophisticated libraries – scouting github!

    What strong types does with your code
    Type Safe C++? - LOL! :-)

    View Slide

  7. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 7/144
    using request_id = uint32_t;
    using receiver_id = uint32_t;
    token remove(request_id req, receiver_id rec);
    token initiate_remove(receiver_id receiver)
    {
    auto req = new_request();
    return remove(receiver, req);
    }
    My story begins

    View Slide

  8. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 8/144
    using request_id = uint32_t;
    using receiver_id = uint32_t;
    token remove(request_id req, receiver_id rec);
    token initiate_remove(receiver_id receiver)
    {
    auto req = new_request();
    return remove(receiver, req);
    }
    My story begins

    View Slide

  9. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 9/144
    using request_id = uint32_t;
    using receiver_id = uint32_t;
    token remove(request_id req, receiver_id rec);
    token initiate_remove(receiver_id receiver)
    {
    auto req = new_request();
    return remove(receiver, req);
    }
    My story begins

    View Slide

  10. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 10/144
    void other(A const& a);
    void func(B b)
    {
    other(b);
    }
    When is
    this call
    allowed?

    View Slide

  11. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 11/144
    using A = double;
    using B = enum { aa, bb, cc };
    void other(A const& a);
    void func(B b)
    {
    other(b);
    }

    View Slide

  12. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 12/144
    struct A {
    int value;
    };
    struct B {
    int value;
    };
    void other(A const& a);
    void func(B b)
    {
    other(b);
    }

    View Slide

  13. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 13/144
    struct A {
    int value;
    };
    struct B {
    int value;
    };
    void other(A const& a);
    void func(B b)
    {
    other(b);
    }
    If we want this to compile, we can add:

    View Slide

  14. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 14/144
    struct A {
    int value;
    };
    struct B {
    int value;
    };
    void other(A const& a);
    void func(B b)
    {
    other(b);
    }
    If we want this to compile, we can add:
    A::A(B const&); // not explicit

    View Slide

  15. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 15/144
    struct A {
    int value;
    };
    struct B {
    int value;
    };
    void other(A const& a);
    void func(B b)
    {
    other(b);
    }
    If we want this to compile, we can add:
    A::A(B const&); // not explicit
    B::operator A(); // not explicit

    View Slide

  16. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 16/144
    struct A {
    int value;
    };
    struct B {
    int value;
    };
    void other(A const& a);
    void func(B b)
    {
    other(b);
    }
    If we want this to compile, we can add:
    A::A(B const&); // not explicit
    B::operator A(); // not explicit
    A as a public base class to B

    View Slide

  17. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 17/144
    struct request_id { uint32_t value; };
    struct receiver_id { uint32_t value; };
    token remove(request_id req, receiver_id rec);
    token initiate_remove(receiver_id receiver)
    {
    request_id req = new_request();
    return remove(receiver, req);
    }
    A different story begins

    View Slide

  18. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 18/144
    struct request_id { uint32_t value; };
    struct receiver_id { uint32_t value; };
    token remove(request_id req, receiver_id rec);
    token initiate_remove(receiver_id receiver)
    {
    request_id req = new_request();
    return remove(receiver, req);
    }
    error: no matching function for call to 'remove'
    return remove(receiver, req);
    ^~~~~~
    note: candidate function not viable:
    no known conversion from 'receiver_id' to 'request_id' for 1st argument
    token remove(request_id req, receiver_id rec);
    ^

    View Slide

  19. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 19/144
    We have control over
    when the compiler
    will allow a conversion!

    View Slide

  20. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 20/144
    class receiver_id
    {
    public:
    explicit receiver_id(uint32_t v) : value{v} {}
    operator uint32_t() const { return value; }
    private:
    uint32_t value;
    };

    View Slide

  21. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 21/144
    class receiver_id
    {
    public:
    explicit receiver_id(uint32_t v) : value{v} {}
    operator uint32_t() const { return value; }
    bool operator==(receiver_id v) const {
    return value == v.value;
    }
    bool operator!=(receiver_id v) const;
    private:
    uint32_t value;
    };

    View Slide

  22. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 22/144
    class receiver_id
    {
    public:
    explicit receiver_id(uint32_t v) : value{v} {}
    operator uint32_t() const { return value; }
    bool operator==(receiver_id v) const {
    return value == v.value;
    }
    bool operator!=(receiver_id v) const;
    bool operator...
    private:
    uint32_t value;
    };

    View Slide

  23. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 23/144
    class receiver_id
    {
    public:
    explicit receiver_id(uint32_t v) : value{v} {}
    operator uint32_t() const { return value; }
    bool operator==(receiver_id v) const {
    return value == v.value;
    }
    bool operator!=(receiver_id v) const;
    bool operator...
    private:
    uint32_t value;
    };
    enum class receiver_id : uint32_t {};

    View Slide

  24. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 24/144
    class receiver_id
    {
    public:
    explicit receiver_id(uint32_t v) : value{v} {}
    operator uint32_t() const { return value; }
    bool operator==(receiver_id v) const {
    return value == v.value;
    }
    bool operator!=(receiver_id v) const;
    bool operator...
    private:
    uint32_t value;
    };
    enum class receiver_id : uint32_t {};

    View Slide

  25. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 25/144
    class receiver_id
    {
    public:
    explicit receiver_id(uint32_t v) : value{v} {}
    operator uint32_t() const { return value; }
    bool operator==(receiver_id v) const {
    return value == v.value;
    }
    bool operator!=(receiver_id v) const;
    bool operator...
    private:
    uint32_t value;
    };
    enum class receiver_id : uint32_t {};

    View Slide

  26. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 26/144
    class receiver_id
    {
    public:
    explicit receiver_id(uint32_t v) : value{v} {}
    operator uint32_t() const { return value; }
    bool operator==(receiver_id v) const {
    return value == v.value;
    }
    bool operator!=(receiver_id v) const;
    bool operator...
    private:
    uint32_t value;
    };
    enum class receiver_id : uint32_t {};

    View Slide

  27. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 27/144
    class receiver_id
    {
    public:
    explicit receiver_id(uint32_t v) : value{v} {}
    operator uint32_t() const { return value; }
    bool operator==(receiver_id v) const {
    return value == v.value;
    }
    bool operator!=(receiver_id v) const;
    bool operator...
    private:
    uint32_t value;
    };
    enum class receiver_id : uint32_t {};

    View Slide

  28. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 28/144
    class receiver_id
    {
    public:
    explicit receiver_id(uint32_t v) : value{v} {}
    operator uint32_t() const { return value; }
    bool operator==(receiver_id v) const {
    return value == v.value;
    }
    bool operator!=(receiver_id v) const;
    bool operator...
    private:
    uint32_t value;
    };
    enum class receiver_id : uint32_t {};

    View Slide

  29. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 29/144
    class receiver_id
    {
    public:
    explicit receiver_id(uint32_t v) : value{v} {}
    operator uint32_t() const { return value; }
    bool operator==(receiver_id v) const {
    return value == v.value;
    }
    bool operator!=(receiver_id v) const;
    bool operator...
    private:
    uint32_t value;
    };

    View Slide

  30. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 30/144
    class receiver_id
    {
    public:
    explicit receiver_id(uint32_t v) : value{v} {}
    operator uint32_t() const { return value; }
    bool operator==(receiver_id v) const {
    return value == v.value;
    }
    bool operator!=(receiver_id v) const;
    bool operator...
    private:
    uint32_t value;
    };
    There’s an awful
    lot of boiler plate
    code here!

    View Slide

  31. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 31/144
    class receiver_id
    {
    public:
    explicit receiver_id(uint32_t v) : value{v} {}
    operator uint32_t() const { return value; }
    bool operator==(receiver_id v) const {
    return value == v.value;
    }
    bool operator!=(receiver_id v) const;
    bool operator...
    private:
    uint32_t value;
    };
    There’s an awful
    lot of boiler plate
    code here!
    Repeat once more
    for request_id

    View Slide

  32. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 32/144

    Introduction to type safety

    Type safety in C++

    Simple library solution for strong types

    Sophisticated libraries – scouting github!

    What strong types does with your code
    Type Safe C++? - LOL! :-)

    View Slide

  33. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 33/144
    template
    class safe_type
    {
    public:
    private:
    T value_;
    };

    View Slide

  34. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 34/144
    template
    class safe_type
    {
    public:
    safe_type(T t) : value_(std::move(t)) {}
    operator T() const { return value_; }
    // operators...
    private:
    T value_;
    };

    View Slide

  35. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 35/144
    template
    class safe_type
    {
    public:
    safe_type(T t) : value_(std::move(t)) {}
    template
    safe_type(safe_type const&) = delete;
    operator T() const { return value_; }
    // operators...
    private:
    T value_;
    };

    View Slide

  36. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 36/144
    template
    class safe_type
    {
    public:
    safe_type(T t) : value_(std::move(t)) {}
    template
    safe_type(safe_type const&) = delete;
    operator T() const { return value_; }
    // operators...
    private:
    T value_;
    };
    using int1 = safe_type;
    using int2 = safe_type;

    View Slide

  37. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 37/144
    using request_id = safe_type;
    using receiver_id = safe_type;
    token remove(request_id req, receiver_id rec);
    token initiate_remove(receiver_id receiver)
    {
    auto req = new_request();
    return remove(receiver, req);
    }

    View Slide

  38. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 38/144
    using request_id = safe_type;
    using receiver_id = safe_type;
    token remove(request_id req, receiver_id rec);
    token initiate_remove(receiver_id receiver)
    {
    auto req = new_request();
    return remove(receiver, req);
    }

    View Slide

  39. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 39/144
    using request_id = safe_type;
    using receiver_id = safe_type;
    token remove(request_id req, receiver_id rec);
    token initiate_remove(receiver_id receiver)
    {
    auto req = new_request();
    return remove(receiver, req);
    }

    View Slide

  40. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 40/144
    using request_id = safe_type;
    using receiver_id = safe_type;
    token remove(request_id req, receiver_id rec);
    token initiate_remove(receiver_id receiver)
    {
    auto req = new_request();
    return remove(receiver, req);
    }
    error: no matching function for call to 'remove'
    remove(receiver, req);
    ^~~~~~
    note: candidate function not viable: no known conversion
    from 'safe_type'
    to 'safe_type' for 1st argument
    token remove(request_id req, receiver_id rec);
    ^

    View Slide

  41. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 41/144
    using request_id = safe_type;
    using receiver_id = safe_type;
    token remove(request_id req, receiver_id rec);
    token initiate_remove(receiver_id receiver)
    {
    auto req = new_request();
    return remove(receiver, req);
    }

    View Slide

  42. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 42/144
    struct request_id : safe_type {
    using safe_type::safe_type;
    };
    struct receiver_id : safe_type {
    using safe_type::safe_type;
    };
    token remove(request_id req, receiver_id rec);
    token initiate_remove(receiver_id receiver)
    {
    auto req = new_request();
    return remove(receiver, req);
    }

    View Slide

  43. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 43/144
    struct request_id : safe_type {
    using safe_type::safe_type;
    };
    struct receiver_id : safe_type {
    using safe_type::safe_type;
    };
    token remove(request_id req, receiver_id rec);
    token initiate_remove(receiver_id receiver)
    {
    auto req = new_request();
    return remove(receiver, req);
    }
    error: no matching function for call to 'remove'
    remove(receiver, req);
    ^~~~~~
    note: candidate function not viable: no known conversion
    from 'receiver_id' to 'request_id' for 1st argument
    token remove(request_id req, receiver_id rec);
    ^

    View Slide

  44. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 44/144
    struct request_id : safe_type {
    using safe_type::safe_type;
    };
    struct receiver_id : safe_type {
    using safe_type::safe_type;
    };
    token remove(request_id req, receiver_id rec);
    token initiate_remove(receiver_id receiver)
    {
    auto req = new_request();
    return remove(receiver, req);
    }
    #define SAFE_TYPE(name, base_type) \
    struct name : safe_type { \
    using safe_type::safe_type; \
    }

    View Slide

  45. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 45/144
    SAFE_TYPE(request_id, uint32_t);
    SAFE_TYPE(receiver_id, uint32_t);
    token remove(request_id req, receiver_id rec);
    token initiate_remove(receiver_id receiver)
    {
    auto req = new_request();
    return remove(receiver, req);
    }
    #define SAFE_TYPE(name, base_type) \
    struct name : safe_type { \
    using safe_type::safe_type; \
    }

    View Slide

  46. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 46/144
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(interface_name const& ifname,
    customer_name const& customer);
    interface_name lookup_interface(MAC_address mac);
    void setup_customer(MAC_address mac,
    customer_name const& customer)
    {
    assert(!customer.empty());
    auto if_name = lookup_interface(mac);
    assert(if_name.find(':') != std::string::npos);
    label_interface(customer, if_name);
    }

    View Slide

  47. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 47/144
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(interface_name const& ifname,
    customer_name const& customer);
    interface_name lookup_interface(MAC_address mac);
    void setup_customer(MAC_address mac,
    customer_name const& customer)
    {
    assert(!customer.empty());
    auto if_name = lookup_interface(mac);
    assert(if_name.find(':') != std::string::npos);
    label_interface(customer, if_name);
    }

    View Slide

  48. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 48/144
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(interface_name const& ifname,
    customer_name const& customer);
    interface_name lookup_interface(MAC_address mac);
    void setup_customer(MAC_address mac,
    customer_name const& customer)
    {
    assert(!customer.empty());
    auto if_name = lookup_interface(mac);
    assert(if_name.find(':') != std::string::npos);
    label_interface(customer, if_name);
    }
    Accidental swap!

    View Slide

  49. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 49/144
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(interface_name const& ifname,
    customer_name const& customer);
    interface_name lookup_interface(MAC_address mac);
    void setup_customer(MAC_address mac,
    const customer_name& customer)
    {
    assert(!customer.empty());
    auto if_name = lookup_interface(mac);
    assert(if_name.find(':') != std::string::npos);
    label_interface(customer, if_name);
    }
    Accidertal swap!
    template typename tag,
    bool = std::is_class{} && !std::is_final{}>
    class safe_type { /* as before */};

    View Slide

  50. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 50/144
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(interface_name const& ifname,
    customer_name const& customer);
    interface_name lookup_interface(MAC_address mac);
    void setup_customer(MAC_address mac,
    const customer_name& customer)
    {
    assert(!customer.empty());
    auto if_name = lookup_interface(mac);
    assert(if_name.find(':') != std::string::npos);
    label_interface(customer, if_name);
    }
    Accidertal swap!
    template typename tag,
    bool = std::is_class{} && !std::is_final{}>
    class safe_type { /* as before */};
    template
    struct safe_type : T
    {
    using T::T;
    template
    safe_type(safe_type const&) = delete;
    };

    View Slide

  51. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 51/144
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(interface_name const& ifname,
    customer_name const& customer);
    interface_name lookup_interface(MAC_address mac);
    void setup_customer(MAC_address mac,
    customer_name const& customer)
    {
    assert(!customer.empty());
    auto if_name = lookup_interface(mac);
    assert(if_name.find(':') != std::string::npos);
    label_interface(customer, if_name);
    }
    Accidental swap!
    error: no matching function for call to 'label_interface'
    label_interface(customer, if_name);
    ^~~~~~~~~~~~~~~
    note: candidate function not viable: no known conversion
    from 'customer_name'
    to 'const interface_name' for 1st argument
    void label_interface(const interface_name& ifname,
    ^

    View Slide

  52. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 52/144
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(interface_name const& ifname,
    customer_name const& customer);
    interface_name lookup_interface(MAC_address mac);
    void setup_customer(MAC_address mac,
    const customer_name& customer)
    {
    assert(!customer.empty());
    auto if_name = lookup_interface(mac);
    assert(if_name.find(':') != std::string::npos);
    label_interface(customer, if_name);
    }
    Accidertal swap!
    template typename tag,
    bool = std::is_class{} && !std::is_final{}>
    class safe_type { /* as before */};
    template
    struct safe_type : T
    {
    using T::T;
    template
    safe_type(safe_type const&) = delete;
    };

    View Slide

  53. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 53/144
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(interface_name const& ifname,
    customer_name const& customer);
    interface_name lookup_interface(MAC_address mac);
    void setup_customer(MAC_address mac,
    const customer_name& customer)
    {
    assert(!customer.empty());
    auto if_name = lookup_interface(mac);
    assert(if_name.find(':') != std::string::npos);
    label_interface(customer, if_name);
    }
    Accidertal swap!
    template typename tag,
    bool = std::is_class{} && !std::is_final{}>
    class safe_type { /* as before */};
    template
    struct safe_type : T
    {
    using T::T;
    template
    safe_type(safe_type const&) = delete;
    };

    View Slide

  54. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 54/144
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(interface_name const& ifname,
    customer_name const& customer);
    interface_name lookup_interface(MAC_address mac);
    void setup_customer(MAC_address mac,
    const customer_name& customer)
    {
    assert(!customer.empty());
    auto if_name = lookup_interface(mac);
    assert(if_name.find(':') != std::string::npos);
    label_interface(customer, if_name);
    }
    Accidertal swap!
    template typename tag,
    bool = std::is_class{} && !std::is_final{}>
    class safe_type { /* as before */};
    template
    struct safe_type : T
    {
    using T::T;
    template
    safe_type(safe_type const&) = delete;
    };
    Oh, no, I violated the
    Liskov Substitution Principle!

    View Slide

  55. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 55/144
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(interface_name const& ifname,
    customer_name const& customer);
    interface_name lookup_interface(MAC_address mac);
    void setup_customer(MAC_address mac,
    const customer_name& customer)
    {
    assert(!customer.empty());
    auto if_name = lookup_interface(mac);
    assert(if_name.find(':') != std::string::npos);
    label_interface(customer, if_name);
    }
    Accidertal swap!
    template typename tag,
    bool = std::is_class{} && !std::is_final{}>
    class safe_type { /* as before */};
    template
    struct safe_type : T
    {
    using T::T;
    template
    safe_type(safe_type const&) = delete;
    };
    Liskov Substitution Principle
    Subtype Requirement:
    Let φ(x) be a property provable about objects x of type T.
    Then φ(y) should be true for objects y of type S
    where S is a subtype of T.

    View Slide

  56. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 56/144
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(interface_name const& ifname,
    customer_name const& customer);
    interface_name lookup_interface(MAC_address mac);
    void setup_customer(MAC_address mac,
    const customer_name& customer)
    {
    assert(!customer.empty());
    auto if_name = lookup_interface(mac);
    assert(if_name.find(':') != std::string::npos);
    label_interface(customer, if_name);
    }
    Accidertal swap!
    template typename tag,
    bool = std::is_class{} && !std::is_final{}>
    class safe_type { /* as before */};
    template
    struct safe_type : T
    {
    using T::T;
    template
    safe_type(safe_type const&) = delete;
    };
    Liskov Substitution Principle
    Subtype Requirement:
    Let φ(x) be a property provable about objects x of type T.
    Then φ(y) should be true for objects y of type S
    where S is a subtype of T.
    Robert (Uncle Bob) Martin
    Functions that use pointers or references
    to base classes must be able to use objects
    of derived classes without knowing it.

    View Slide

  57. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 57/144
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(interface_name const& ifname,
    customer_name const& customer);
    interface_name lookup_interface(MAC_address mac);
    void setup_customer(MAC_address mac,
    customer_name const& customer)
    {
    assert(!customer.empty());
    auto if_name = lookup_interface(mac);
    assert(if_name.find(':') != std::string::npos);
    label_interface(customer, if_name);
    }
    Liskov Substitution Principle
    Subtype Requirement:
    Let φ(x) be a property provable about objects x of type T.
    Then φ(y) should be true for objects y of type S
    where S is a subtype of T.
    Robert (Uncle Bob) Martin
    Functions that use pointers or references
    to base classes must be able to use objects
    of derived classes without knowing it.
    customer_name and interface_name
    are different types implemented in terms
    of strings

    View Slide

  58. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 58/144
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(interface_name const& ifname,
    customer_name const& customer);
    interface_name lookup_interface(MAC_address mac);
    void setup_customer(MAC_address mac,
    customer_name const& customer)
    {
    assert(!customer.empty());
    auto if_name = lookup_interface(mac);
    assert(if_name.find(':') != std::string::npos);
    label_interface(customer, if_name);
    }
    Liskov Substitution Principle
    Subtype Requirement:
    Let φ(x) be a property provable about objects x of type T.
    Then φ(y) should be true for objects y of type S
    where S is a subtype of T.
    Robert (Uncle Bob) Martin
    Functions that use pointers of reference
    to base classes must be able to use objects
    of derived classes without knowing it.
    customer_name and interface_name
    are different types implemented in terms
    of strings

    View Slide

  59. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 59/144
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(interface_name const& ifname,
    customer_name const& customer);
    interface_name lookup_interface(MAC_address mac);
    void setup_customer(MAC_address mac,
    customer_name const& customer)
    {
    assert(!customer.empty());
    auto if_name = lookup_interface(mac);
    assert(if_name.find(':') != std::string::npos);
    label_interface(customer, if_name);
    }
    Liskov Substitution Principle
    Subtype Requirement:
    Let φ(x) be a property provable about objects x of type T.
    Then φ(y) should be true for objects y of type S
    where S is a subtype of T.
    Robert (Uncle Bob) Martin
    Functions that use pointers of reference
    to base classes must be able to use objects
    of derived classes without knowing it.
    customer_name and interface_name
    are different types implemented in terms
    of strings, but they are not strings.

    View Slide

  60. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 60/144
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(interface_name const& ifname,
    customer_name const& customer);
    interface_name lookup_interface(MAC_address mac);
    void setup_customer(MAC_address mac,
    customer_name const& customer)
    {
    assert(!customer.empty());
    auto if_name = lookup_interface(mac);
    assert(if_name.find(':') != std::string::npos);
    label_interface(customer, if_name);
    }
    Liskov Substitution Principle
    Subtype Requirement:
    Let φ(x) be a property provable about objects x of type T.
    Then φ(y) should be true for objects y of type S
    where S is a subtype of T.
    Robert (Uncle Bob) Martin
    Functions that use pointers of reference
    to base classes must be able to use objects
    of derived classes without knowing it.
    customer_name and interface_name
    are different types implemented in terms
    of strings, but they are not strings.
    Maybe it makes sense to allow unlimited access
    to the non-mutating functions of
    std::string, but not to all mutating ones.

    View Slide

  61. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 61/144

    Introduction to type safety

    Type safety in C++

    Simple library solution for strong types

    Sophisticated libraries – scouting github!

    What strong types does with your code
    Type Safe C++? - LOL! :-)

    View Slide

  62. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 62/144
    Jonathan Müller @foonathan
    type_safe Zero overhead utilities for
    preventing bugs at compile time
    https://github.com/foonathan/type_safe

    View Slide

  63. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 63/144
    Jonathan Müller @foonathan
    type_safe Zero overhead utilities for
    preventing bugs at compile time
    https://github.com/foonathan/type_safe
    A rich type library, with which you can piece together the exact behaviour
    of a type that you want.
    It also includes a number of predefined neat type templates, and other
    features like improved optional and variant

    View Slide

  64. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 64/144
    Jonathan Müller @foonathan
    type_safe Zero overhead utilities for
    preventing bugs at compile time
    https://github.com/foonathan/type_safe
    A rich type library, with which you can piece together the exact behaviour
    of a type that you want.
    It also includes a number of predefined neat type templates, and other
    features like improved optional and variant
    Since October 2016

    View Slide

  65. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 65/144
    // type_safe/strong_typedef.hpp
    template
    class type_safe::strong_typedef {
    public:
    constexpr strong_typedef();
    explicit constexpr strong_typedef(const T& value);
    explicit constexpr strong_typedef(T&& value);
    explicit constexpr operator T&() & noexcept;
    explicit constexpr operator const T&() const & noexcept;
    explicit constexpr operator T&&() && noexcept;
    explicit constexpr operator const T&&() const && noexcept;
    };
    https://github.com/foonathan/type_safe

    View Slide

  66. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 66/144
    https://github.com/foonathan/type_safe
    #include
    namespace ts = type_safe;
    namespace op = type_safe::strong_typedef_op;
    struct my_handle : ts::strong_typedef
    , op::equality_comparison
    , op::output_operator
    {
    using strong_typedef::strong_typedef;
    };
    struct my_int : ts::strong_typedef
    , op::integer_arithmetic
    {
    using strong_typedef::strong_typedef;
    };

    View Slide

  67. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 67/144
    https://github.com/foonathan/type_safe
    #include
    namespace ts = type_safe;
    namespace op = type_safe::strong_typedef_op;
    struct my_handle : ts::strong_typedef
    , op::equality_comparison
    , op::output_operator
    {
    using strong_typedef::strong_typedef;
    };
    struct my_int : ts::strong_typedef
    , op::integer_arithmetic
    {
    using strong_typedef::strong_typedef;
    };

    View Slide

  68. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 68/144
    https://github.com/foonathan/type_safe
    #include
    namespace ts = type_safe;
    namespace op = type_safe::strong_typedef_op;
    struct my_handle : ts::strong_typedef
    , op::equality_comparison
    , op::output_operator
    {
    using strong_typedef::strong_typedef;
    };
    struct my_int : ts::strong_typedef
    , op::integer_arithmetic
    {
    using strong_typedef::strong_typedef;
    };

    View Slide

  69. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 69/144
    https://github.com/foonathan/type_safe
    #include
    namespace ts = type_safe;
    namespace op = type_safe::strong_typedef_op;
    struct my_handle : ts::strong_typedef
    , op::equality_comparison
    , op::output_operator
    {
    using strong_typedef::strong_typedef;
    };
    struct my_int : ts::strong_typedef
    , op::integer_arithmetic
    {
    using strong_typedef::strong_typedef;
    };

    View Slide

  70. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 70/144
    https://github.com/foonathan/type_safe
    #include
    namespace ts = type_safe;
    namespace op = type_safe::strong_typedef_op;
    struct my_handle : ts::strong_typedef
    , op::equality_comparison
    , op::output_operator
    {
    using strong_typedef::strong_typedef;
    };
    struct my_int : ts::strong_typedef
    , op::integer_arithmetic
    {
    using strong_typedef::strong_typedef;
    };

    View Slide

  71. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 71/144
    https://github.com/foonathan/type_safe
    #include
    namespace ts = type_safe;
    namespace op = type_safe::strong_typedef_op;
    struct my_handle : ts::strong_typedef
    , op::equality_comparison
    , op::output_operator
    {
    using strong_typedef::strong_typedef;
    };
    struct my_int : ts::strong_typedef
    , op::integer_arithmetic
    {
    using strong_typedef::strong_typedef;
    };

    View Slide

  72. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 72/144
    https://github.com/foonathan/type_safe
    #include
    namespace ts = type_safe;
    namespace op = type_safe::strong_typedef_op;
    struct my_handle : ts::strong_typedef
    , op::equality_comparison
    {
    using strong_typedef::strong_typedef;
    friend std::ostream&
    operator<{
    return os << "H{" << static_cast(h) << "}";
    }
    };

    View Slide

  73. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 73/144
    https://github.com/foonathan/type_safe
    #include
    namespace ts = type_safe;
    namespace op = type_safe::strong_typedef_op;
    struct my_handle : ts::strong_typedef
    , op::equality_comparison
    {
    using strong_typedef::strong_typedef;
    friend std::ostream&
    operator<{
    return os << "H{" << ts::get(h) << "}";
    }
    };

    View Slide

  74. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 74/144
    Jonathan Boccara @joboccara
    NamedType Implementation of
    strong types in C++
    https://github.com/joboccara/NamedType

    View Slide

  75. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 75/144
    Jonathan Boccara @joboccara
    NamedType Implementation of
    strong types in C++
    https://github.com/joboccara/NamedType
    A small type library with a simpler aim, but which still allows you to
    piece together the strong types with your desired behaviour.
    It also supports conversions between different types of the same kind,
    for example meters to feet, or non-linear like Watt to dB.

    View Slide

  76. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 76/144
    Jonathan Boccara @joboccara
    NamedType Implementation of
    strong types in C++
    https://github.com/joboccara/NamedType
    A small type library with a simpler aim, but which still allows you to
    piece together the strong types with your desired behaviour.
    It also supports conversions between different types of the same kind,
    for example meters to feet, or non-linear like Watt to dB.
    MeetingC++ https://www.youtube.com/watch?v=WVleZqzTw2k

    View Slide

  77. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 77/144
    // NamedType/named_type.hpp
    using my_handle =
    fluent::NamedType<
    int, struct my_handle_tag
    >;
    https://github.com/joboccara/NamedType

    View Slide

  78. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 78/144
    // NamedType/named_type.hpp
    using my_handle =
    fluent::NamedType<
    int, struct my_handle_tag,
    fluent::comparable,
    fluent::printable,
    fluent::hashable
    >;
    https://github.com/joboccara/NamedType

    View Slide

  79. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 79/144
    // NamedType/named_type.hpp
    struct my_handle
    : fluent::NamedType<
    int, my_handle,
    fluent::comparable,
    fluent::printable,
    fluent::hashable
    >
    {
    using NamedType::NamedType;
    };
    https://github.com/joboccara/NamedType

    View Slide

  80. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 80/144
    // NamedType/named_type.hpp
    struct my_handle
    : fluent::NamedType<
    int, my_handle,
    fluent::comparable,
    fluent::printable,
    fluent::hashable,
    fluent::ImplicitlyConvertibleTo::templ
    >
    {
    using NamedType::NamedType;
    };
    https://github.com/joboccara/NamedType

    View Slide

  81. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 81/144

    Introduction to type safety

    Type safety in C++

    Simple library solution for strong types

    Sophisticated libraries – scouting github!

    What strong types does with your code
    Type Safe C++? - LOL! :-)

    View Slide

  82. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 82/144
    Network capacity utilisation
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots
    A slot is a network capacity quanta

    View Slide

  83. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 83/144
    Network capacity utilisation
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots
    SlotCount SlotIndexes SlotRanges
    8 3,4,7,8,13,14,15,16 {3-4},{7-8},{13-16}
    3 5,9,10 {5},{9-10}
    13 0,1,2,6,11,12,17,18,
    19,20,21,22,23
    {0-2},{6},{11-12},{17-23}
    A slot is a network capacity quanta

    View Slide

  84. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 84/144
    Network capacity utilisation
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots
    SlotCount SlotIndexes SlotRanges
    8 3,4,7,8,13,14,15,16 {3-4},{7-8},{13-16}
    3 5,9,10 {5},{9-10}
    13 0,1,2,6,11,12,17,18,
    19,20,21,22,23
    {0-2},{6},{11-12},{17-23}
    A slot is a network capacity quanta
    typename SlotIndex; typename SlotCount; struct SlotRange {
    SlotIndex start;
    SlotCount length;
    };

    View Slide

  85. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 85/144
    Magic Numbers

    View Slide

  86. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 86/144
    SlotCount availableCapacity();
    ...
    if (availableCapacity() == 0) {
    ...
    }

    View Slide

  87. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 87/144
    SlotCount availableCapacity();
    ...
    if (availableCapacity() == SlotCount{0}) {
    ...
    }

    View Slide

  88. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 88/144
    SlotCount availableCapacity();
    constexpr SlotCount noSlots{0};
    ...
    if (availableCapacity() == noSlots) {
    ...
    }

    View Slide

  89. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 89/144
    Encapsulation

    View Slide

  90. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 90/144
    class MessageBuffer
    {
    public:
    template
    void serialize_bits(unsigned value);
    };
    SlotCount capacity = ...
    MessageBuffer buffer ...
    buffer.serialize_bits<24>(capacity);

    View Slide

  91. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 91/144
    class MessageBuffer
    {
    public:
    template
    void serialize_bits(unsigned value);
    };
    SlotCount capacity = ...
    MessageBuffer buffer ...
    buffer.serialize_bits<24>(capacity);

    View Slide

  92. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 92/144
    class MessageBuffer
    {
    public:
    template
    void serialize_bits(unsigned value);
    };
    void serialize_data(MessageBuffer& b, SlotCount const& c)
    {
    b.serialize_bits<24>(c);
    }
    SlotCount capacity = ...
    MessageBuffer buffer ...
    serialize_data(buffer, capacity);

    View Slide

  93. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 93/144
    class MessageBuffer
    {
    public:
    template
    void serialize(T const& t) { serialize_data(*this, t); }
    template
    void serialize_bits(unsigned value);
    };
    void serialize_data(MessageBuffer& b, SlotCount const& c)
    {
    b.serialize_bits<24>(c);
    }
    SlotCount capacity = ...
    MessageBuffer buffer ...
    buffer.serialize(capacity);

    View Slide

  94. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 94/144
    Type Semantics

    View Slide

  95. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 95/144
    class SlotPool
    {
    public:
    void releaseCapacity(std::vector const& ranges)
    SlotCount availableCapacity() const { return unusedSlots;}
    ...
    private:
    SlotCount unusedSlots;
    ...
    };

    View Slide

  96. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 96/144
    class SlotPool
    {
    public:
    void releaseCapacity(std::vector const& ranges)
    {
    for (auto& range : ranges)
    {
    ususedSlots += range.length;
    }
    ...
    }
    SlotCount availableCapacity() const { return unusedSlots;}
    ...
    private:
    SlotCount unusedSlots;
    ...
    };

    View Slide

  97. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 97/144
    class SlotPool
    {
    public:
    void releaseCapacity(std::vector const& ranges)
    {
    for (auto& range : ranges)
    {
    ususedSlots += range.length;
    }
    ...
    }
    SlotCount availableCapacity() const { return unusedSlots;}
    ...
    private:
    SlotCount unusedSlots;
    ...
    };
    Does not compile!
    No operator += for SlotCount

    View Slide

  98. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 98/144
    Which operations makes sense?
    SlotCount+SlotCount?
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  99. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 99/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  100. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 100/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount?
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  101. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 101/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  102. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 102/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount?
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  103. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 103/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  104. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 104/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio?
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  105. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 105/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  106. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 106/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount?
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  107. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 107/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  108. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 108/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio?
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  109. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 109/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  110. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 110/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex?
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  111. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 111/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  112. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 112/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount?
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  113. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 113/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  114. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 114/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    SlotIndex-SlotIndex?
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  115. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 115/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    SlotIndex-SlotIndex->SlotCount
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  116. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 116/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    SlotIndex-SlotIndex->SlotCount
    SlotIndex/SlotIndex?
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  117. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 117/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    SlotIndex-SlotIndex->SlotCount
    SlotIndex/SlotIndex
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  118. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 118/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    SlotIndex-SlotIndex->SlotCount
    SlotIndex/SlotIndex
    SlotIndex/SlotCount?
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  119. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 119/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    SlotIndex-SlotIndex->SlotCount
    SlotIndex/SlotIndex
    SlotIndex/SlotCount
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  120. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 120/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    SlotIndex-SlotIndex->SlotCount
    SlotIndex/SlotIndex
    SlotIndex/SlotCount
    SlotIndex/Ratio?
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  121. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 121/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    SlotIndex-SlotIndex->SlotCount
    SlotIndex/SlotIndex
    SlotIndex/SlotCount
    SlotIndex/Ratio
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  122. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 122/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    SlotIndex-SlotIndex->SlotCount
    SlotIndex/SlotIndex
    SlotIndex/SlotCount
    SlotIndex/Ratio
    SlotIndex*SlotIndex?
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  123. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 123/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    SlotIndex-SlotIndex->SlotCount
    SlotIndex/SlotIndex
    SlotIndex/SlotCount
    SlotIndex/Ratio
    SlotIndex*SlotIndex
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  124. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 124/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    SlotIndex-SlotIndex->SlotCount
    SlotIndex/SlotIndex
    SlotIndex/SlotCount
    SlotIndex/Ratio
    SlotIndex*SlotIndex
    SlotIndex*SlotCount?
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  125. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 125/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    SlotIndex-SlotIndex->SlotCount
    SlotIndex/SlotIndex
    SlotIndex/SlotCount
    SlotIndex/Ratio
    SlotIndex*SlotIndex
    SlotIndex*SlotCount
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  126. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 126/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    SlotIndex-SlotIndex->SlotCount
    SlotIndex/SlotIndex
    SlotIndex/SlotCount
    SlotIndex/Ratio
    SlotIndex*SlotIndex
    SlotIndex*SlotCount
    SlotIndex*Ratio?
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  127. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 127/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    SlotIndex-SlotIndex->SlotCount
    SlotIndex/SlotIndex
    SlotIndex/SlotCount
    SlotIndex/Ratio
    SlotIndex*SlotIndex
    SlotIndex*SlotCount
    SlotIndex*Ratio
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  128. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 128/144
    Which operations makes sense?
    SlotCount+SlotCount->SlotCount
    SlotCount-SlotCount->SlotCount
    SlotCount*SlotCount
    SlotCount*Ratio->SlotCount
    SlotCount/SlotCount->Ratio
    SlotCount/Ratio->SlotCount
    SlotIndex+SlotIndex
    SlotIndex+SlotCount->SlotIndex
    SlotIndex-SlotIndex->SlotCount
    SlotIndex/SlotIndex
    SlotIndex/SlotCount
    SlotIndex/Ratio
    SlotIndex*SlotIndex
    SlotIndex*SlotCount
    SlotIndex*Ratio
    Affine Space
    In mathematics, an affine space is a geometric
    structure that generalizes the properties of Euclidean
    spaces in such a way that these are independent of
    the concepts of distance and measure of angles,
    keeping only the properties related to parallelism and
    ratio of lengths for parallel line segments...
    -- Wikipedia
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  129. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 129/144
    Test Code

    View Slide

  130. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 130/144
    DestClient::newCapacity(RequestId, SlotCount);
    TestNode::throttleCapacityTo(RequestId, SlotCount total);
    TEST(capacity_decrease_is_notified_to_clients) {
    TestNode node;
    DestClient client1 = node.clientWithCapacity(5);
    DestClient client2 = node.clientWithCapacity(8);
    REQUIRE_CALL(client1, newCapacity(4, 2));
    REQUIRE_CALL(client2, newCapacity(4, 3));
    node.throttleCapacityTo(4, 5);
    }

    View Slide

  131. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 131/144
    DestClient::newCapacity(RequestId, SlotCount);
    TestNode::throttleCapacityTo(RequestId, SlotCount total);
    TEST(capacity_decrease_is_notified_to_clients) {
    TestNode node;
    DestClient client1 = node.clientWithCapacity(5);
    DestClient client2 = node.clientWithCapacity(8);
    RequestId req{4};
    REQUIRE_CALL(client1, newCapacity(req, 2));
    REQUIRE_CALL(client2, newCapacity(req, 3));
    node.throttleCapacityTo(req, 5);
    }

    View Slide

  132. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 132/144
    DestClient::newCapacity(RequestId, SlotCount);
    TestNode::throttleCapacityTo(RequestId, SlotCount total);
    TEST(capacity_decrease_is_notified_to_clients) {
    TestNode node;
    SlotCount c1Capacity{5}, c2Capacity{8};
    DestClient client1 = node.clientWithCapacity(c1Capacity);
    DestClient client2 = node.clientWithCapacity(c2Capacity);
    RequestId req{4};
    SlotCount newC1Capacity{2}, newC2Capacity{3};
    REQUIRE_CALL(client1, newCapacity(req, newC1Capacity));
    REQUIRE_CALL(client2, newCapacity(req, newC2Capacity));
    SlotCount newTotalCapacity{5};
    node.throttleCapacityTo(req, newTotalCapacity);
    }

    View Slide

  133. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 133/144
    DestClient::newCapacity(RequestId, SlotCount);
    TestNode::throttleCapacityTo(RequestId, SlotCount total);
    TEST(capacity_decrease_is_notified_to_clients) {
    TestNode node;
    SlotCount c1Capacity{5}, c2Capacity{8};
    DestClient client1 = node.clientWithCapacity(c1Capacity);
    DestClient client2 = node.clientWithCapacity(c2Capacity);
    RequestId req{4};
    SlotCount newC1Capacity{2}, newC2Capacity{3};
    REQUIRE_CALL(client1, newCapacity(req, newC1Capacity));
    REQUIRE_CALL(client2, newCapacity(req, newC2Capacity));
    SlotCount newTotalCapacity{5};
    node.throttleCapacityTo(req, newTotalCapacity);
    }
    WTF!

    View Slide

  134. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 134/144
    DestClient::newCapacity(RequestId, SlotCount);
    TestNode::throttleCapacityTo(RequestId, SlotCount total);
    TEST(capacity_decrease_is_notified_to_clients) {
    TestNode node;
    DestClient client1 = node.clientWithCapacity(SlotCount{5});
    DestClient client2 = node.clientWithCapacity(SlotCount{8});
    RequestId req{4};
    REQUIRE_CALL(client1, newCapacity(req, SlotCount{2}));
    REQUIRE_CALL(client2, newCapacity(req, SlotCount{3}));
    node.throttleCapacityTo(req, SlotCount{5});
    }

    View Slide

  135. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 135/144
    DestClient::newCapacity(RequestId, SlotCount);
    TestNode::throttleCapacityTo(RequestId, SlotCount total);
    TEST(capacity_decrease_is_notified_to_clients) {
    TestNode node;
    DestClient client1 = node.clientWithCapacity(SlotCount{5});
    DestClient client2 = node.clientWithCapacity(SlotCount{8});
    RequestId req{4};
    REQUIRE_CALL(client1, newCapacity(req, SlotCount{2}));
    REQUIRE_CALL(client2, newCapacity(req, SlotCount{3}));
    node.throttleCapacityTo(req, SlotCount{5});
    }
    constexpr SlotCount operator"" _slots(unsigned long long v)
    {
    auto cv = static_cast(v);
    return SlotCount{cv};
    }

    View Slide

  136. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 136/144
    DestClient::newCapacity(RequestId, SlotCount);
    TestNode::throttleCapacityTo(RequestId, SlotCount total);
    TEST(capacity_decrease_is_notified_to_clients) {
    TestNode node;
    DestClient client1 = node.clientWithCapacity(5_slots);
    DestClient client2 = node.clientWithCapacity(8_slots);
    RequestId req{4};
    REQUIRE_CALL(client1, newCapacity(req, 2_slots));
    REQUIRE_CALL(client2, newCapacity(req, 3_slots));
    node.throttleCapacityTo(req, 5_slots);
    }
    constexpr SlotCount operator"" _slots(unsigned long long v)
    {
    auto cv = static_cast(v);
    return SlotCount{cv};
    }

    View Slide

  137. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 137/144

    Introduction to type safety

    Type safety in C++

    Simple library solution for strong types

    Sophisticated libraries – scouting github!

    What strong types does with your code
    Type Safe C++? - LOL! :-)

    View Slide

  138. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 138/144

    Safety for built in types is abysmal in C++
    Type Safe C++? - LOL! :-)

    View Slide

  139. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 139/144

    Safety for built in types is abysmal in C++

    Structs/classes are as strong as you wish
    – You must add the functionality you want
    Type Safe C++? - LOL! :-)

    View Slide

  140. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 140/144

    Safety for built in types is abysmal in C++

    Structs/classes are as strong as you wish
    – You must add the functionality you want

    Libraries exist that makes this easier
    Type Safe C++? - LOL! :-)

    View Slide

  141. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 141/144

    Safety for built in types is abysmal in C++

    Structs/classes are as strong as you wish
    – You must add the functionality you want

    Libraries exist that makes this easier

    Thinking about what operations your types should support makes you understand the
    problem better!
    – Beware of the urge for convencience!
    Type Safe C++? - LOL! :-)

    View Slide

  142. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 142/144

    Safety for built in types is abysmal in C++

    Structs/classes are as strong as you wish
    – You must add the functionality you want

    Libraries exist that makes this easier

    Thinking about what operations your types should support makes you understand the
    problem better!
    – Beware of the urge for convencience!

    Strong types leads to more expressive code
    – Fewer magical numbers
    – More encapsulation
    – Explicit tests that express intent
    Type Safe C++? - LOL! :-)

    View Slide

  143. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 143/144

    Safety for built in types is abysmal in C++

    Structs/classes are as strong as you wish
    – You must add the functionality you want

    Libraries exist that makes this easier

    Thinking about what operations your types should support makes you understand the
    problem better!
    – Beware of the urge for convencience!

    Strong types leads to more expressive code
    – Fewer magical numbers
    – More encapsulation
    – Explicit tests that express intent
    Type Safe C++? - LOL! :-)
    Avoid typedef

    View Slide

  144. Type Safe C++? - LOL! :-) – ACCU 2018 – © Björn Fahller @bjorn_fahller 144/144
    Björn Fahller
    [email protected]
    @bjorn_fahller
    @rollbear cpplang, swedencpp
    Type Safe C++? - LOL! :-)

    View Slide