Boost.Mixin is a library that allows the composition and modifications of types at run time. Types and objects are constructed out of building blocks called mixins enabling an effect similar to multiple inheritance, while allowing the client code to remain oblivious to the actual composition of the objects.
A take on the Composition over inheritance technique, the result closely resembles the popular pattern entity-component-system, or the mixins in Ruby. It can also be compared to the inheritance in Eiffel or the traits in Self, Scala, PHP, and many others, or the roles in Perl.
This is given while also having full abstraction between the interface and the definition of types – a problem often given as the motivation for the PIMPL idiom.
The library uses the type
as a placeholder, whose instances can be extended with existing classes (mixins),
thus providing a particular instance with the functionality of all those
types. Accessing the newly formed type's interface is made through messages
– stand-alone functions generated by the library, which can be thought
of as methods.
Boost.Mixin focuses on maximal performance and minimal memory overhead.
The closest thing to Boost.Miixin that C++ can offer out of the box is
multiple inheritance. A
composed of some mixins, can be though of as an empty class that's derived
from these classes – the object's interface will be equal to the
union of the interfaces of its mixins, and it will internally instantiate
We covered how much more than multiple inheritance the library is in the previous section, but in case you haven't inferred everything, here a comprehensive list of the most imporatnt differences between Boost.Mixin and C++ multiple inheritance:
However, even-though compared to other libraries that have similar features, Boost.Mixin is one of the fastest and with the least memory overhead, using the library comes with some inevitable downsides when compared with plain multiple inheritance:
barcan implicitly be cast too
bar. Since the library uses a placeholder type –
boost::mixin::object– implicit casts to any of its mixins are impossible. That aside, the hypothetical object from above, will recieve all of the methods from foo and bar, but while this is true for the
mixin::objectwith such mixins, a compilation error cannot be generated if a message is called that the object can't handle. A runtime error will be generated instead, which is the norm in similar libraries, but is harder to catch and debug than it is with plain multiple inheritance.
boost::mixin::objectsnaturally takes up the same amount plus an additional pointer for the type metadata, plus N pointers used for the special
bm_thispointer, where N is equal to the number of mixins within. So, in short, the memory overhead of an object composed on N mixins, is N+1 times
sizeof(intptr_t)((N+1) * 8 bytes on a 64 bit system).
std::functioncall in terms of speed, which in most (but not all) cases is a negligible overhead.
If you're familiar with entity-component-systems, one way of looking at at the library is as if it is one of those, and indeed, it has many features that are characteristic for such systems.
If you're not familiar with entity-component-systems, you might want to check out the appendix entry on them.
Here's how Boost.Mixin is like an ECS:
boost::mixin::objectcan be interpreted as an entity in an ECS. It's just an empty class, that needs to be "built" from mixins.
However, Boost.Mixin is not strictly an ECS. Here's a list of the differences.
boost::mixin::object-s can be (and are) completely oblivious to what kinds of mixins there may be, allowing you to truly, physically separate a program's subsystems. The entity in an ECS on the other hand, usually has at least some knowledge of all the possible component types (like the top level parent classes, for example).