Skip to content

Proposal: Use Strong Types throughout the whole API

Motivation

MantleAPI uses the units library to ensure the validiy of calculations based on physical units, which is great! We also du a good job on declaring all enums as enum class. Other parts of the API, however, do not provide the same safety on a type level.

Let's look at some examples (not exhaustive):

  1. Same type, easily swapped by mistake
virtual void IEnvironment::RemoveEntityFromController(UniqueId entity_id, UniqueId controller_id) = 0;
                                                               ^                   ^
virtual void IEnvironment::SetTrafficSignalState(const std::string& traffic_signal_name, const std::string& traffic_signal_state) = 0;
                                                                    ^                                       ^
std::string OpenDriveLanePosition::road;
            ^
TrafficSwarmParameters{"central_entity", 10, {10_mps, 20_mps}, 10_m, 10_m, 20_m, 0_m}
                                              ^       ^        ^     ^     ^     ^
  1. Implicitly convertable
using UniqueId = std::uint64_t;
      ^ 
std::int32_t OpenDriveLanePosition::lane;
             ^

Solutions

For integer-like types, an easy solution could be enum class:

using UnsignedIdType = std::uint64_t;
using SignedIdType = std::int64_t;

enum class EntityId : UnsignedIdType {};
enum class ControllerId : UnsignedIdType {};

enum class LaneId : SignedIdType {};

For other types, such as names the following resources provide possible solutions.

Resources

There's a great series of articles on the topic here, which includes a number of possible solutions: Fluent C++: Strong types for strong interfaces

Edited by Martin Stump