Time to announce some unconventional features again!
Named tuplesThe C++11 standard library provides the
std::tuple class template, which is able to store multiple types. It provides many handy features, such as member-wise equality comparison and lexicographical ordering, making it suitable to be used in STL containers. However, standard pairs and tuples have a big disadvantage: accessing their elements is not expressive at all.
std::tuple<int, double> tuple(1, 3.42);
int i = std::get<0>(tuple);
Code like that is not only hard to read, but also error-prone: You have to know the order of elements by heart, using a wrong index may lead to silent bugs. Furthermore, you cannot associate any meaning to the tuple member; it's unclear what the
int stands for.
A common alternative is to use simple
struct types, where it's possible to give names to the member variables. However, this approach suffers again several limitations: You have to define all the functionality you need yourself. The compiler-generated default constructor may leave some members uninitialized, and a custom constructor is still required in many cases, even if it just initializes member by member.
operator== and
operator< have to be hand-written, and the definition of the latter is often non-trivial.
Aurora introduces a
named tuple type that combines the functionality of
std::tuple with the expressive and intuitive usage of user-defined
structs. Named tuples are very effective at avoiding boilerplate code. A named tuple is defined by using a macro:
AURORA_NAMED_TUPLE(UnitData,
(
(sf::Vector2f, position),
(float, rotation),
(int, hitpoints)
))
AURORA_NAMED_TUPLE(Index2D,
(
(std::size_t, x),
(std::size_t, y)
))
The first parameter is the type name, the second is a preprocessor sequence of type-value pairs, declaring each member variable. Extended functionality can easily be introduced by using the macro
AURORA_NAMED_TUPLE_EXT. For example, the following code defines an
operator== and a default constructor. At the moment, the extensions
EQUAL,
LESS,
DEFAULT_CTOR and
HASHER are available.
AURORA_NAMED_TUPLE_EXT(UnitData,
(
(sf::Vector2f, position),
(float, rotation),
(int, hitpoints)
),
(AURORA_NT_EQUAL, AURORA_NT_DEFAULT_CTOR))
Every named tuple defines a constructor taking a value for each member, a default constructors is defined as shown above. The type can now be used as follows:
UnitData d(sf::Vector2f(200, 300), 270.f, 20);
UnitData e;
e.position = sf::Vector2f(200, 300);
e.rotation = 270.f;
e.hitpoints = 20;
assert(d == e);
Named tuples are convertible to
std::tuple by using the
toStdTuple() member function.
std::tuple<sf::Vector2f, float, int> t = d.toStdTuple();