API — ICoreEssentials/Containers
The public contract of 6 header(s) under src/ICoreEssentials/Containers — 6 class/struct definition(s), 64 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.
| Header | Defines | Declarations | Bases |
|---|---|---|---|
ICoreArray.h | ICoreArray | 9 | — |
ICoreHashMap.h | ICoreHashMap | 6 | — |
ICoreList.h | ICoreList | 6 | — |
ICoreSet.h | ICoreSet | 6 | — |
ICoreSortedMap.h | ICoreSortedMap | 6 | — |
ICoreVariant.h | ICoreVariant | 31 | — |
ICoreArray.h#
src/ICoreEssentials/Containers/ICoreArray.h
ICoreArray#
ICoreArray.h:11 · class · 9 declaration(s)
class ICoreArray {
public:
ICoreArray(const size_t r = 0, const size_t c = 0) : rows(r), cols(c), data(r * c) {}
std::vector<T> getAllEntriesAsList() const {
return data;
}
// Resize explicitly
void resize(const size_t r, const size_t c) {
grow(r, c);
}
// Safe setter/getter with auto-grow
T& operator()(const size_t i, size_t j) {
if (i >= rows || j >= cols) {
grow(std::max(rows, i + 1), std::max(cols, j + 1));
}
return data[i * cols + j];
}
const T& operator()(size_t i, size_t j) const {
return data[i * cols + j]; // assume valid for const
}
ICoreArray<T> slice(const size_t r1, const size_t r2, const size_t c1, const size_t c2) const {
ICoreArray<T> result(r2 - r1 + 1, c2 - c1 + 1);
for (size_t i = r1; i <= r2; ++i)
for (size_t j = c1; j <= c2; ++j)
result(i - r1, j - c1) = (*this)(i, j);
return result;
}
// Full row
ICoreArray<T> row(const size_t r) const {
return slice(r, r, 0, cols - 1);
}
// Full column
ICoreArray<T> col(const size_t c) const {
return slice(0, rows - 1, c, c);
}
ICoreArray<T> operator|(const ICoreArray<T>& other) const {
size_t newRows = std::max(rows, other.rows);
size_t newCols = cols + other.cols;
ICoreArray<T> result(newRows, newCols);
// copy left
for (size_t i = 0; i < rows; ++i)
for (size_t j = 0; j < cols; ++j)
result(i,j) = (*this)(i,j);
// copy right
for (size_t i = 0; i < other.rows; ++i)
for (size_t j = 0; j < other.cols; ++j)
result(i, j + cols) = other(i,j);
return result;
}
ICoreArray<T> operator&(const ICoreArray<T>& other) const {
size_t newRows = rows + other.rows;
size_t newCols = std::max(cols, other.cols);
ICoreArray<T> result(newRows, newCols);
// copy top
for (size_t i = 0; i < rows; ++i)
for (size_t j = 0; j < cols; ++j)
result(i,j) = (*this)(i,j);
// copy bottom
for (size_t i = 0; i < other.rows; ++i)
for (size_t j = 0; j < other.cols; ++j)
result(i + rows, j) = other(i,j);
return result;
}
size_t getRows() const { return rows; }
size_t getCols() const { return cols; }
};
};
ICoreHashMap.h#
src/ICoreEssentials/Containers/ICoreHashMap.h
ICoreHashMap -- the project's own unordered key/value map.
PHASE 1 (current): a thin value wrapper around QHash<K, V>. Every operation forwards. Phase 3 replaces the member with std::unordered_map<K, V>.
The conversion shape, the class-not-alias decision and the "Qt's operators are templates, so deduction ignores our conversions" argument are all derived at the top of ICoreList.h -- read that file first; this one only records what is different.
⚠ THIS WRAPPER FRONTS QHash ONLY. QMap IS NOT PART OF IT.
The README's wave-8 line and the plan's B24 row both said "ICoreHashMap -- wraps QHash, QMap", and B24 found that to be wrong in a way that would not
ICoreHashMap#
ICoreHashMap.h:52 · class · 6 declaration(s)
class ICoreHashMap {
public:
using key_type = K;
using mapped_type = V;
using iterator = typename QHash<K, V>::iterator;
using const_iterator = typename QHash<K, V>::const_iterator;
using size_type = qsizetype;
// --- construction ------------------------------------------------------
ICoreHashMap() = default;
ICoreHashMap(const ICoreHashMap&) = default;
ICoreHashMap(ICoreHashMap&&) noexcept = default;
ICoreHashMap& operator=(const ICoreHashMap&) = default;
ICoreHashMap& operator=(ICoreHashMap&&) noexcept = default;
~ICoreHashMap() = default;
ICoreHashMap(const QHash<K, V>& h) : m_h(h) {}
ICoreHashMap(QHash<K, V>&& h) noexcept : m_h(std::move(h)) {}
ICoreHashMap(std::initializer_list<std::pair<K, V>> items) : m_h(items) {}
template <class It, class = typename std::iterator_traits<It>::iterator_category>
ICoreHashMap(It first_, It last_) : m_h(first_, last_) {}
// --- interop with the Qt backing store ---------------------------------
operator const QHash<K, V>&() const noexcept { return m_h; }
const QHash<K, V>& toQHash() const noexcept { return m_h; }
// --- size and state ----------------------------------------------------
bool isEmpty() const noexcept { return m_h.isEmpty(); }
bool empty() const noexcept { return m_h.isEmpty(); }
qsizetype size() const noexcept { return m_h.size(); }
qsizetype count() const noexcept { return m_h.size(); }
void clear() { m_h.clear(); }
void reserve(qsizetype n) { m_h.reserve(n); }
void squeeze() { m_h.squeeze(); }
void detach() { m_h.detach(); }
// --- lookup ------------------------------------------------------------
bool contains(const K& key) const { return m_h.contains(key); }
V value(const K& key) const { return m_h.value(key); }
V value(const K& key, const V& fallback) const { return m_h.value(key, fallback); }
V& operator[](const K& key) { return m_h[key]; }
V operator[](const K& key) const { return m_h[key]; }
K key(const V& value) const { return m_h.key(value); }
K key(const V& value, const K& fallback) const { return m_h.key(value, fallback); }
qsizetype count(const K& key) const { return m_h.count(key); }
iterator find(const K& key) { return m_h.find(key); }
const_iterator find(const K& key) const { return m_h.find(key); }
const_iterator constFind(const K& key) const { return m_h.constFind(key); }
// keys() and values() hand back the WRAPPER, not QList -- otherwise every
// `hash.keys()` would put a Qt type back into a migrated file, which is
// exactly what the rename is for. This is why the umbrella must include
// ICoreList.h before this header.
ICoreList<K> keys() const { return ICoreList<K>(m_h.keys()); }
ICoreList<K> keys(const V& value) const { return ICoreList<K>(m_h.keys(value)); }
ICoreList<V> values() const { return ICoreList<V>(m_h.values()); }
// --- modification ------------------------------------------------------
iterator insert(const K& key, const V& value) { return m_h.insert(key, value); }
void insert(const ICoreHashMap& other) { m_h.insert(other.m_h); }
void insert(const QHash<K, V>& other) { m_h.insert(other); }
template <class... Args>
iterator emplace(const K& key, Args&&... args) { return m_h.emplace(key, std::forward<Args>(args)...); }
qsizetype remove(const K& key) { return m_h.remove(key); }
template <class Predicate>
qsizetype removeIf(Predicate pred) { return m_h.removeIf(pred); }
V take(const K& key) { return m_h.take(key); }
iterator erase(const_iterator pos) { return m_h.erase(pos); }
void swap(ICoreHashMap& other) noexcept { m_h.swap(other.m_h); }
// --- iteration ---------------------------------------------------------
iterator begin() { return m_h.begin(); }
iterator end() { return m_h.end(); }
const_iterator begin() const { return m_h.begin(); }
const_iterator end() const { return m_h.end(); }
const_iterator cbegin() const { return m_h.cbegin(); }
const_iterator cend() const { return m_h.cend(); }
const_iterator constBegin() const { return m_h.constBegin(); }
const_iterator constEnd() const { return m_h.constEnd(); }
auto keyBegin() const { return m_h.keyBegin(); }
auto keyEnd() const { return m_h.keyEnd(); }
auto keyValueBegin() { return m_h.keyValueBegin(); }
auto keyValueEnd() { return m_h.keyValueEnd(); }
auto keyValueBegin() const { return m_h.keyValueBegin(); }
auto keyValueEnd() const { return m_h.keyValueEnd(); }
auto asKeyValueRange() { return m_h.asKeyValueRange(); }
auto asKeyValueRange() const { return m_h.asKeyValueRange(); }
};
ICoreList.h#
src/ICoreEssentials/Containers/ICoreList.h
ICoreList -- the project's own sequence container.
PHASE 1 (current): a thin value wrapper around QList<T>. Every operation forwards. Phase 3 replaces the member with std::vector<T>; there is nothing in the API below that std::vector cannot carry, which is the point of keeping the surface small.
DESIGN NOTES -- read before changing anything, none of these was free.
- IT IS A CLASS TEMPLATE, NOT AN ALIAS -- and the placeholder this file
replaced said the opposite ("probably an alias rather than a class, QList is already std::vector-shaped in Qt 6"). That suggestion was measured and rejected, because
template <class T> using ICoreList = QList<T>is not a wrapper at all: it is the SAME type under a second
ICoreList#
ICoreList.h:73 · class · 6 declaration(s)
class ICoreList {
public:
using value_type = T;
using iterator = typename QList<T>::iterator;
using const_iterator = typename QList<T>::const_iterator;
using reference = T&;
using const_reference = const T&;
using size_type = qsizetype;
// --- construction ------------------------------------------------------
ICoreList() = default;
ICoreList(const ICoreList&) = default;
ICoreList(ICoreList&&) noexcept = default;
ICoreList& operator=(const ICoreList&) = default;
ICoreList& operator=(ICoreList&&) noexcept = default;
~ICoreList() = default;
// Implicit on purpose: lists arrive from Qt-declared API constantly
// (QHash::keys(), QWidget::actions(), QTreeWidget::selectedItems()), and
// an explicit constructor would turn every one of those into a cast.
ICoreList(const QList<T>& l) : m_l(l) {}
ICoreList(QList<T>&& l) noexcept : m_l(std::move(l)) {}
ICoreList(std::initializer_list<T> items) : m_l(items) {}
explicit ICoreList(qsizetype n) : m_l(n) {}
ICoreList(qsizetype n, const T& value) : m_l(n, value) {}
// CONSTRAINED, and it has to be -- see the H12 note at the foot of this
// file. An unconstrained `template <class It> ICoreList(It, It)` makes the
// wrapper constructible from ANY two arguments, which turns every
// `list.append({a, b})` into an ambiguity that the plain Qt type does not
// have. The iterator_category requirement removes it from consideration
// for anything that is not actually an iterator.
template <class It, class = typename std::iterator_traits<It>::iterator_category>
ICoreList(It first_, It last_) : m_l(first_, last_) {}
// --- interop with the Qt backing store ---------------------------------
operator const QList<T>&() const noexcept { return m_l; }
const QList<T>& toQList() const noexcept { return m_l; }
// --- size and state ----------------------------------------------------
bool isEmpty() const noexcept { return m_l.isEmpty(); }
bool empty() const noexcept { return m_l.isEmpty(); }
qsizetype size() const noexcept { return m_l.size(); }
qsizetype count() const noexcept { return m_l.size(); }
qsizetype length() const noexcept { return m_l.length(); }
void clear() { m_l.clear(); }
void reserve(qsizetype n) { m_l.reserve(n); }
void resize(qsizetype n) { m_l.resize(n); }
void resize(qsizetype n, const T& value) { m_l.resize(n, value); }
void squeeze() { m_l.squeeze(); }
void detach() { m_l.detach(); }
// --- element access ----------------------------------------------------
const T& at(qsizetype i) const { return m_l.at(i); }
T& operator[](qsizetype i) { return m_l[i]; }
const T& operator[](qsizetype i) const { return m_l[i]; }
T& first() { return m_l.first(); }
const T& first() const { return m_l.first(); }
T& last() { return m_l.last(); }
const T& last() const { return m_l.last(); }
const T& constFirst() const { return m_l.constFirst(); }
const T& constLast() const { return m_l.constLast(); }
T& front() { return m_l.front(); }
const T& front() const { return m_l.front(); }
T& back() { return m_l.back(); }
const T& back() const { return m_l.back(); }
T value(qsizetype i) const { return m_l.value(i); }
T value(qsizetype i, const T& fallback) const { return m_l.value(i, fallback); }
T* data() { return m_l.data(); }
const T* data() const { return m_l.data(); }
const T* constData() const { return m_l.constData(); }
// --- iteration ---------------------------------------------------------
iterator begin() { return m_l.begin(); }
iterator end() { return m_l.end(); }
const_iterator begin() const { return m_l.begin(); }
const_iterator end() const { return m_l.end(); }
const_iterator cbegin() const { return m_l.cbegin(); }
const_iterator cend() const { return m_l.cend(); }
const_iterator constBegin() const { return m_l.constBegin(); }
const_iterator constEnd() const { return m_l.constEnd(); }
auto rbegin() { return m_l.rbegin(); }
auto rend() { return m_l.rend(); }
auto rbegin() const { return m_l.rbegin(); }
auto rend() const { return m_l.rend(); }
// --- adding and removing -----------------------------------------------
void append(const T& v) { m_l.append(v); }
void append(T&& v) { m_l.append(std::move(v)); }
void append(const ICoreList& other) { m_l.append(other.m_l); }
void append(const QList<T>& other) { m_l.append(other); }
void prepend(const T& v) { m_l.prepend(v); }
void prepend(T&& v) { m_l.prepend(std::move(v)); }
void push_back(const T& v) { m_l.push_back(v); }
void push_back(T&& v) { m_l.push_back(std::move(v)); }
void push_front(const T& v) { m_l.push_front(v); }
void pop_back() { m_l.pop_back(); }
void pop_front() { m_l.pop_front(); }
template <class... Args>
T& emplaceBack(Args&&... args) { return m_l.emplaceBack(std::forward<Args>(args)...); }
template <class... Args>
T& emplace_back(Args&&... args) { return m_l.emplace_back(std::forward<Args>(args)...); }
void insert(qsizetype i, const T& v) { m_l.insert(i, v); }
iterator insert(const_iterator before, const T& v) { return m_l.insert(before, v); }
void removeAt(qsizetype i) { m_l.removeAt(i); }
qsizetype removeAll(const T& v) { return m_l.removeAll(v); }
bool removeOne(const T& v) { return m_l.removeOne(v); }
void removeFirst() { m_l.removeFirst(); }
void removeLast() { m_l.removeLast(); }
template <class Predicate>
qsizetype removeIf(Predicate pred) { return m_l.removeIf(pred); }
T takeAt(qsizetype i) { return m_l.takeAt(i); }
T takeFirst() { return m_l.takeFirst(); }
T takeLast() { return m_l.takeLast(); }
iterator erase(const_iterator pos) { return m_l.erase(pos); }
iterator erase(const_iterator first_, const_iterator last_) { return m_l.erase(first_, last_); }
void swapItemsAt(qsizetype i, qsizetype j) { m_l.swapItemsAt(i, j); }
void move(qsizetype from, qsizetype to) { m_l.move(from, to); }
void fill(const T& v) { m_l.fill(v); }
// --- searching ---------------------------------------------------------
bool contains(const T& v) const { return m_l.contains(v); }
qsizetype indexOf(const T& v, qsizetype from = 0) const { return m_l.indexOf(v, from); }
qsizetype lastIndexOf(const T& v, qsizetype from = -1) const { return m_l.lastIndexOf(v, from); }
qsizetype count(const T& v) const { return m_l.count(v); }
bool startsWith(const T& v) const { return m_l.startsWith(v); }
bool endsWith(const T& v) const { return m_l.endsWith(v); }
// --- slicing (returns the wrapper, so a chain never leaks Qt) ----------
ICoreList mid(qsizetype pos, qsizetype n = -1) const { return ICoreList(m_l.mid(pos, n)); }
ICoreList sliced(qsizetype pos) const { return ICoreList(m_l.sliced(pos)); }
ICoreList sliced(qsizetype pos, qsizetype n) const { return ICoreList(m_l.sliced(pos, n)); }
ICoreList first(qsizetype n) const { return ICoreList(m_l.first(n)); }
ICoreList last(qsizetype n) const { return ICoreList(m_l.last(n)); }
// --- compound operators (members, so they join no Qt overload set) ------
ICoreList& operator<<(const T& v) { m_l << v; return *this; }
ICoreList& operator<<(const ICoreList& other) { m_l << other.m_l; return *this; }
ICoreList& operator<<(const QList<T>& other) { m_l << other; return *this; }
ICoreList& operator+=(const T& v) { m_l += v; return *this; }
ICoreList& operator+=(const ICoreList& other) { m_l += other.m_l; return *this; }
ICoreList& operator+=(const QList<T>& other) { m_l += other; return *this; }
ICoreList operator+(const ICoreList& other) const { return ICoreList(m_l + other.m_l); }
void swap(ICoreList& other) noexcept { m_l.swap(other.m_l); }
};
ICoreSet.h#
src/ICoreEssentials/Containers/ICoreSet.h
ICoreSet -- the project's own unordered unique-element container.
PHASE 1 (current): a thin value wrapper around QSet<T>. Every operation forwards. Phase 3 replaces the member with std::unordered_set<T>.
The conversion shape and the class-not-alias decision are derived at the top of ICoreList.h; this header only records what is different.
WHAT THIS TYPE IS ACTUALLY FOR, measured rather than assumed: 38 of the project's 40 QSet occurrences are QSet<ICoreString>, and every one of them is a seen-set -- handles already emitted, names already taken, warnings already issued. The API below is sized for that: insert, contains, iterate, and the initialiser-list form the SimulinkBridge keyword tables use. Set ALGEBRA (unite/intersect/subtract) is forwarded because QSet has it, but no
ICoreSet#
ICoreSet.h:34 · class · 6 declaration(s)
class ICoreSet {
public:
using value_type = T;
using iterator = typename QSet<T>::iterator;
using const_iterator = typename QSet<T>::const_iterator;
using size_type = qsizetype;
// --- construction ------------------------------------------------------
ICoreSet() = default;
ICoreSet(const ICoreSet&) = default;
ICoreSet(ICoreSet&&) noexcept = default;
ICoreSet& operator=(const ICoreSet&) = default;
ICoreSet& operator=(ICoreSet&&) noexcept = default;
~ICoreSet() = default;
ICoreSet(const QSet<T>& s) : m_s(s) {}
ICoreSet(QSet<T>&& s) noexcept : m_s(std::move(s)) {}
ICoreSet(std::initializer_list<T> items) : m_s(items) {}
// Iterator-pair: ICoreRunDiagnosisPanel builds one straight out of a
// QTreeWidget selection this way.
template <class It, class = typename std::iterator_traits<It>::iterator_category>
ICoreSet(It first_, It last_) : m_s(first_, last_) {}
// --- interop with the Qt backing store ---------------------------------
operator const QSet<T>&() const noexcept { return m_s; }
const QSet<T>& toQSet() const noexcept { return m_s; }
// --- size and state ----------------------------------------------------
bool isEmpty() const noexcept { return m_s.isEmpty(); }
bool empty() const noexcept { return m_s.isEmpty(); }
qsizetype size() const noexcept { return m_s.size(); }
qsizetype count() const noexcept { return m_s.size(); }
void clear() { m_s.clear(); }
void reserve(qsizetype n) { m_s.reserve(n); }
void squeeze() { m_s.squeeze(); }
void detach() { m_s.detach(); }
// --- lookup ------------------------------------------------------------
bool contains(const T& v) const { return m_s.contains(v); }
bool contains(const ICoreSet& other) const { return m_s.contains(other.m_s); }
iterator find(const T& v) { return m_s.find(v); }
const_iterator find(const T& v) const { return m_s.find(v); }
const_iterator constFind(const T& v) const { return m_s.constFind(v); }
// Hands back the wrapper, not QList -- same reason as ICoreHashMap::keys().
ICoreList<T> values() const { return ICoreList<T>(m_s.values()); }
// --- modification ------------------------------------------------------
iterator insert(const T& v) { return m_s.insert(v); }
bool remove(const T& v) { return m_s.remove(v); }
template <class Predicate>
qsizetype removeIf(Predicate pred) { return m_s.removeIf(pred); }
iterator erase(const_iterator pos) { return m_s.erase(pos); }
void swap(ICoreSet& other) noexcept { m_s.swap(other.m_s); }
// --- set algebra (forwarded, currently unused -- see the header note) ---
ICoreSet& unite(const ICoreSet& other) { m_s.unite(other.m_s); return *this; }
ICoreSet& intersect(const ICoreSet& other) { m_s.intersect(other.m_s); return *this; }
ICoreSet& subtract(const ICoreSet& other) { m_s.subtract(other.m_s); return *this; }
bool intersects(const ICoreSet& other) const { return m_s.intersects(other.m_s); }
// --- iteration ---------------------------------------------------------
iterator begin() { return m_s.begin(); }
iterator end() { return m_s.end(); }
const_iterator begin() const { return m_s.begin(); }
const_iterator end() const { return m_s.end(); }
const_iterator cbegin() const { return m_s.cbegin(); }
const_iterator cend() const { return m_s.cend(); }
const_iterator constBegin() const { return m_s.constBegin(); }
const_iterator constEnd() const { return m_s.constEnd(); }
// --- compound operators (members, so they join no Qt overload set) ------
ICoreSet& operator<<(const T& v) { m_s << v; return *this; }
ICoreSet& operator+=(const ICoreSet& other) { m_s += other.m_s; return *this; }
ICoreSet& operator-=(const ICoreSet& other) { m_s -= other.m_s; return *this; }
ICoreSet& operator|=(const ICoreSet& other) { m_s |= other.m_s; return *this; }
ICoreSet& operator&=(const ICoreSet& other) { m_s &= other.m_s; return *this; }
};
ICoreSortedMap.h#
src/ICoreEssentials/Containers/ICoreSortedMap.h
ICoreSortedMap -- the project's own ORDERED key/value map.
PHASE 1 (current): a thin value wrapper around QMap<K, V>. Phase 3 replaces the member with std::map<K, V>, which has the same ordering guarantee.
WHY THIS TYPE EXISTS AT ALL -- it is not in the plan, and B24 added it.
The plan's B24 row and the README's wave-8 line both scheduled QMap to go behind ICoreHashMap alongside QHash. That is a silent behaviour change: QMap iterates in ascending key order, QHash's order is unspecified and salt-randomised per process. Phase 1 changes no behaviour, so they cannot share a wrapper.
And it would have mattered. QMap has exactly ONE call site --
ICoreSortedMap#
ICoreSortedMap.h:50 · class · 6 declaration(s)
class ICoreSortedMap {
public:
using key_type = K;
using mapped_type = V;
using iterator = typename QMap<K, V>::iterator;
using const_iterator = typename QMap<K, V>::const_iterator;
using size_type = qsizetype;
// --- construction ------------------------------------------------------
ICoreSortedMap() = default;
ICoreSortedMap(const ICoreSortedMap&) = default;
ICoreSortedMap(ICoreSortedMap&&) noexcept = default;
ICoreSortedMap& operator=(const ICoreSortedMap&) = default;
ICoreSortedMap& operator=(ICoreSortedMap&&) noexcept = default;
~ICoreSortedMap() = default;
ICoreSortedMap(const QMap<K, V>& m) : m_m(m) {}
ICoreSortedMap(QMap<K, V>&& m) noexcept : m_m(std::move(m)) {}
ICoreSortedMap(std::initializer_list<std::pair<K, V>> items) : m_m(items) {}
// --- interop with the Qt backing store ---------------------------------
operator const QMap<K, V>&() const noexcept { return m_m; }
const QMap<K, V>& toQMap() const noexcept { return m_m; }
// --- size and state ----------------------------------------------------
bool isEmpty() const noexcept { return m_m.isEmpty(); }
bool empty() const noexcept { return m_m.isEmpty(); }
qsizetype size() const noexcept { return m_m.size(); }
qsizetype count() const noexcept { return m_m.size(); }
void clear() { m_m.clear(); }
void detach() { m_m.detach(); }
// --- lookup ------------------------------------------------------------
bool contains(const K& key) const { return m_m.contains(key); }
V value(const K& key) const { return m_m.value(key); }
V value(const K& key, const V& fallback) const { return m_m.value(key, fallback); }
V& operator[](const K& key) { return m_m[key]; }
V operator[](const K& key) const { return m_m[key]; }
K key(const V& value) const { return m_m.key(value); }
K key(const V& value, const K& fallback) const { return m_m.key(value, fallback); }
iterator find(const K& key) { return m_m.find(key); }
const_iterator find(const K& key) const { return m_m.find(key); }
const_iterator constFind(const K& key) const { return m_m.constFind(key); }
// Hands back the wrapper, not QList -- same reason as ICoreHashMap::keys().
// Unlike QHash's, these two come back in ascending key order, which is the
// whole reason this type is separate.
ICoreList<K> keys() const { return ICoreList<K>(m_m.keys()); }
ICoreList<V> values() const { return ICoreList<V>(m_m.values()); }
K firstKey() const { return m_m.firstKey(); }
K lastKey() const { return m_m.lastKey(); }
// --- modification ------------------------------------------------------
iterator insert(const K& key, const V& value) { return m_m.insert(key, value); }
void insert(const ICoreSortedMap& other) { m_m.insert(other.m_m); }
qsizetype remove(const K& key) { return m_m.remove(key); }
template <class Predicate>
qsizetype removeIf(Predicate pred) { return m_m.removeIf(pred); }
V take(const K& key) { return m_m.take(key); }
iterator erase(const_iterator pos) { return m_m.erase(pos); }
void swap(ICoreSortedMap& other) noexcept { m_m.swap(other.m_m); }
// --- iteration (ascending by key -- the invariant this type exists for) -
iterator begin() { return m_m.begin(); }
iterator end() { return m_m.end(); }
const_iterator begin() const { return m_m.begin(); }
const_iterator end() const { return m_m.end(); }
const_iterator cbegin() const { return m_m.cbegin(); }
const_iterator cend() const { return m_m.cend(); }
const_iterator constBegin() const { return m_m.constBegin(); }
const_iterator constEnd() const { return m_m.constEnd(); }
auto keyBegin() const { return m_m.keyBegin(); }
auto keyEnd() const { return m_m.keyEnd(); }
auto keyValueBegin() { return m_m.keyValueBegin(); }
auto keyValueEnd() { return m_m.keyValueEnd(); }
auto keyValueBegin() const { return m_m.keyValueBegin(); }
auto keyValueEnd() const { return m_m.keyValueEnd(); }
auto asKeyValueRange() { return m_m.asKeyValueRange(); }
auto asKeyValueRange() const { return m_m.asKeyValueRange(); }
};
ICoreVariant.h#
src/ICoreEssentials/Containers/ICoreVariant.h
ICoreVariant#
ICoreVariant.h:63 · class · 31 declaration(s)
ICoreVariant -- a value of one of a handful of types, and the conversions between them.
class ICoreVariant {
public:
// ⚠ THE STORAGE IS AN OPAQUE BUFFER (H1.7, 2026-08-14): the tag, the three
// scalars and the ICoreString, held by value. A heap Impl would put a
// malloc on every settings read -- ICoreSettings::value() returns one BY
// VALUE and every `settings.value(k).toBool()` in ICoreUserPreferences
// builds one -- so this takes the small-value residue like the rest of the
// tier. Unlike ICorePoint and ICoreRect the state is NOT trivially
// copyable, because it holds an ICoreString, so all six special members are
// written out in the .cpp.
//
// The size is pinned by a static_assert against the real state, and the
// .cpp's comment records what it measured. Do not adjust it by arithmetic.
static constexpr std::size_t kNativeStorageSize = 48;
static constexpr std::size_t kNativeStorageAlign = 8;
ICoreVariant();
ICoreVariant(const ICoreVariant&);
ICoreVariant(ICoreVariant&&) noexcept;
ICoreVariant& operator=(const ICoreVariant&);
ICoreVariant& operator=(ICoreVariant&&) noexcept;
~ICoreVariant();
ICoreVariant(bool v);
ICoreVariant(int v);
ICoreVariant(unsigned v);
ICoreVariant(long v);
ICoreVariant(unsigned long v);
ICoreVariant(long long v);
ICoreVariant(unsigned long long v);
ICoreVariant(double v);
ICoreVariant(float v);
ICoreVariant(const ICoreString& v);
ICoreVariant(const char* v);
// --- extraction ---------------------------------------------------------
// The coercion table at the top of this file is the contract; the bodies
// that implement it are in ICoreVariant.cpp and every rule is commented
// there, beside the code rather than away from it.
[[nodiscard]] bool toBool() const;
[[nodiscard]] int toInt(bool* ok = nullptr) const;
[[nodiscard]] unsigned toUInt(bool* ok = nullptr) const;
[[nodiscard]] std::int64_t toLongLong(bool* ok = nullptr) const;
[[nodiscard]] std::uint64_t toULongLong(bool* ok = nullptr) const;
[[nodiscard]] double toDouble(bool* ok = nullptr) const;
[[nodiscard]] float toFloat(bool* ok = nullptr) const;
[[nodiscard]] ICoreString toString() const;
[[nodiscard]] bool isValid() const noexcept;
[[nodiscard]] bool isNull() const noexcept;
void clear();
void swap(ICoreVariant& other) noexcept;
bool operator==(const ICoreVariant& other) const;
bool operator!=(const ICoreVariant& other) const;
};