Advertisement
Guest User

Untitled

a guest
Dec 7th, 2016
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.50 KB | None | 0 0
  1. #ifndef AISDI_MAPS_HASHMAP_H
  2. #define AISDI_MAPS_HASHMAP_H
  3. #include "TreeMap.h"
  4. #include <cstddef>
  5. #include <initializer_list>
  6. #include <stdexcept>
  7. #include <utility>
  8. #include <list>
  9. #include <array>
  10. #include <iterator>
  11.  
  12. #define ARRAY_SIZE 1024
  13.  
  14. namespace aisdi {
  15.  
  16.     template<typename KeyType, typename ValueType>
  17.     class HashMap {
  18.     public:
  19.         using key_type = KeyType;
  20.         using mapped_type = ValueType;
  21.         using value_type = std::pair<const key_type, mapped_type>;
  22.         using size_type = std::size_t;
  23.         using reference = value_type &;
  24.         using const_reference = const value_type &;
  25.  
  26.         class ConstIterator;
  27.         class Iterator;
  28.         class List;
  29.         struct BaseNode;
  30.         struct Node;
  31.         friend class List;
  32.         friend class ConstIterator;
  33.  
  34.         friend class Iterator;
  35.  
  36.         using iterator = Iterator;
  37.         using const_iterator = ConstIterator;
  38.  
  39.         HashMap():count(0) {}
  40.  
  41.         HashMap(std::initializer_list<value_type> list) {
  42.             (void) list; // disables "unused argument" warning, can be removed when method is implemented.
  43.            // throw std::runtime_error("TODO");
  44.         }
  45.  
  46.         HashMap(const HashMap &other) {
  47.             (void) other;
  48.          //   throw std::runtime_error("TODO");
  49.         }
  50.  
  51.         HashMap(HashMap &&other) {
  52.             (void) other;
  53.          //   throw std::runtime_error("TODO");
  54.         }
  55.  
  56.         HashMap &operator=(const HashMap &other) {
  57.             (void) other;
  58.            // throw std::runtime_error("TODO");
  59.         }
  60.  
  61.         HashMap &operator=(HashMap &&other) {
  62.             (void) other;
  63.            // throw std::runtime_error("TODO");
  64.         }
  65.  
  66.         bool isEmpty() const {
  67.             return count == 0;
  68.         }
  69.  
  70.         mapped_type &operator[](const key_type &key) {
  71.             size_t index = get_index(key);
  72.             Node *found;
  73.             found = array[index].find(key);
  74.             if( !found ){
  75.                 array[index].append(key, ValueType());
  76.                 ++count;
  77.                 found = array[index].find(key);
  78.                 return found->item.second;
  79.             }else{
  80.                 return found->item.second;
  81.             }
  82.         }
  83.  
  84.         const mapped_type &valueOf(const key_type &key) const {
  85.             (void) key;
  86.         //    throw std::runtime_error("TODO");
  87.         }
  88.  
  89.         mapped_type &valueOf(const key_type &key) {
  90.             (void) key;
  91.         //    throw std::runtime_error("TODO");
  92.         }
  93.  
  94.         const_iterator find(const key_type &key) const {
  95.             (void) key;
  96.        //     throw std::runtime_error("TODO");
  97.         }
  98.  
  99.         iterator find(const key_type &key) {
  100.             (void) key;
  101.             throw std::runtime_error("TODO");
  102.         }
  103.  
  104.         void remove(const key_type &key) {
  105.             (void) key;
  106.        //     throw std::runtime_error("TODO");
  107.         }
  108.  
  109.         void remove(const const_iterator &it) {
  110.             (void) it;
  111.        //     throw std::runtime_error("TODO");
  112.         }
  113.  
  114.         size_type getSize() const {
  115.     //        throw std::runtime_error("TODO");
  116.             return count;
  117.         }
  118.  
  119.         bool operator==(const HashMap &other) const {
  120.             (void) other;
  121.         //    throw std::runtime_error("TODO");
  122.             return true;
  123.         }
  124.  
  125.         bool operator!=(const HashMap &other) const {
  126.             return !(*this == other);
  127.         }
  128.  
  129.         iterator begin() {
  130.             return Iterator(this, 0, array[0].head->next);
  131.         }
  132.  
  133.         iterator end() {
  134.             BaseNode *result = NULL;
  135.             size_t last_used_index = 0;
  136.             for(size_t i = 0; i < ARRAY_SIZE; i++){
  137.                 if(array[i].size != 0) last_used_index = i;
  138.             }
  139.             result = array[last_used_index].tail;
  140.             return Iterator(this, last_used_index, result);
  141.         }
  142.  
  143.         const_iterator cbegin() const {
  144.             return ConstIterator(this, 0, array[0].head->next);
  145.         }
  146.  
  147.         const_iterator cend() const {
  148.             BaseNode *result = NULL;
  149.             size_t last_used_index = 0;
  150.             for(size_t i = 0; i < ARRAY_SIZE; i++){
  151.                 if(array[i].size != 0) last_used_index = i;
  152.             }
  153.             result = array[last_used_index].tail;
  154.             return ConstIterator(this, last_used_index, result);
  155.         }
  156.  
  157.         const_iterator begin() const {
  158.             return cbegin();
  159.         }
  160.  
  161.         const_iterator end() const {
  162.             return cend();
  163.         }
  164.  
  165.     protected:
  166.         List array[ARRAY_SIZE];
  167.         size_t count;
  168.  
  169.         size_t get_index(const key_type &key) {
  170.             std::hash<KeyType> h;
  171.             return (h(key) % ARRAY_SIZE);
  172.         }
  173.  
  174.     };
  175.  
  176.     template<typename KeyType, typename ValueType>
  177.     class HashMap<KeyType, ValueType>::ConstIterator {
  178.     public:
  179.         using reference = typename HashMap::const_reference;
  180.         using iterator_category = std::bidirectional_iterator_tag;
  181.         using value_type = typename HashMap::value_type;
  182.         using pointer = const typename HashMap::value_type *;
  183.  
  184.         friend class HashMap;
  185.  
  186.         explicit ConstIterator(const HashMap *mmap, size_t tindex, BaseNode *tnode):
  187.                 map(mmap), index(tindex), node(tnode){}
  188.  
  189.         ConstIterator(const ConstIterator &other) {
  190.             (void) other;
  191.            // throw std::runtime_error("TODO");
  192.         }
  193.  
  194.         ConstIterator &operator++() {
  195.             if(node == map->end().node)throw std::out_of_range("Trying to increment end()");
  196.             if(node->next == map->array[index].tail){
  197.                 size_t next_index = index;
  198.                 for(; next_index < ARRAY_SIZE; ++next_index){
  199.                     if(map->array[next_index].size != 0) break;
  200.                 }
  201.                 if(index != next_index){
  202.                     index = next_index;
  203.                     node = map->array[index].head;
  204.                 }
  205.                 else{
  206.                     node = node->next; //Powinno przejść na end().node
  207.                 }
  208.             }else{
  209.                 node = node->next;
  210.             }
  211.             return *this;
  212.         }
  213.  
  214.         ConstIterator operator++(int) {
  215.             ConstIterator result(*this);
  216.             if(node == map->end().node)throw std::out_of_range("Trying to increment end()");
  217.             if(node->next == map->array[index].tail){
  218.                 size_t next_index = index;
  219.                 for(; next_index < ARRAY_SIZE; ++next_index){
  220.                     if(map->array[next_index].size != 0) break;
  221.                 }
  222.                 if(index != next_index){
  223.                     index = next_index;
  224.                     node = map->array[index].head;
  225.                 }
  226.                 else{
  227.                     node = node->next; //Powinno przejść na end().node
  228.                 }
  229.             }else{
  230.                 node = node->next;
  231.             }
  232.             return result;
  233.         }
  234.  
  235.         ConstIterator &operator--() {
  236.          //   throw std::runtime_error("TODO");
  237.         }
  238.  
  239.         ConstIterator operator--(int) {
  240.         //    throw std::runtime_error("TODO");
  241.         }
  242.  
  243.         reference operator*() const {
  244.            if( node == map->array[index].head || node == map->array[index].tail) throw std::out_of_range("Trying to dereference outside of scope.");
  245.             else return static_cast<Node *>(node)->item;
  246.         }
  247.  
  248.         pointer operator->() const {
  249.             return &this->operator*();
  250.         }
  251.  
  252.         bool operator==(const ConstIterator &other) const {
  253.             return ((this->map == other.map)&&(this->index == other.index)&&(this->node == other.node));
  254.         }
  255.  
  256.         bool operator!=(const ConstIterator &other) const {
  257.             return !(*this == other);
  258.         }
  259.  
  260.     protected:
  261.         const HashMap *map;
  262.         size_t index;
  263.         BaseNode *node;
  264.     };
  265.  
  266.     template<typename KeyType, typename ValueType>
  267.     class HashMap<KeyType, ValueType>::Iterator : public HashMap<KeyType, ValueType>::ConstIterator {
  268.     public:
  269.         using reference = typename HashMap::reference;
  270.         using pointer = typename HashMap::value_type *;
  271.  
  272.         friend class HashMap;
  273.  
  274.         explicit Iterator(const HashMap *mmap, size_t tindex, BaseNode *node):ConstIterator(mmap, tindex, node){}
  275.  
  276.         Iterator(const ConstIterator &other)
  277.                 : ConstIterator(other) {}
  278.  
  279.         Iterator &operator++() {
  280.             ConstIterator::operator++();
  281.             return *this;
  282.         }
  283.  
  284.         Iterator operator++(int) {
  285.             auto result = *this;
  286.             ConstIterator::operator++();
  287.             return result;
  288.         }
  289.  
  290.         Iterator &operator--() {
  291.             ConstIterator::operator--();
  292.             return *this;
  293.         }
  294.  
  295.         Iterator operator--(int) {
  296.             auto result = *this;
  297.             ConstIterator::operator--();
  298.             return result;
  299.         }
  300.  
  301.         pointer operator->() const {
  302.             return &this->operator*();
  303.         }
  304.  
  305.         reference operator*() const {
  306.             // ugly cast, yet reduces code duplication.
  307.             return const_cast<reference>(ConstIterator::operator*());
  308.         }
  309.     };
  310.  
  311.     template<typename KeyType, typename ValueType>
  312.     class HashMap<KeyType, ValueType>::List {
  313.     friend class HashMap;
  314.     public:
  315.         List() {
  316.             head = new BaseNode(nullptr, nullptr);
  317.             tail = new BaseNode(nullptr, nullptr);
  318.             head->next = tail;
  319.             tail->previous = head;
  320.             size = 0;
  321.         }
  322.         Node * find(const KeyType key){
  323.             BaseNode *result;
  324.             result = head;
  325.             while(result != tail){
  326.                 if(static_cast<Node *>(result)->item .first == key){
  327.                     return static_cast<Node *>(result);
  328.                 };
  329.                 result = result->next;
  330.             }
  331.             return NULL;
  332.         }
  333.         void append(const KeyType &key, const ValueType &item) {
  334.             BaseNode *newNode = new Node(tail->previous, tail, key, item);
  335.             tail->previous->next = newNode;
  336.             tail->previous = newNode;
  337.             size++;
  338.         }
  339.     protected:
  340.         BaseNode *head;
  341.         BaseNode *tail;
  342.         size_type size;
  343.     };
  344.  
  345.     template<typename KeyType, typename ValueType>
  346.     struct HashMap<KeyType, ValueType>::BaseNode {
  347.         BaseNode *next;
  348.         BaseNode *previous;
  349.  
  350.         BaseNode() {
  351.             next = nullptr;
  352.             previous = nullptr;
  353.         }
  354.  
  355.         BaseNode(BaseNode *prev, BaseNode *nxt) {
  356.             previous = prev;
  357.             next = nxt;
  358.         }
  359.  
  360.         virtual ~BaseNode() {
  361.             previous = nullptr;
  362.             next = nullptr;
  363.         }
  364.     };
  365.  
  366.     template<typename KeyType, typename ValueType>
  367.     struct HashMap<KeyType, ValueType>::Node : public HashMap<KeyType, ValueType>::BaseNode {
  368.         std::pair<KeyType, ValueType> item;
  369.  
  370.         Node() : BaseNode() {
  371.             item.first = nullptr;
  372.             item.second = nullptr;
  373.         }
  374.  
  375.         Node(BaseNode *prev, BaseNode *nxt, const KeyType &key, const ValueType &value) : BaseNode(prev, nxt) {
  376.             item.first = key;
  377.             item.second = value;
  378.         }
  379.  
  380.         Node(BaseNode *prev, BaseNode *nxt, KeyType &&key, ValueType &&value) : BaseNode(prev, nxt) {
  381.             item.first = std::move(key);
  382.             item = std::move(value);
  383.         }
  384.  
  385.         ~Node() {}
  386.     };
  387. }
  388.  
  389. #endif /* AISDI_MAPS_HASHMAP_H */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement