«

Sep 07

Strong Typing PODs

Identifiying object by a numerical integer is an almost trivial task. In DISPLACE, a very complex simulator I am involved with, there are many of different categories of objects that model different categoris of agents in the simulator, like vessels, marine locations, ships, ports, and so on.

Each object has an Id, and it was very natural, at the start of the project, to implement it using an int.

Problems started when we decided, for optimization purpose, to shrink the memory footprint, to use smaller int instead.

Indeed, there could be at most 65535 nodes, and at most 256 node types, and each was modeled with an int.

The mess started when we found that ids were mixed, and assigning a "Vessel Id" to a "Node Id" was very easy… with obvious, tragic effect.

So there were two problems here: the type opacity, and the strong typing. 

Using PODs were natural, but POD can be assigned to each other (weak types) and, since their storage is predefined, they cannot be changed easily (they aren't opaque).

If the PODs we're using do not require complex methods but they must only represent an integer (a POD) with some meaning, a concept, wrapping them in a class can be tedious. This is why I created the following header file:

template <typename T, typename TAG>
class strong_type {
    T value;
public:
    using Base = T;
    using Tag = TAG;

    explicit strong_type (T v)
    : value (v) {}

    T get() const { return value; }
};

 

The class is very simple: Base and Tag allow extracting the types, Base of the container/Wrapped POD, and Tag of the structure implementing the Tagging of the new type. I implemented Get() to access the POD value, because we don't want the type to be deduced using a cast.

Here the test file (I'm a fanatic of TDD, of course.)

 

#include <gtest/gtest.h>
#include <strongtype.h>
#include <type_traits>

TEST(StrongType, usage)
{
    struct IdTag {};
    using ID = strong_type<int,IdTag>;

    ID i (10);

    struct ValueTag {};
    using Value = strong_type<ID::Base, ValueTag>;

    Value j (10);

    static_assert(!std::is_convertible<ID,Value>::value, "ID and values are convertible!");

    ASSERT_EQ(i.get(), j.get());
}

Note the usage of static_assert to check that the types cannot be assigned or converted automatically by the compiler.

You can find the snippet here.

Happy Coding!

 

Permanent link to this article: http://www.studiofuga.com/2017/09/07/strong-typing-pods/

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

%d bloggers like this: