FreeCAD

Форк
0
/
Enumeration.cpp 
297 строк · 6.9 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2015 Ian Rees <ian.rees@gmail.com>                      *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24
#ifndef _PreComp_
25
# include <cassert>
26
# include <cstring>
27
#endif
28

29
#include <Base/Exception.h>
30
#include "Enumeration.h"
31
#include <string_view>
32

33
using namespace App;
34

35
namespace {
36
struct StringCopy : public Enumeration::Object {
37
    explicit StringCopy(const char* str) : d(str) {
38
    }
39
    const char* data() const override {
40
        return d.data();
41
    }
42
    bool isEqual(const char* str) const override {
43
        return d == str;
44
    }
45
    bool isCustom() const override {
46
        return true;
47
    }
48

49
private:
50
    std::string d;
51
};
52

53
struct StringView : public Enumeration::Object {
54
    explicit StringView(const char* str) : d(str) {
55
    }
56
    const char* data() const override {
57
        return d.data();
58
    }
59
    bool isEqual(const char* str) const override {
60
        return d == str;
61
    }
62
    bool isCustom() const override {
63
        return false;
64
    }
65

66
private:
67
    std::string_view d;
68
};
69
}
70

71
Enumeration::Enumeration()
72
    : _index(0)
73
{
74
}
75

76
Enumeration::Enumeration(const Enumeration &other)
77
{
78
    enumArray = other.enumArray;
79
    _index = other._index;
80
}
81

82
Enumeration::Enumeration(const char *valStr)
83
    : _index(0)
84
{
85
    enumArray.push_back(std::make_shared<StringCopy>(valStr));
86
    setValue(valStr);
87
}
88

89
Enumeration::Enumeration(const char **list, const char *valStr)
90
    : _index(0)
91
{
92
    while (list && *list) {
93
        enumArray.push_back(std::make_shared<StringView>(*list));
94
        list++;
95
    }
96
    setValue(valStr);
97
}
98

99
Enumeration::~Enumeration()
100
{
101
    enumArray.clear();
102
}
103

104
void Enumeration::setEnums(const char **plEnums)
105
{
106
    std::string oldValue;
107
    bool preserve = (isValid() && plEnums != nullptr);
108
    if (preserve) {
109
        const char* str = getCStr();
110
        if (str)
111
            oldValue = str;
112
    }
113

114
    enumArray.clear();
115
    while (plEnums && *plEnums) {
116
        enumArray.push_back(std::make_shared<StringView>(*plEnums));
117
        plEnums++;
118
    }
119

120
    // set _index
121
    if (_index < 0)
122
        _index = 0;
123
    if (preserve) {
124
        setValue(oldValue);
125
    }
126
}
127

128
void Enumeration::setEnums(const std::vector<std::string> &values)
129
{
130
    if (values.empty()) {
131
        setEnums(nullptr);
132
        return;
133
    }
134

135
    std::string oldValue;
136
    bool preserve = isValid();
137
    if (preserve) {
138
        const char* str = getCStr();
139
        if (str)
140
            oldValue = str;
141
    }
142

143
    enumArray.clear();
144
    for (const auto & it : values) {
145
        enumArray.push_back(std::make_shared<StringCopy>(it.c_str()));
146
    }
147

148
    // set _index
149
    if (_index < 0)
150
        _index = 0;
151
    if (preserve) {
152
        setValue(oldValue);
153
    }
154
}
155

156
void Enumeration::setValue(const char *value)
157
{
158
    _index = 0;
159
    for (std::size_t i = 0; i < enumArray.size(); i++) {
160
        if (enumArray[i]->isEqual(value)) {
161
            _index = static_cast<int>(i);
162
            break;
163
        }
164
    }
165
}
166

167
void Enumeration::setValue(long value, bool checkRange)
168
{
169
    if (value >= 0 && value < countItems()) {
170
        _index = value;
171
    } else {
172
        if (checkRange) {
173
            throw Base::ValueError("Out of range");
174
        } else {
175
            _index = value;
176
        }
177
    }
178
}
179

180
bool Enumeration::isValue(const char *value) const
181
{
182
    int i = getInt();
183

184
    if (i == -1) {
185
        return false;
186
    } else {
187
        return enumArray[i]->isEqual(value);
188
    }
189
}
190

191
bool Enumeration::contains(const char *value) const
192
{
193
    if (!isValid()) {
194
        return false;
195
    }
196

197
    for (const auto& it : enumArray) {
198
        if (it->isEqual(value))
199
            return true;
200
    }
201

202
    return false;
203
}
204

205
const char * Enumeration::getCStr() const
206
{
207
    if (!isValid() || _index < 0 || _index >= countItems()) {
208
        return nullptr;
209
    }
210

211
    return enumArray[_index]->data();
212
}
213

214
int Enumeration::getInt() const
215
{
216
    if (!isValid() || _index < 0 || _index >= countItems()) {
217
        return -1;
218
    }
219

220
    return _index;
221
}
222

223
std::vector<std::string> Enumeration::getEnumVector() const
224
{
225
    std::vector<std::string> list;
226
    for (const auto& it : enumArray)
227
        list.emplace_back(it->data());
228
    return list;
229
}
230

231
bool Enumeration::hasEnums() const
232
{
233
    return (!enumArray.empty());
234
}
235

236
bool Enumeration::isValid() const
237
{
238
    return (!enumArray.empty() && _index >= 0 && _index < countItems());
239
}
240

241
int Enumeration::maxValue() const
242
{
243
    int num = -1;
244
    if (!enumArray.empty())
245
        num = static_cast<int>(enumArray.size()) - 1;
246
    return num;
247
}
248

249
bool Enumeration::isCustom() const
250
{
251
    for (const auto& it : enumArray) {
252
        if (it->isCustom())
253
            return true;
254
    }
255
    return false;
256
}
257

258
Enumeration & Enumeration::operator=(const Enumeration &other)
259
{
260
    if (this == &other)
261
        return *this;
262

263
    enumArray = other.enumArray;
264
    _index = other._index;
265

266
    return *this;
267
}
268

269
bool Enumeration::operator==(const Enumeration &other) const
270
{
271
    if (_index != other._index || enumArray.size() != other.enumArray.size()) {
272
        return false;
273
    }
274
    for (size_t i = 0; i < enumArray.size(); ++i) {
275
        if (enumArray[i]->data() == other.enumArray[i]->data())
276
            continue;
277
        if (!enumArray[i]->data() || !other.enumArray[i]->data())
278
            return false;
279
        if (!enumArray[i]->isEqual(other.enumArray[i]->data()))
280
            return false;
281
    }
282
    return true;
283
}
284

285
bool Enumeration::operator==(const char *other) const
286
{
287
    if (!getCStr()) {
288
        return false;
289
    }
290

291
    return (strcmp(getCStr(), other) == 0);
292
}
293

294
int Enumeration::countItems() const
295
{
296
    return static_cast<int>(enumArray.size());
297
}
298

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.