1
// SPDX-License-Identifier: LGPL-2.1-or-later
3
/***************************************************************************************************
5
* Copyright (c) 2022 Zheng, Lei (realthunder) <realthunder.dev@gmail.com> *
6
* Copyright (c) 2023 FreeCAD Project Association *
8
* This file is part of FreeCAD. *
10
* FreeCAD is free software: you can redistribute it and/or modify it under the terms of the *
11
* GNU Lesser General Public License as published by the Free Software Foundation, either *
12
* version 2.1 of the License, or (at your option) any later version. *
14
* FreeCAD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; *
15
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16
* See the GNU Lesser General Public License for more details. *
18
* You should have received a copy of the GNU Lesser General Public License along with *
19
* FreeCAD. If not, see <https://www.gnu.org/licenses/>. *
21
**************************************************************************************************/
24
#include "PreCompiled.h"
28
# include <unordered_set>
31
#include "DocumentObject.h"
32
#include "MappedElement.h"
36
bool ElementNameComparator::operator()(const MappedName& leftName,
37
const MappedName& rightName) const
39
int size = static_cast<int>(std::min(leftName.size(), rightName.size()));
41
return leftName.size() < rightName.size();
44
if (rightName[0] == '#') {
45
if (leftName[0] != '#') {
48
// If both string starts with '#', compare the following hex digits by
51
for (currentIndex = 1; currentIndex < size; ++currentIndex) {
52
auto ac = (unsigned char)leftName[currentIndex];
53
auto bc = (unsigned char)rightName[currentIndex];
54
if (std::isxdigit(bc) != 0) {
55
if (std::isxdigit(ac) == 0) {
67
else if (std::isxdigit(ac) != 0) {
81
for (; currentIndex < size; ++currentIndex) {
82
char ac = leftName[currentIndex];
83
char bc = rightName[currentIndex];
91
return leftName.size() < rightName.size();
93
if (leftName[0] == '#') {
97
// If the string does not start with '#', compare the non-digits prefix
98
// using lexical order.
99
for (currentIndex = 0; currentIndex < size; ++currentIndex) {
100
auto ac = (unsigned char)leftName[currentIndex];
101
auto bc = (unsigned char)rightName[currentIndex];
102
if (std::isdigit(bc) == 0) {
103
if (std::isdigit(ac) != 0) {
113
else if (std::isdigit(ac) == 0) {
121
// Then compare the following digits part by integer value
123
for (; currentIndex < size; ++currentIndex) {
124
auto ac = (unsigned char)leftName[currentIndex];
125
auto bc = (unsigned char)rightName[currentIndex];
126
if (std::isdigit(bc) != 0) {
127
if (std::isdigit(ac) == 0) {
139
else if (std::isdigit(ac) != 0) {
153
// Finally, compare the remaining tail using lexical order
154
for (; currentIndex < size; ++currentIndex) {
155
char ac = leftName[currentIndex];
156
char bc = rightName[currentIndex];
164
return leftName.size() < rightName.size();
167
HistoryItem::HistoryItem(App::DocumentObject *obj, const Data::MappedName &name)
168
:obj(obj),tag(0),element(name)