================================ How-To make C++ types comparable ================================ Often, we find ourselves in a situation where we have some struct or class, and it would be convenient to compare one instance to another. Similarly, we may find that it is conceptually ideal as a key for some `std::map` we're using. This isn't a particularly complex thing to achieve, but it introduces a lot of boilerplate code. Instead, we can use `liberate/cpp/operators/comparison.h`. .. sourcecode:: cpp :linenos: :dedent: :caption: Header and inheritance #include struct my_type : public liberate::cpp::comparison_operators { // ... }; my_type a, b; assert(a == b); The :cpp:class:`liberate::cpp::comparison_operators` struct adds a number of comparison operators to your class including ``operator==()`` -- but the compilation of the above will nonetheless fail, because *how* to compare ``my_struct`` is unclear. You will have to provide a function for performing this comparison, ``is_equal_to``. .. sourcecode:: cpp :linenos: :dedent: :caption: Make equality comparable struct my_type : public liberate::cpp::comparison_operators { bool is_equal_to(my_type const & other) const { // do your comparison here } }; How is this any better than implementing ``operator==()`` directly? Simply because the `liberate` class also provides an ``operator!=()`` from the same function. The utility of this may become more apparent when considering less-than comparison instead. .. sourcecode:: cpp :linenos: :dedent: :caption: Make less-than comparable struct my_type : public liberate::cpp::comparison_operators { bool is_less_than(my_type const & other) const { // do your comparison here } }; my_type a, b; if (a < b) { /* ... */ } if (a > b) { /* ... */ } if (a <= b) { /* ... */ } if (a >= b) { /* ... */ } All of the above four operators are provided via the single ``is_less_than`` function. Providing both functions yields 6 operators altogether, enough for comparisions required for key types in ``std::map``, etc. .. note:: All operators are inline functions, so will not generate code unless you use them. This means that it's entirely possible to provide only an implementation of e.g. ``is_equal_to`` so long as you never perform any less-than, greater-than or similar comparisons. Sometimes it's easier to make a type comparable with free functions when it already has defined an ``operator==`` and an ``operator<``. You can do this very easily. It's also possible to combine both approaches. There's a simple macro for that. .. sourcecode:: cpp :linenos: :dedent: :caption: Add operators as free functions LIBERATE_MAKE_COMPARABLE(my_type);