.. title:: clang-tidy - bugprone-missing-end-comparison

bugprone-missing-end-comparison
===============================

Finds instances where the result of a standard algorithm is used in a Boolean
context without being compared to the end iterator.

Standard algorithms such as ``std::find``, ``std::search``, and
``std::lower_bound`` return an iterator to the element if found, or the end
iterator otherwise.

Using the result directly in a Boolean context (like an ``if`` statement) is
almost always a bug, as it only checks if the iterator itself evaluates to
``true``, which may always be true for many iterator types.

Examples:

.. code-block:: c++

  void example() {
    int arr[] = {1, 2, 3};
    int* begin = std::begin(arr);
    int* end = std::end(arr);

    if (std::find(begin, end, 2)) {
      // ...
    }

    // Fixed by the check:
    if ((std::find(begin, end, 2) != end)) {
      // ...
    }

    // C++20 ranges:
    int v[] = {1, 2, 3};
    if (std::ranges::find(v, 2)) {
      // ...
    }

    // Fixed by the check:
    if ((std::ranges::find(v, 2) != std::ranges::end(v))) {
      // ...
    }
  }

The check also handles range-based algorithms introduced in C++20.

Supported algorithms:

- ``std::adjacent_find``
- ``std::find``
- ``std::find_end``
- ``std::find_first_of``
- ``std::find_if``
- ``std::find_if_not``
- ``std::is_sorted_until``
- ``std::lower_bound``
- ``std::max_element``
- ``std::min_element``
- ``std::partition_point``
- ``std::search``
- ``std::search_n``
- ``std::upper_bound``
- ``std::ranges::adjacent_find``
- ``std::ranges::find``
- ``std::ranges::find_first_of``
- ``std::ranges::find_if``
- ``std::ranges::find_if_not``
- ``std::ranges::is_sorted_until``
- ``std::ranges::lower_bound``
- ``std::ranges::max_element``
- ``std::ranges::min_element``
- ``std::ranges::upper_bound``

Options
-------

.. option:: ExtraAlgorithms

  A semicolon-separated list of extra algorithms to check.
  The list can contain:

  - Iterator-based algorithms. These should follow the standard iterator
    pattern: ``func(Iter, Iter, ...)``.

  - Range-based algorithms. These are heuristically detected if they take
    exactly two arguments and the first argument is a container or range.
    The fix will insert ``std::end(Container)``.

  Default is an empty string.
