'Sort elements alphabetically but keep one always at the beginning

I have elements of the following type stored in a collection.

class Element
{
public:
    bool IsDefault { false };
    std::wstring Name { };

    Element() = default;
    Element(const bool isDefault, std::wstring name) : IsDefault { isDefault }, Name { std::move(name) }
    {}

    bool operator==(const Element& other) const noexcept = default;
};

Note there can only be one element with IsDefault == true. What I want to achieve is sort the collection alphabetically (case-insensitive), but put the one element with IsDefault == true always at the beginning, regardless of its name.

My current code works, but I am looking for a way that is more efficient (as it is now, finding the one element with IsDefault == true takes O(N) and then sorting the collection takes O(N log N) afterwards) ore more idiomatic / requires less code. What can I do to improve it? Is there a way to achieve my goal with a single call to std::ranges::sort or some other function?

I can make use of C++20 features if required.

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    std::vector elements { Element(false, L"World"), Element(true, L"Foo"), Element(false, L"Zoo"), Element(false, L"Bar") };

    // Find the default element and remove it from the vector.
    Element defaultElement;

    for (const auto& e : elements)
    {
        if (e.IsDefault)
        {
            defaultElement = e;
            std::erase(elements, e);
            break;
        }
    }

    // Sort the remaining elements alphabetically
    std::ranges::sort(elements, [](const Element& a, const Element& b) noexcept
                      {
                          const auto& first { a.Name };
                          const auto& second { b.Name };
                          return ::_wcsnicmp(first.c_str(), second.c_str(), std::min(first.size(), second.size())) < 0;
                      });

    // Insert the default element at index 0
    elements.insert(std::begin(elements), defaultElement);

    _ASSERT(elements.at(0).Name == L"Foo");
    _ASSERT(elements.at(1).Name == L"Bar");
    _ASSERT(elements.at(2).Name == L"World");
    _ASSERT(elements.at(3).Name == L"Zoo");
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source