Catch2 Catch_test_macros.hpp

0 views
Skip to first unread message

Lida Rick

unread,
Aug 5, 2024, 1:46:16 AM8/5/24
to fisuhatos
Catch2is transitioning to a 3.0 release, and the changes break compatibility with Qt's Test integration. Specifically, the current implementation searches for an inclusion of "catch.hpp" for test detection here:

In the 3.0 branch (now the default branch), the headers have been split to help Catch2 compile times. As a result, the catch.hpp header no longer exists in that branch. This has been replaced with several other possible headers: "catch2/catch_all.hpp", "catch2/catch_test_macros.hpp", and "catch2/catch_template_test_macros.hpp"


P.S.: For others that may crave a workaround in the meantime: you can force the current version to work with a minor kludge: make a symlink named catch.hpp pointing to catch_all.hpp, and then include that in your test source. It's not pretty, but it gets Qt to detect it until the above is implemented.


Today we are following up on the previous lesson, finishing our exploration of the standard library. This time, we will focus on algorithms which cover a large portion of the standard library. If you missed the previous lesson, you can find it here:


We have already mentioned iterators in lesson four. Iterators are weak reference types that abstract the internal structure of a container and provide an interface that only exposes constant time operations.


Note that we are less efficient than the previous implementation using indices, as we always traverse the entire container twice and do not meet in the middle. One way to overcome this problem is to utilize the std::counted_iterator adapter.


Another iterator adapter that we will use frequently is std::back_inserter. This adapter can adapt a container, and for each write to the iterator, it will call the corresponding push_back() member function.


The C++20 standard introduced library-level tools that formalize this notion. A range is a pair of an iterator and a sentinel (we have seen a sentinel in action in the previous example with counted iterator). You can still conceptually think about the sentinel as an end. However, it no longer has to be the same type as the iterator; it only needs to be comparable.


This is the first time we have used a template function which works similarly to type templates, except the template arguments can be deduced (same rules as auto) from the arguments the function was called with.


The standard algorithms have undergone several iterations throughout the C++ standards. This, unfortunately, means that when looking for a specific algorithm, you will get multiple results, and the descriptions will contain multiple versions for different algorithm variants.


The main three sorting algorithms that will use regularly are std::ranges::sort - a basic O(n*logn) sort; std::ranges::stable_sort, which is typically less performant but maintains the relative order of elements that compare equal and finally, std::ranges::partial_sort that only sorts up to the provided iterator, leaving the rest of the elements in arbitrary order. The partial sort comes particularly handy where we are only interested in the top k elements, as it runs in O(n*logk).


The third argument is the projection (also optional). Before we apply our comparator to the two elements, we can first project them. This can be as simple as the default std::identity, which returns the original passed-in element. Alternatively, we can project to a member or a value produced by a member function or even completely transform the element.


The main benefit of using lambdas is that we keep our customization code close to where it is used, and since the compiler automatically generates the type for each lambda, we do not have to come up with unique names, such as CompareItemGreaterByLabel.


The above use of lambda is equivalent to a free function. Additionally, we can introduce an internal state to a lambda by capturing some of the local variables. Capturing lambdas are equivalent to function objects (like GreaterObj in the above example).


To check whether two ranges have the same content, we can use the std::ranges::equal algorithm, which returns a boolean. Alternatively, we can use the std::ranges::mismatch algorithm that returns a pair of iterators to the mismatched elements (or simply a pair of end iterators if there is no mismatch).


We have already seen views in action in the initial palindrome example. Views address the core downside of algorithms. Algorithms are eagerly evaluated, meaning that when we want to chain a sequence of operations, we have to contend with intermediate copies of data.


However, once applied to a range and due to lazy evaluation, views are stateful. Notably, they will hold iterators to the underlying range. This means that the usual iterator invalidation rules apply, and even when iterators are not invalidated, mutating the underlying range can lead to unexpected results.


Also, I don't think it's related but, VS Code also complains that it cannot open "catch2/catch_test_macros.hpp: No such file or directory gcc" in the include. When I run it with bazel from the command line it builds and runs OK. So when I try to launch it says gcc could noot compile it.


There isn\u2019t anything wrong with the above approach; however, we are implementing this functionality for one specific type - std::vector. Therefore, it would make sense to lift this into a function, and at that point, we probably do not want to have a variant of this function for every container.


The standard library provides roughly 150 algorithms and views; therefore, we won\u2019t be going over all of them. I have written a book on standard C++ algorithms that you can grab entirely for free: -cpp-algorithms.


Whenever you are writing a loop, consider whether there is an algorithm that already encapsulates this functionality. You will save time in writing and testing the custom logic. On top of that, when you see in your code std::sort(), you will immediately know what is happening and won\u2019t have to study the custom logic you wrote a couple of months ago.

3a8082e126
Reply all
Reply to author
Forward
0 new messages