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

February 22, 2018
Tweet

More Decks by Björn Fahller

Other Decks in Programming

Transcript

  1. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 1/140
    Type Safe C++? - LOL! :-)
    Björn Fahller

    View Slide

  2. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 2/140
    Type Safe C++? - LOL! :-)
    Björn Fahller

    View Slide

  3. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 3/140
    Type Safe C++? - LOL! :-)
    What is type safety?

    View Slide

  4. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 4/140
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 5/140
    A type safe system 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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 6/140

    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 7/140
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 8/140
    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);
    }
    The story begins

    View Slide

  9. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 9/140
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 10/140
    void other(const A& a);
    void func(B b)
    {
    other(b);
    }
    When is
    this call
    allowed?

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  17. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 17/140
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 18/140
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 19/140
    We have control over
    when the compiler
    will allow a conversion!

    View Slide

  20. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 20/140
    class receiver_id
    {
    public:
    receiver_id(uint32_t v) : value{v} {}
    operator uint32_t() const { return value; }
    private:
    uint32_t value;
    };

    View Slide

  21. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 21/140
    class receiver_id
    {
    public:
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 22/140
    class receiver_id
    {
    public:
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 23/140
    class receiver_id
    {
    public:
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 24/140
    class receiver_id
    {
    public:
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 25/140
    class receiver_id
    {
    public:
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 26/140
    class receiver_id
    {
    public:
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 27/140
    class receiver_id
    {
    public:
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 28/140
    class receiver_id
    {
    public:
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 29/140
    class receiver_id
    {
    public:
    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

  30. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 30/140
    class receiver_id
    {
    public:
    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

  31. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 31/140

    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

  32. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 32/140
    template
    class safe_type
    {
    public:
    private:
    T value_;
    };

    View Slide

  33. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 33/140
    template
    class safe_type
    {
    public:
    safe_type(T t) : value_(std::move(t)) {}
    operator T() const { return value_; }
    // operators...
    private:
    T value_;
    };

    View Slide

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

    View Slide

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

    View Slide

  36. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 36/140
    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

  37. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 37/140
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 38/140
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 39/140
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 40/140
    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

  41. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 41/140
    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! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 42/140
    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

  43. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 43/140
    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

  44. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 44/140
    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

  45. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 45/140
    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

  46. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 46/140
    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

  47. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 47/140
    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

  48. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 48/140
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(const interface_name& ifname,
    const customer_name& 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);
    }

    View Slide

  49. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 49/140
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(const interface_name& ifname,
    const customer_name& 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);
    }

    View Slide

  50. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 50/140
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(const interface_name& ifname,
    const customer_name& 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);
    }
    Accidental swap!

    View Slide

  51. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 51/140
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(const interface_name& ifname,
    const customer_name& 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

  52. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 52/140
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(const interface_name& ifname,
    const customer_name& 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(const safe_type&) = delete;
    };

    View Slide

  53. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 53/140
    SAFE_TYPE(interface_name, std::string);
    SAFE_TYPE(customer_name, std::string);
    void label_interface(const interface_name& ifname,
    const customer_name& 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);
    }
    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

  54. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 54/140

    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

  55. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 55/140
    Jonathan Müller @foonathan
    type_safe Zero overhead utilities for
    preventing bugs at compile time
    https://github.com/foonathan/type_safe

    View Slide

  56. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 56/140
    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

  57. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 57/140
    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

  58. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 58/140
    // 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

  59. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 59/140
    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

  60. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 60/140
    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

  61. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 61/140
    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

  62. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 62/140
    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

  63. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 63/140
    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

  64. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 64/140
    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

  65. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 65/140
    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

  66. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 66/140
    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

  67. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 67/140
    Jonathan Boccara @joboccara
    NamedType Implementation of
    strong types in C++
    https://github.com/joboccara/NamedType

    View Slide

  68. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 68/140
    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

  69. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 69/140
    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

  70. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 70/140
    // NamedType/named_type.hpp
    using my_handle =
    fluent::NamedType<
    int, struct my_handle_tag
    >;
    https://github.com/joboccara/NamedType

    View Slide

  71. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 71/140
    // 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

  72. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 72/140
    // 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

  73. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 73/140
    // 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

  74. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 74/140

    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

  75. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 75/140
    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

  76. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 76/140
    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

  77. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 77/140
    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

  78. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 78/140
    Magic Numbers

    View Slide

  79. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 79/140
    SlotCount availableCapacity();
    ...
    if (availableCapacity() == 0) {
    ...
    }

    View Slide

  80. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 80/140
    SlotCount availableCapacity();
    ...
    if (availableCapacity() == SlotCount{0}) {
    ...
    }

    View Slide

  81. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 81/140
    SlotCount availableCapacity();
    constexpr SlotCount noCapacity{0};
    ...
    if (availableCapacity() == noCapacity) {
    ...
    }

    View Slide

  82. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 82/140
    Encapsulation

    View Slide

  83. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 83/140
    class MessageBuff {
    public:
    template
    serialize_bits(unsigned value);
    };
    SlotCount capacity = ...
    MessageBuff buffer ...
    buffer.serialize_bits<24>(capacity);

    View Slide

  84. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 84/140
    class MessageBuff {
    public:
    template
    serialize_bits(unsigned value);
    };
    SlotCount capacity = ...
    MessageBuff buffer ...
    buffer.serialize_bits<24>(capacity);

    View Slide

  85. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 85/140
    class MessageBuff {
    public:
    template
    serialize_bits(unsigned value);
    };
    void serialize(MessageBuff& b, const SlotCount& c) {
    b.serialize_bits<24>(value(c));
    }
    SlotCount capacity = ...
    MessageBuff buffer ...
    serialize(buffer, capacity);

    View Slide

  86. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 86/140
    template
    void serialize(MessageBuff&,const T&) = delete;
    class MessageBuff {
    public:
    template
    serialize_bits(unsigned value);
    };
    template <>
    void serialize(MessageBuff& b, const SlotCount& c) {
    b.serialize_bits<24>(value(c));
    }
    SlotCount capacity = ...
    MessageBuff buffer ...
    serialize(buffer, capacity);

    View Slide

  87. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 87/140
    class MessageBuff;
    template
    void serialize(MessageBuff&,const T&) = delete;
    class MessageBuff {
    public:
    template
    serialize_bits(unsigned value);
    };
    template <>
    void serialize(MessageBuff& b, const SlotCount& c) {
    b.serialize_bits<24>(value(c));
    }
    SlotCount capacity = ...
    MessageBuff buffer ...
    serialize(buffer, capacity);

    View Slide

  88. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 88/140
    class MessageBuff;
    template
    void serialize(MessageBuff&,const T&) = delete;
    class MessageBuff {
    public:
    template
    void serialize(const T& t) { ::serialize(*this, t); }
    template
    serialize_bits(unsigned value);
    };
    template <>
    void serialize(MessageBuff& b, const SlotCount& c) {
    b.serialize_bits<24>(value(c));
    }
    SlotCount capacity = ...
    MessageBuff buffer ...
    serialize(buffer, capacity);

    View Slide

  89. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 89/140
    class MessageBuff;
    template
    void serialize(MessageBuff&,const T&) = delete;
    class MessageBuff {
    public:
    template
    void serialize(const T& t) { ::serialize(*this, t); }
    template
    serialize_bits(unsigned value);
    };
    template <>
    void serialize(MessageBuff& b, const SlotCount& c) {
    b.serialize_bits<24>(value(c));
    }
    SlotCount capacity = ...
    MessageBuff buffer ...
    buffer.serialize(capacity);

    View Slide

  90. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 90/140
    Type Semantics

    View Slide

  91. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 91/140
    class SlotPool
    {
    public:
    void releaseCapacity(const std::vector& ranges)
    SlotCount availableCapacity() const { return unusedSlots;}
    ...
    private:
    SlotCount unusedSlots;
    ...
    };

    View Slide

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

    View Slide

  93. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 93/140
    class SlotPool
    {
    public:
    void releaseCapacity(const std::vector& 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

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

    View Slide

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

    View Slide

  96. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 96/140
    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

  97. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 97/140
    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

  98. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 98/140
    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

  99. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 99/140
    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

  100. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 100/140
    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

  101. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 101/140
    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

  102. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 102/140
    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

  103. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 103/140
    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

  104. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 104/140
    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

  105. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 105/140
    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

  106. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 106/140
    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

  107. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 107/140
    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

  108. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 108/140
    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

  109. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 109/140
    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

  110. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 110/140
    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

  111. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 111/140
    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

  112. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 112/140
    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

  113. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 113/140
    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

  114. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 114/140
    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

  115. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 115/140
    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

  116. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 116/140
    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

  117. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 117/140
    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

  118. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 118/140
    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

  119. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 119/140
    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

  120. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 120/140
    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

  121. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 121/140
    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

  122. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 122/140
    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

  123. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 123/140
    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

  124. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 124/140
    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 Geometry
    In mathematics, affine geometry is what
    remains of Euclidean geometry when not
    using (mathematicians often say "when forgetting")
    the metric notions of distance and angle.
    -- Wikipedia
    0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223
    Frame with 24 slots

    View Slide

  125. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 125/140
    Test Code

    View Slide

  126. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 126/140
    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

  127. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 127/140
    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

  128. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 128/140
    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

  129. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 129/140
    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

  130. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 130/140
    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

  131. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 131/140
    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

  132. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 132/140
    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

  133. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 133/140

    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

  134. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 134/140

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

    View Slide

  135. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 135/140

    Safety for built in types is abysmal in C++

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

    View Slide

  136. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 136/140

    Safety for built in types is abysmal in C++

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

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

    View Slide

  137. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 137/140

    Safety for built in types is abysmal in C++

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

    Libraries exist that makes this easier

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

    View Slide

  138. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 138/140

    Safety for built in types is abysmal in C++

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

    Libraries exist that makes this easier

    Thinking about what operations your types should support makes you
    understand the problem better!

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

    View Slide

  139. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 139/140

    Safety for built in types is abysmal in C++

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

    Libraries exist that makes this easier

    Thinking about what operations your types should support makes you
    understand the problem better!

    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

  140. Type Safe C++? - LOL! :-) – Stockholm C++ 0x0A – Björn Fahller @bjorn_fahller 140/140
    Björn Fahller
    [email protected]
    @bjorn_fahller
    @rollbear cpplang, swedencpp
    Type Safe C++? - LOL! :-)

    View Slide