#961·doctest

Enhance existing matcher system

Author: mitchgroutCreated Oct 27, 2025Updated Jul 13, 2026

Consider the following snippet:

cpp
struct event { std::string message; std::any data; };
auto events = std::vector<event> { ... };

auto found = std::find_if(events.begin(), events.end(), [](auto event) { return event.message == "task started"; });
CHECK(found);

While this gets the job done, it bugs me for a few reasons:

  1. We need to use <algorithm> for std::find_if which incurs an not-insignificant inclusion cost
  2. The majority of the auto found = ... expression is iterative boilerplate
  3. Upon assertion failure, we learn nothing about the content of events (assuming a stringification is available for both event and std::vector)
    • This is particularly annoying when a failure occurs on CI/CD, where debugging is not readily available
    • This could be fixed via an explicit CAPTURE(events), but this feels like a bolted-on solution

Taking inspiration from RSpec, we could rewrite this into the following hypothetical form:

cpp
using namespace doctest::matchers;
CHECK(events == Includes( Splat("task started", ignore) ));

The Includes takes a matcher<T> object, and essentially performs the std::find_if operation. The Splat on the other hand, takes an Args... sequence which are the members of T, destructs the T object into its parts, and then pairwise compares each (note this only works if T is POD), effectively performing the lambda associated with the std::find_if. doctest::ignore is a special matcher which is always-true. This would resolve the three prior points:

  1. It is directly available in doctest, at (presumably) a low inclusion/compilation cost
  2. The assertion is now almost-entirely composed of relevant components
  3. Upon assertion failure, the expression decomposer will request events to be shown, providing further context when debugging

Matchers would be an entirely optional part of doctest to make certain types of assertion easier, but should have no impact on existing code-bases.