According to the commenters on the question and some further reading, the complexity is specified as such because there is no trivial stable in-place O(nlogn) sorting algorithm. With some further inspection on the source code, the implementation of libc++
and libstdc++
are similar, both are a merge sort where the in-place merge has complexity O(nlogn). As for the "additional memory", the two libraries require N additional memory, where N is the length of the array.
More specifically, instead linearly scanning the two sub-arrays and merging one element at a time, the in-place merge search for a way partition each of the two sub-arrays into two parts (four parts in total), such that when swapping the middle two parts, all elements in the the leftmost two parts are smaller or equal to the rightmost two parts. Then they perform in-place merge on the leftmost and rightmost two part respectively.