MyTetra Share
Делитесь знаниями!
Реализация класса OrderedMap на Qt (аналог QMap, только с доступом в последовательности создания элементов)
Время создания: 10.02.2026 09:41
Текстовые метки: qt, qt5, QMap, аналог, ordered, последовательность, создание, массив, ассоциативный, доступ, перебор, элемент
Раздел: Компьютер - Программирование - Язык C++ (Си++) - Библиотека Qt - Принципы написания кода
Запись: xintrea/mytetra_syncro/master/base/1770705714gulh6jaqwm/text.html на raw.githubusercontent.com

Заголовочный файл OrderedMap.h



#ifndef ORDEREDMAP_H

#define ORDEREDMAP_H


#include <QList>

#include <QHash>


// Вспомогательный класс, который является простым аналогом QMap

// только с доступом в последовательности добавления элементов



template<typename Key, typename Value>

class OrderedMap {


public:

// Конструкторы

OrderedMap();

OrderedMap(std::initializer_list<std::pair<Key, Value>> initList);


void insert(const Key& key, const Value& value);

Value value(const Key& key, const Value& defaultValue = Value()) const;

bool contains(const Key& key) const;

void remove(const Key& key);

void clear();

int size() const;

bool isEmpty() const;

QList<Key> keys() const;

QList<Value> values() const;


Value& operator[](const Key& key);

// const Value& operator[](const Key& key) const;

const Value& at(const Key& key) const; // Безопасный const-метод


// Класс const_iterator

class const_iterator {

private:

const OrderedMap* map;

int index;


public:

const_iterator(const OrderedMap* m, int i) : map(m), index(i) {}


// Оператор разыменования

const std::pair<Key, Value> operator*() const {

const Key& key = map->mapKeys[index];

return std::make_pair(key, map->mapValues.value(key));

}


// Оператор доступа к члену

const std::pair<Key, Value>* operator->() const {

// Для упрощения возвращаем временный объект

// В реальной реализации можно использовать указатель

static std::pair<Key, Value> temp;

temp = std::make_pair(map->mapKeys[index], map->mapValues.value(map->mapKeys[index]));

return &temp;

}


// Префиксный инкремент

const_iterator& operator++() {

++index;

return *this;

}


// Постфиксный инкремент

const_iterator operator++(int) {

const_iterator temp = *this;

++index;

return temp;

}


// Префиксный декремент

const_iterator& operator--() {

--index;

return *this;

}


// Постфиксный декремент

const_iterator operator--(int) {

const_iterator temp = *this;

--index;

return temp;

}


// Операторы сравнения

bool operator==(const const_iterator& other) const {

return map == other.map && index == other.index;

}


bool operator!=(const const_iterator& other) const {

return !(*this == other);

}


// Операторы отношения (для совместимости с STL)

bool operator<(const const_iterator& other) const {

return index < other.index;

}


bool operator<=(const const_iterator& other) const {

return index <= other.index;

}


bool operator>(const const_iterator& other) const {

return index > other.index;

}


bool operator>=(const const_iterator& other) const {

return index >= other.index;

}

};


// Методы для итераторов

const_iterator begin() const {

return const_iterator(this, 0);

}


const_iterator end() const {

return const_iterator(this, mapKeys.size());

}


const_iterator cbegin() const {

return const_iterator(this, 0);

}


const_iterator cend() const {

return const_iterator(this, mapKeys.size());

}


// Поиск по ключу

const_iterator find(const Key& key) const {

int index = mapKeys.indexOf(key);

if (index != -1) {

return const_iterator(this, index);

}

return end();

}


// Первый и последний элементы

const_iterator first() const {

return isEmpty() ? end() : const_iterator(this, 0);

}


const_iterator last() const {

return isEmpty() ? end() : const_iterator(this, mapKeys.size() - 1);

}


private:

QList<Key> mapKeys;

QHash<Key, Value> mapValues;


};



// Явное инстанцирование для используемых типов

extern template class OrderedMap<QString, int>;

extern template class OrderedMap<QString, QString>;

extern template class OrderedMap<QString, double>;

extern template class OrderedMap<QString, QPair<QString, float> >;



#endif // ORDEREDMAP_H



Файл реализации OrderedMap.cpp



#include "OrderedMap.h"



template<typename Key, typename Value>

OrderedMap<Key, Value>::OrderedMap() = default;


template<typename Key, typename Value>

OrderedMap<Key, Value>::OrderedMap(std::initializer_list<std::pair<Key, Value>> initList) {

for (const auto& pair : initList) {

insert(pair.first, pair.second);

}

}


// Вставка элемента

template<typename Key, typename Value>

void OrderedMap<Key, Value>::insert(const Key& key, const Value& value) {

if (!mapValues.contains(key)) {

mapKeys.append(key);

}

mapValues[key] = value;

}


// Получение значения по ключу

template<typename Key, typename Value>

Value OrderedMap<Key, Value>::value(const Key& key, const Value& defaultValue) const {

return mapValues.value(key, defaultValue);

}


// Проверка наличия ключа

template<typename Key, typename Value>

bool OrderedMap<Key, Value>::contains(const Key& key) const {

return mapValues.contains(key);

}


// Удаление элемента

template<typename Key, typename Value>

void OrderedMap<Key, Value>::remove(const Key& key) {

if (mapValues.contains(key)) {

mapValues.remove(key);

mapKeys.removeAll(key);

}

}


// Очистка

template<typename Key, typename Value>

void OrderedMap<Key, Value>::clear() {

mapKeys.clear();

mapValues.clear();

}


// Размер

template<typename Key, typename Value>

int OrderedMap<Key, Value>::size() const {

return mapKeys.size();

}


// Проверка что объект пустой (не содержит элементов)

template<typename Key, typename Value>

bool OrderedMap<Key, Value>::isEmpty() const {

return mapKeys.isEmpty();

}


// Получение списка ключей в порядке добавления

template<typename Key, typename Value>

QList<Key> OrderedMap<Key, Value>::keys() const {

return mapKeys;

}


// Получение списка значений в порядке добавления

template<typename Key, typename Value>

QList<Value> OrderedMap<Key, Value>::values() const {

QList<Value> result;

for (const Key& key : mapKeys) {

result.append(mapValues.value(key));

}

return result;

}


// Оператор доступа

template<typename Key, typename Value>

Value& OrderedMap<Key, Value>::operator[](const Key& key) {

if (!mapValues.contains(key)) {

mapKeys.append(key);

}

return mapValues[key];

}


// Const оператор доступа

/*

template<typename Key, typename Value>

const Value& OrderedMap<Key, Value>::operator[](const Key& key) const {

return mapValues[key];

}

*/


template<typename Key, typename Value>

const Value& OrderedMap<Key, Value>::at(const Key& key) const {

auto it = mapValues.find(key);

if (it == mapValues.end()) {

throw std::out_of_range("Key not found in OrderedMap");

}

return it.value();

}


// Явное инстанцирование для конкретных типов

template class OrderedMap<QString, int>;

template class OrderedMap<QString, QString>;

template class OrderedMap<QString, double>;

template class OrderedMap<QString, QPair<QString, float> >;





Так же в этом разделе:
 
MyTetra Share v.0.67
Яндекс индекс цитирования