That actually is quite interesting. std::partition only really registered as a sorting function for me.

At the risk of going off into the weeds with you, I would normally use the code I posted in a single invocation to remove a single element once found.  Whereas unstable_remove_if would have required invoking all of the following in the version you linked to:

template<class BidirIt, class UnaryPredicate>

#if __cplusplus >= 201703L

[[nodiscard]]

#endif

BidirIt unstable_remove_if(BidirIt first, BidirIt last, UnaryPredicate p) {

  while (true) {

    // Find the first instance of "p"...

    while (true) {

      if (first == last) {

        return first;

      }

      if (p(*first)) {

        break;

      }

      ++first;

    }

    // ...and the last instance of "not p"...

    while (true) {

      --last;

      if (first == last) {

        return first;

      }

      if (!p(*last)) {

        break;

      }

    }

    // ...and move the latter over top of the former.

    *first = std::move(*last);

    ++first;

  }

}


template<class FwdIt>

void destroy(FwdIt begin, FwdIt end) {

  typedef typename std::iterator_traits<FwdIt>::value_type T;

  while (begin != end) {

    begin->~T();

    ++begin;

  }

}










On Mon, Apr 6, 2026 at 10:41 AM Arthur O'Dwyer <arthur.j.odwyer@gmail.com> wrote:
On Mon, Apr 6, 2026 at 1:28 PM Adrian Johnston via Std-Proposals <std-proposals@lists.isocpp.org> wrote:

If your array is unordered then you can just swap the end element down when erasing an element.

From my own code:


template<hxarray_concept_ T_, size_t capacity_>

void hxarray<T_, capacity_>::erase_unordered(const T_* pos_) {

    hxassertmsg(pos_ >= this->data() && pos_ < m_end_, "invalid_iterator");

    if(pos_ != --m_end_) {

        *const_cast<T_*>(pos_) = hxmove(*m_end_);

    }

    m_end_->~T_();

}


This is something I think the std::vector could definitely use.


This is properly an algorithm: `stdx::unstable_remove{,_if}`.
See
Brent Friedman, 2015: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0041r0.html
Brent Friedman, 2016: https://iterator.wordpress.com/2016/01/31/algorithms_0/ (archived)
Arthur O'Dwyer, 2023-ish: https://github.com/Quuxplusone/SG14?tab=readme-ov-file#efficient-removal-algorithms-future--c14
Ted Lyngmo, 2025: https://discourse.bemanproject.org/t/help-getting-started-writing-a-propsal-for-unstable-remove-and-friends-wanted/335

Note that David Sankel asked (in the last link above) how std::unstable_remove_if was different from std::partition. The answer is that std::partition swaps; std::unstable_remove_if leaves the right-hand elements in a moved-from state (à la std::shift_left).
Note that (AIUI) Ted Lyngmo abandoned his proposal because the benchmark numbers weren't good enough to justify the standardization effort; see here.

HTH,
Arthur