32 values (other.values),
33 ignoreCase (other.ignoreCase)
40 values = other.values;
48 if (num != other.size())
51 for (
int i = 0; i < num; ++i)
53 if (keys[i] == other.keys[i])
55 if (values[i] != other.values[i])
61 for (
int j = i; j < num; ++j)
63 auto otherIndex = other.keys.indexOf (keys[j], other.ignoreCase);
65 if (otherIndex < 0 || values[j] != other.values[otherIndex])
83 return values[keys.
indexOf (key, ignoreCase)];
88 auto i = keys.
indexOf (key, ignoreCase);
93 return defaultReturnValue;
98 return keys.contains (key, ignoreCase);
103 auto i = keys.
indexOf (key, ignoreCase);
107 values.
set (i, value);
118 for (
int i = 0; i < other.size(); ++i)
119 set (other.keys[i], other.values[i]);
141 ignoreCase = shouldIgnoreCase;
153 for (
int i = 0; i < keys.
size(); ++i)
155 s << keys[i] <<
" = " << values[i];
170template <
typename Map>
171void StringPairArray::addMapImpl (
const Map& toAdd)
177 std::map<String, int> contents;
179 const auto normaliseKey = [
this] (
const String& key)
181 return ignoreCase ? key.toLowerCase() : key;
184 for (
auto i = 0; i !=
size(); ++i)
185 contents.emplace (normaliseKey (
getAllKeys().getReference (i)), i);
187 for (
const auto& pair : toAdd)
189 const auto key = normaliseKey (pair.first);
190 const auto it = contents.find (key);
192 if (it != contents.cend())
198 contents.emplace (key,
static_cast<int> (contents.size()));
199 keys.
add (pair.first);
200 values.
add (pair.second);
212static String operator""_S (
const char* chars,
size_t)
217class StringPairArrayTests final :
public UnitTest
220 StringPairArrayTests()
221 : UnitTest (
"StringPairArray", UnitTestCategories::text)
224 void runTest()
override
226 beginTest (
"addMap respects case sensitivity of StringPairArray");
228 StringPairArray insensitive {
true };
229 insensitive.addMap ({ {
"duplicate",
"a" },
230 {
"Duplicate",
"b" } });
232 expect (insensitive.size() == 1);
233 expectEquals (insensitive[
"DUPLICATE"],
"a"_S);
235 StringPairArray sensitive {
false };
236 sensitive.addMap ({ {
"duplicate",
"a"_S },
237 {
"Duplicate",
"b"_S } });
239 expect (sensitive.size() == 2);
240 expectEquals (sensitive[
"duplicate"],
"a"_S);
241 expectEquals (sensitive[
"Duplicate"],
"b"_S);
242 expectEquals (sensitive[
"DUPLICATE"],
""_S);
245 beginTest (
"addMap overwrites existing pairs");
247 StringPairArray insensitive {
true };
248 insensitive.set (
"key",
"value");
249 insensitive.addMap ({ {
"KEY",
"VALUE" } });
251 expect (insensitive.size() == 1);
252 expectEquals (insensitive.getAllKeys()[0],
"key"_S);
253 expectEquals (insensitive.getAllValues()[0],
"VALUE"_S);
255 StringPairArray sensitive {
false };
256 sensitive.set (
"key",
"value");
257 sensitive.addMap ({ {
"KEY",
"VALUE" },
258 {
"key",
"another value" } });
260 expect (sensitive.size() == 2);
261 expect (sensitive.getAllKeys() == StringArray {
"key",
"KEY" });
262 expect (sensitive.getAllValues() == StringArray {
"another value",
"VALUE" });
265 beginTest (
"addMap doesn't change the order of existing keys");
267 StringPairArray array;
268 array.set (
"a",
"a");
269 array.set (
"z",
"z");
270 array.set (
"b",
"b");
271 array.set (
"y",
"y");
272 array.set (
"c",
"c");
274 array.addMap ({ {
"B",
"B" },
278 expect (array.getAllKeys() == StringArray {
"a",
"z",
"b",
"y",
"c",
"0" });
279 expect (array.getAllValues() == StringArray {
"a",
"Z",
"B",
"y",
"c",
"0" });
282 beginTest (
"addMap has equivalent behaviour to addArray");
284 StringPairArray initial;
285 initial.set (
"aaa",
"aaa");
286 initial.set (
"zzz",
"zzz");
287 initial.set (
"bbb",
"bbb");
289 auto withAddMap = initial;
290 withAddMap.addMap ({ {
"ZZZ",
"ZZZ" },
293 auto withAddArray = initial;
294 withAddArray.addArray ([]
296 StringPairArray toAdd;
297 toAdd.set (
"ZZZ",
"ZZZ");
298 toAdd.set (
"ddd",
"ddd");
302 expect (withAddMap == withAddArray);
307static StringPairArrayTests stringPairArrayTests;
String & getReference(int index) noexcept
int indexOf(StringRef stringToLookFor, bool ignoreCase=false, int startIndex=0) const
void minimiseStorageOverheads()
int size() const noexcept
void add(String stringToAdd)
void set(int index, String newString)
void setIgnoresCase(bool shouldIgnoreCase)
String getValue(StringRef, const String &defaultReturnValue) const
StringPairArray & operator=(const StringPairArray &other)
bool containsKey(StringRef key) const noexcept
void set(const String &key, const String &value)
String getDescription() const
void remove(StringRef key)
StringPairArray(bool ignoreCaseWhenComparingKeys=true)
bool getIgnoresCase() const noexcept
const String & operator[](StringRef key) const
bool operator!=(const StringPairArray &other) const
void minimiseStorageOverheads()
void addMap(const std::map< String, String > &mapToAdd)
void addArray(const StringPairArray &other)
void addUnorderedMap(const std::unordered_map< String, String > &mapToAdd)
int size() const noexcept
bool operator==(const StringPairArray &other) const
const StringArray & getAllKeys() const noexcept