Advertisement
ArinaRaguzina

Untitled

Nov 22nd, 2019
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 32.70 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <functional>
  4. #include <memory>
  5. #include <utility>
  6. #include <type_traits>
  7. #include <vector>
  8.  
  9. namespace fefu
  10. {
  11.    
  12.     template<typename T>
  13.     class allocator {
  14.     public:
  15.         using size_type = std::size_t;
  16.         using difference_type = std::ptrdiff_t;
  17.         using pointer = T*;
  18.         using const_pointer = const T*;
  19.         using reference = typename std::add_lvalue_reference<T>::type;
  20.         using const_reference = typename std::add_lvalue_reference<const T>::type;
  21.         using value_type = T;
  22.  
  23.         allocator() noexcept = default;
  24.  
  25.         allocator(const allocator&) noexcept = default;
  26.  
  27.         template <class U>
  28.         allocator(const allocator<U>&) noexcept {};
  29.  
  30.         ~allocator() = default;
  31.  
  32.         pointer allocate(size_type size) {
  33.             auto p = ::operator new(size * sizeof(value_type));
  34.  
  35.             return static_cast<pointer>(p);
  36.         };
  37.  
  38.         void deallocate(pointer p, size_type n) noexcept {
  39.             ::operator delete (p, n);
  40.         };
  41.     private:
  42.     };
  43.     template<typename ValueType>
  44.     class Node {
  45.     public:
  46.         using value_type = ValueType*;
  47.         enum  State
  48.         {
  49.             Empty = 0,
  50.             Full = 1,
  51.             END = 2
  52.         };
  53.         value_type val;
  54.         State state;      
  55.     };
  56.     template<typename ValueType>
  57.     class hash_map_iterator {
  58.     public:
  59.         using iterator_category = std::forward_iterator_tag;
  60.         using value_type = ValueType;
  61.         using difference_type = std::ptrdiff_t;
  62.         using reference = ValueType&;
  63.         using pointer = ValueType*;
  64.  
  65.         template<typename K, typename T,
  66.             typename Hash = std::hash<K>,
  67.             typename Pred = std::equal_to<K>,
  68.             typename Alloc = allocator<std::pair<const K, T>>>
  69.             friend class hash_map;
  70.  
  71.         //friend class hash_map;
  72.         hash_map_iterator() noexcept = default;
  73.         hash_map_iterator(const hash_map_iterator& other) noexcept : ptr(other.ptr) {};
  74.  
  75.         reference operator*() const {
  76.             return (*ptr);
  77.         };
  78.         pointer operator->() const {
  79.             return (ptr);
  80.         };
  81.  
  82.         // prefix ++
  83.         hash_map_iterator& operator++() {
  84.             //hash_map_iterator new_ptr = hash_map_iterator();
  85.             //new_ptr.size = size;
  86.             //new_ptr.set = set;
  87.             //difference_type index = 0;
  88.  
  89.             //if (size == 0)
  90.             //    throw (std::exception("Hash_mapIsEmpty"));
  91.             //while (set[index] == 0) {
  92.             //    index++;
  93.             //    if (index > size - 1)
  94.             //        throw (std::exception("Overload"));
  95.             //}
  96.             //ptr = ptr[index];
  97.             ptr++;
  98.             return *this;
  99.         };
  100.         // postfix ++
  101.         hash_map_iterator operator++(int) {
  102.             hash_map_iterator new_ptr = hash_map_iterator(*this);
  103.             ptr++;
  104.             return new_ptr;
  105.         };
  106.  
  107.         friend bool operator==(const hash_map_iterator<ValueType>&, const hash_map_iterator<ValueType>&);
  108.         friend bool operator!=(const hash_map_iterator<ValueType>&, const hash_map_iterator<ValueType>&);
  109.     private:
  110.         hash_map_iterator(Node* _new_ptr): ptr(_new_ptr) {};
  111.         Node* ptr;
  112.     };
  113.  
  114.     template<typename ValueType>
  115.     class hash_map_const_iterator {
  116.         // Shouldn't give non const references on value
  117.     public:
  118.         using iterator_category = std::forward_iterator_tag;
  119.         using value_type = ValueType;
  120.         using difference_type = std::ptrdiff_t;
  121.         using reference = const ValueType&;
  122.         using pointer = const ValueType*;
  123.  
  124.         hash_map_const_iterator() noexcept;
  125.         hash_map_const_iterator(const hash_map_const_iterator& other) noexcept;
  126.         hash_map_const_iterator(const hash_map_iterator<ValueType>& other) noexcept;
  127.  
  128.         reference operator*() const;
  129.         pointer operator->() const;
  130.  
  131.         // prefix ++
  132.         hash_map_const_iterator& operator++();
  133.         // postfix ++
  134.         hash_map_const_iterator operator++(int);
  135.  
  136.         friend bool operator==(const hash_map_const_iterator<ValueType>&, const hash_map_const_iterator<ValueType>&);
  137.         friend bool operator!=(const hash_map_const_iterator<ValueType>&, const hash_map_const_iterator<ValueType>&);
  138.     private:
  139.         hash_map_const_iterator(Node* _new_ptr) : ptr(_new_ptr) {}
  140.         Node* ptr;
  141.  
  142.     };
  143.     template<typename K, typename T,
  144.         typename Hash = std::hash<K>,
  145.         typename Pred = std::equal_to<K>,
  146.         typename Alloc = allocator<std::pair<const K, T>>>
  147.         class hash_map {
  148.         public:
  149.             using key_type = K;
  150.             using mapped_type = T;
  151.             using hasher = Hash;
  152.             using key_equal = Pred;
  153.             using allocator_type = Alloc;
  154.             using value_type = std::pair<const key_type, mapped_type>;
  155.             using reference = value_type&;
  156.             using const_reference = const value_type&;
  157.             using iterator = hash_map_iterator<value_type>;
  158.             using const_iterator = hash_map_const_iterator<value_type>;
  159.             using size_type = std::size_t;
  160.  
  161.  
  162.             /// Default constructor.
  163.             hash_map() = default;
  164.  
  165.             /**
  166.              *  @brief  Default constructor creates no elements.
  167.              *  @param n  Minimal initial number of buckets.
  168.              */
  169.             explicit hash_map(size_type n) :
  170.                 m_data(m_allocator.allocate(n)),
  171.                 m_size(n)
  172.             {
  173.                 m_node.resize(n + 1);
  174.                 for (int i = 0; i < n; i++) {
  175.                     m_node[i].val = m_data + i;
  176.                     m_node[i].state = Empty;
  177.                 }
  178.                 m_node[n].state = END;
  179.             }
  180.  
  181.  
  182.             /**
  183.              *  @brief  Builds an %hash_map from a range.
  184.              *  @param  first  An input iterator.
  185.              *  @param  last  An input iterator.
  186.              *  @param  n  Minimal initial number of buckets.
  187.              *
  188.              *  Create an %hash_map consisting of copies of the elements from
  189.              *  [first,last).  This is linear in N (where N is
  190.              *  distance(first,last)).
  191.              */
  192.             template<typename InputIterator>
  193.             hash_map(InputIterator first, InputIterator last,
  194.                 size_type n = 0);
  195.  
  196.             /// Copy constructor.
  197.             hash_map(const hash_map&) {
  198.                 hash_map new_hash;
  199.             };
  200.  
  201.             /// Move constructor.
  202.             hash_map(hash_map&& x) {
  203.                 swap();
  204.             };
  205.  
  206.             /**
  207.              *  @brief Creates an %hash_map with no elements.
  208.              *  @param a An allocator object.
  209.              */
  210.             explicit hash_map(const allocator_type& a);
  211.  
  212.             /*
  213.             *  @brief Copy constructor with allocator argument.
  214.             * @param  uset  Input %hash_map to copy.
  215.             * @param  a  An allocator object.
  216.             */
  217.             hash_map(const hash_map& umap,
  218.                 const allocator_type& a);
  219.  
  220.             /*
  221.             *  @brief  Move constructor with allocator argument.
  222.             *  @param  uset Input %hash_map to move.
  223.             *  @param  a    An allocator object.
  224.             */
  225.             hash_map(hash_map&& umap,
  226.                 const allocator_type& a);
  227.  
  228.             /**
  229.              *  @brief  Builds an %hash_map from an initializer_list.
  230.              *  @param  l  An initializer_list.
  231.              *  @param n  Minimal initial number of buckets.
  232.              *
  233.              *  Create an %hash_map consisting of copies of the elements in the
  234.              *  list. This is linear in N (where N is @a l.size()).
  235.              */
  236.             hash_map(std::initializer_list<value_type> l,
  237.                 size_type n = 0);
  238.  
  239.             /// Copy assignment operator.
  240.             hash_map& operator=(const hash_map&);
  241.  
  242.             /// Move assignment operator.
  243.             hash_map& operator=(hash_map&&);
  244.  
  245.             /**
  246.              *  @brief  %hash_map list assignment operator.
  247.              *  @param  l  An initializer_list.
  248.              *
  249.              *  This function fills an %hash_map with copies of the elements in
  250.              *  the initializer list @a l.
  251.              *
  252.              *  Note that the assignment completely changes the %hash_map and
  253.              *  that the resulting %hash_map's size is the same as the number
  254.              *  of elements assigned.
  255.              */
  256.             hash_map& operator=(std::initializer_list<value_type> l);
  257.  
  258.             ///  Returns the allocator object used by the %hash_map.
  259.             allocator_type get_allocator() const noexcept;
  260.  
  261.             // size and capacity:
  262.  
  263.             ///  Returns true if the %hash_map is empty.
  264.             bool empty() const noexcept {
  265.                 if (m_size == 0)
  266.                     return true;
  267.                 return false;
  268.             };
  269.  
  270.             ///  Returns the size of the %hash_map.
  271.             size_type size() const noexcept;
  272.  
  273.             ///  Returns the maximum size of the %hash_map.
  274.             size_type max_size() const noexcept;
  275.  
  276.             // iterators.
  277.  
  278.             /**
  279.              *  Returns a read/write iterator that points to the first element in the
  280.              *  %hash_map.
  281.              */
  282.             iterator begin() noexcept {
  283.                 iterator ptr(&m_node[0]);
  284.                 return ptr;
  285.             };
  286.  
  287.             //@{
  288.             /**
  289.              *  Returns a read-only (constant) iterator that points to the first
  290.              *  element in the %hash_map.
  291.              */
  292.             const_iterator begin() const noexcept {
  293.                 const_iterator ptr(&m_node[0]);
  294.                 return ptr;
  295.             };
  296.  
  297.             const_iterator cbegin() const noexcept;
  298.  
  299.             /**
  300.              *  Returns a read/write iterator that points one past the last element in
  301.              *  the %hash_map.
  302.              */
  303.             iterator end() noexcept;
  304.  
  305.             //@{
  306.             /**
  307.              *  Returns a read-only (constant) iterator that points one past the last
  308.              *  element in the %hash_map.
  309.              */
  310.             const_iterator end() const noexcept;
  311.  
  312.             const_iterator cend() const noexcept;
  313.             //@}
  314.  
  315.             // modifiers.
  316.  
  317.             /**
  318.              *  @brief Attempts to build and insert a std::pair into the
  319.              *  %hash_map.
  320.              *
  321.              *  @param args  Arguments used to generate a new pair instance (see
  322.              *          std::piecewise_contruct for passing arguments to each
  323.             *           part of the pair constructor).
  324.             *
  325.             *  @return  A pair, of which the first element is an iterator that points
  326.             *           to the possibly inserted pair, and the second is a bool that
  327.             *           is true if the pair was actually inserted.
  328.             *
  329.             *  This function attempts to build and insert a (key, value) %pair into
  330.             *  the %hash_map.
  331.             *  An %hash_map relies on unique keys and thus a %pair is only
  332.             *  inserted if its first element (the key) is not already present in the
  333.             *  %hash_map.
  334.             *
  335.             *  Insertion requires amortized constant time.
  336.             */
  337.             template<typename... _Args>
  338.             std::pair<iterator, bool> emplace(_Args&&... args);
  339.  
  340.             /**
  341.              *  @brief Attempts to build and insert a std::pair into the
  342.              *  %hash_map.
  343.              *
  344.              *  @param  pos  An iterator that serves as a hint as to where the pair
  345.              *                should be inserted.
  346.              *  @param  args  Arguments used to generate a new pair instance (see
  347.              *           std::piecewise_contruct for passing arguments to each
  348.             *            part of the pair constructor).
  349.             *  @return An iterator that points to the element with key of the
  350.             *          std::pair built from @a args (may or may not be that
  351.             *          std::pair).
  352.             *
  353.             *  This function is not concerned about whether the insertion took place,
  354.             *  and thus does not return a boolean like the single-argument emplace()
  355.             *  does.
  356.             *  Note that the first parameter is only a hint and can potentially
  357.             *  improve the performance of the insertion process. A bad hint would
  358.             *  cause no gains in efficiency.
  359.             *
  360.             *  See
  361.             *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
  362.             *  for more on @a hinting.
  363.             *
  364.             *  Insertion requires amortized constant time.
  365.             */
  366.             template<typename... _Args>
  367.             iterator emplace_hint(const_iterator pos, _Args&&... args);
  368.  
  369.             /**
  370.              *  @brief Attempts to build and insert a std::pair into the
  371.              *  %hash_map.
  372.              *
  373.              *  @param k    Key to use for finding a possibly existing pair in
  374.              *                the hash_map.
  375.              *  @param args  Arguments used to generate the .second for a
  376.              *                new pair instance.
  377.              *
  378.              *  @return  A pair, of which the first element is an iterator that points
  379.              *           to the possibly inserted pair, and the second is a bool that
  380.              *           is true if the pair was actually inserted.
  381.              *
  382.              *  This function attempts to build and insert a (key, value) %pair into
  383.              *  the %hash_map.
  384.              *  An %hash_map relies on unique keys and thus a %pair is only
  385.              *  inserted if its first element (the key) is not already present in the
  386.              *  %hash_map.
  387.              *  If a %pair is not inserted, this function has no effect.
  388.              *
  389.              *  Insertion requires amortized constant time.
  390.              */
  391.             template <typename... _Args>
  392.             std::pair<iterator, bool> try_emplace(const key_type& k, _Args&&... args) {
  393.                 insert({ k, mapped_type(std::forward<_Args>(args)...) });
  394.             }
  395.             // move-capable overload
  396.             template <typename... _Args>
  397.             std::pair<iterator, bool> try_emplace(key_type&& k, _Args&&... args) {
  398.                 insert({ std::move(k), mapped_type(std::forward<_Args>(args)...) });
  399.             }
  400.             /**
  401.              *  @brief Attempts to build and insert a std::pair into the
  402.              *  %hash_map.
  403.              *
  404.              *  @param  hint  An iterator that serves as a hint as to where the pair
  405.              *                should be inserted.
  406.              *  @param k    Key to use for finding a possibly existing pair in
  407.              *                the hash_map.
  408.              *  @param args  Arguments used to generate the .second for a
  409.              *                new pair instance.
  410.              *  @return An iterator that points to the element with key of the
  411.              *          std::pair built from @a args (may or may not be that
  412.              *          std::pair).
  413.              *
  414.              *  This function is not concerned about whether the insertion took place,
  415.              *  and thus does not return a boolean like the single-argument emplace()
  416.              *  does. However, if insertion did not take place,
  417.              *  this function has no effect.
  418.              *  Note that the first parameter is only a hint and can potentially
  419.              *  improve the performance of the insertion process. A bad hint would
  420.              *  cause no gains in efficiency.
  421.              *
  422.              *  See
  423.              *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
  424.              *  for more on @a hinting.
  425.              *
  426.              *  Insertion requires amortized constant time.
  427.              */
  428.             template <typename... _Args>
  429.             iterator try_emplace(const_iterator hint, const key_type& k,
  430.                 _Args&&... args);
  431.  
  432.             // move-capable overload
  433.             template <typename... _Args>
  434.             iterator try_emplace(const_iterator hint, key_type&& k, _Args&&... args);
  435.  
  436.             //@{
  437.             /**
  438.              *  @brief Attempts to insert a std::pair into the %hash_map.
  439.              *  @param x Pair to be inserted (see std::make_pair for easy
  440.              *       creation of pairs).
  441.             *
  442.             *  @return  A pair, of which the first element is an iterator that
  443.             *           points to the possibly inserted pair, and the second is
  444.             *           a bool that is true if the pair was actually inserted.
  445.             *
  446.             *  This function attempts to insert a (key, value) %pair into the
  447.             *  %hash_map. An %hash_map relies on unique keys and thus a
  448.             *  %pair is only inserted if its first element (the key) is not already
  449.             *  present in the %hash_map.
  450.             *
  451.             *  Insertion requires amortized constant time.
  452.             */
  453.             std::pair<iterator, bool> insert(const value_type& x);
  454.  
  455.             std::pair<iterator, bool> insert(value_type&& x);
  456.  
  457.             //@}
  458.  
  459.             //@{
  460.             /**
  461.              *  @brief Attempts to insert a std::pair into the %hash_map.
  462.              *  @param  hint  An iterator that serves as a hint as to where the
  463.              *                 pair should be inserted.
  464.              *  @param  x  Pair to be inserted (see std::make_pair for easy creation
  465.              *               of pairs).
  466.              *  @return An iterator that points to the element with key of
  467.              *           @a x (may or may not be the %pair passed in).
  468.              *
  469.              *  This function is not concerned about whether the insertion took place,
  470.              *  and thus does not return a boolean like the single-argument insert()
  471.              *  does.  Note that the first parameter is only a hint and can
  472.              *  potentially improve the performance of the insertion process.  A bad
  473.              *  hint would cause no gains in efficiency.
  474.              *
  475.              *  See
  476.              *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
  477.              *  for more on @a hinting.
  478.              *
  479.              *  Insertion requires amortized constant time.
  480.              */
  481.             iterator insert(const_iterator hint, const value_type& x);
  482.  
  483.             iterator insert(const_iterator hint, value_type&& x);
  484.  
  485.             //@}
  486.  
  487.             /**
  488.              *  @brief A template function that attempts to insert a range of
  489.              *  elements.
  490.              *  @param  first  Iterator pointing to the start of the range to be
  491.              *                   inserted.
  492.              *  @param  last  Iterator pointing to the end of the range.
  493.              *
  494.              *  Complexity similar to that of the range constructor.
  495.              */
  496.             template<typename _InputIterator>
  497.             void insert(_InputIterator first, _InputIterator last);
  498.  
  499.             /**
  500.              *  @brief Attempts to insert a list of elements into the %hash_map.
  501.              *  @param  l  A std::initializer_list<value_type> of elements
  502.              *               to be inserted.
  503.              *
  504.              *  Complexity similar to that of the range constructor.
  505.              */
  506.             void insert(std::initializer_list<value_type> l);
  507.  
  508.  
  509.             /**
  510.              *  @brief Attempts to insert a std::pair into the %hash_map.
  511.              *  @param k    Key to use for finding a possibly existing pair in
  512.              *                the map.
  513.              *  @param obj  Argument used to generate the .second for a pair
  514.              *                instance.
  515.              *
  516.              *  @return  A pair, of which the first element is an iterator that
  517.              *           points to the possibly inserted pair, and the second is
  518.              *           a bool that is true if the pair was actually inserted.
  519.              *
  520.              *  This function attempts to insert a (key, value) %pair into the
  521.              *  %hash_map. An %hash_map relies on unique keys and thus a
  522.              *  %pair is only inserted if its first element (the key) is not already
  523.              *  present in the %hash_map.
  524.              *  If the %pair was already in the %hash_map, the .second of
  525.              *  the %pair is assigned from obj.
  526.              *
  527.              *  Insertion requires amortized constant time.
  528.              */
  529.             template <typename _Obj>
  530.             std::pair<iterator, bool> insert_or_assign(const key_type& k, _Obj&& obj);
  531.  
  532.             // move-capable overload
  533.             template <typename _Obj>
  534.             std::pair<iterator, bool> insert_or_assign(key_type&& k, _Obj&& obj);
  535.  
  536.             /**
  537.              *  @brief Attempts to insert a std::pair into the %hash_map.
  538.              *  @param  hint  An iterator that serves as a hint as to where the
  539.              *                  pair should be inserted.
  540.              *  @param k    Key to use for finding a possibly existing pair in
  541.              *                the hash_map.
  542.              *  @param obj  Argument used to generate the .second for a pair
  543.              *                instance.
  544.              *  @return An iterator that points to the element with key of
  545.              *           @a x (may or may not be the %pair passed in).
  546.              *
  547.              *  This function is not concerned about whether the insertion took place,
  548.              *  and thus does not return a boolean like the single-argument insert()
  549.              *  does.
  550.              *  If the %pair was already in the %unordered map, the .second of
  551.              *  the %pair is assigned from obj.
  552.              *  Note that the first parameter is only a hint and can
  553.              *  potentially improve the performance of the insertion process.  A bad
  554.              *  hint would cause no gains in efficiency.
  555.              *
  556.              *  See
  557.              *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
  558.              *  for more on @a hinting.
  559.              *
  560.              *  Insertion requires amortized constant time.
  561.              */
  562.             template <typename _Obj>
  563.             iterator insert_or_assign(const_iterator hint, const key_type& k,
  564.                 _Obj&& obj);
  565.  
  566.             // move-capable overload
  567.             template <typename _Obj>
  568.             iterator insert_or_assign(const_iterator hint, key_type&& k, _Obj&& obj);
  569.  
  570.             //@{
  571.             /**
  572.              *  @brief Erases an element from an %hash_map.
  573.              *  @param  position  An iterator pointing to the element to be erased.
  574.              *  @return An iterator pointing to the element immediately following
  575.              *          @a position prior to the element being erased. If no such
  576.              *          element exists, end() is returned.
  577.              *
  578.              *  This function erases an element, pointed to by the given iterator,
  579.              *  from an %hash_map.
  580.              *  Note that this function only erases the element, and that if the
  581.              *  element is itself a pointer, the pointed-to memory is not touched in
  582.              *  any way.  Managing the pointer is the user's responsibility.
  583.              */
  584.             iterator erase(const_iterator position);
  585.  
  586.             // LWG 2059.
  587.             iterator erase(iterator position);
  588.             //@}
  589.  
  590.             /**
  591.              *  @brief Erases elements according to the provided key.
  592.              *  @param  x  Key of element to be erased.
  593.              *  @return  The number of elements erased.
  594.              *
  595.              *  This function erases all the elements located by the given key from
  596.              *  an %hash_map. For an %hash_map the result of this function
  597.              *  can only be 0 (not present) or 1 (present).
  598.              *  Note that this function only erases the element, and that if the
  599.              *  element is itself a pointer, the pointed-to memory is not touched in
  600.              *  any way.  Managing the pointer is the user's responsibility.
  601.              */
  602.             size_type erase(const key_type& x);
  603.  
  604.             /**
  605.              *  @brief Erases a [first,last) range of elements from an
  606.              *  %hash_map.
  607.              *  @param  first  Iterator pointing to the start of the range to be
  608.              *                  erased.
  609.              *  @param last  Iterator pointing to the end of the range to
  610.              *                be erased.
  611.              *  @return The iterator @a last.
  612.              *
  613.              *  This function erases a sequence of elements from an %hash_map.
  614.              *  Note that this function only erases the elements, and that if
  615.              *  the element is itself a pointer, the pointed-to memory is not touched
  616.              *  in any way.  Managing the pointer is the user's responsibility.
  617.              */
  618.             iterator erase(const_iterator first, const_iterator last);
  619.  
  620.             /**
  621.              *  Erases all elements in an %hash_map.
  622.              *  Note that this function only erases the elements, and that if the
  623.              *  elements themselves are pointers, the pointed-to memory is not touched
  624.              *  in any way.  Managing the pointer is the user's responsibility.
  625.              */
  626.             void clear() noexcept;
  627.  
  628.             /**
  629.              *  @brief  Swaps data with another %hash_map.
  630.              *  @param  x  An %hash_map of the same element and allocator
  631.              *  types.
  632.              *
  633.              *  This exchanges the elements between two %hash_map in constant
  634.              *  time.
  635.              *  Note that the global std::swap() function is specialized such that
  636.              *  std::swap(m1,m2) will feed to this function.
  637.              */
  638.             void swap(hash_map& x);
  639.  
  640.             template<typename _H2, typename _P2>
  641.             void merge(hash_map<K, T, _H2, _P2, Alloc>& source);
  642.  
  643.             template<typename _H2, typename _P2>
  644.             void merge(hash_map<K, T, _H2, _P2, Alloc>&& source);
  645.  
  646.             // observers.
  647.  
  648.             ///  Returns the hash functor object with which the %hash_map was
  649.             ///  constructed.
  650.             Hash hash_function() const;
  651.  
  652.             ///  Returns the key comparison object with which the %hash_map was
  653.             ///  constructed.
  654.             Pred key_eq() const;
  655.  
  656.             // lookup.
  657.  
  658.             //@{
  659.             /**
  660.              *  @brief Tries to locate an element in an %hash_map.
  661.              *  @param  x  Key to be located.
  662.              *  @return  Iterator pointing to sought-after element, or end() if not
  663.              *           found.
  664.              *
  665.              *  This function takes a key and tries to locate the element with which
  666.              *  the key matches.  If successful the function returns an iterator
  667.              *  pointing to the sought after element.  If unsuccessful it returns the
  668.              *  past-the-end ( @c end() ) iterator.
  669.              */
  670.             iterator find(const key_type& x);
  671.  
  672.             const_iterator find(const key_type& x) const;
  673.             //@}
  674.  
  675.             /**
  676.              *  @brief  Finds the number of elements.
  677.              *  @param  x  Key to count.
  678.              *  @return  Number of elements with specified key.
  679.              *
  680.              *  This function only makes sense for %unordered_multimap; for
  681.              *  %hash_map the result will either be 0 (not present) or 1
  682.              *  (present).
  683.              */
  684.             size_type count(const key_type& x) const;
  685.  
  686.             /**
  687.              *  @brief  Finds whether an element with the given key exists.
  688.              *  @param  x  Key of elements to be located.
  689.              *  @return  True if there is any element with the specified key.
  690.              */
  691.             bool contains(const key_type& x) const;
  692.  
  693.             //@{
  694.             /**
  695.              *  @brief  Subscript ( @c [] ) access to %hash_map data.
  696.              *  @param  k  The key for which data should be retrieved.
  697.              *  @return  A reference to the data of the (key,data) %pair.
  698.              *
  699.              *  Allows for easy lookup with the subscript ( @c [] )operator.  Returns
  700.              *  data associated with the key specified in subscript.  If the key does
  701.              *  not exist, a pair with that key is created using default values, which
  702.              *  is then returned.
  703.              *
  704.              *  Lookup requires constant time.
  705.              */
  706.             mapped_type& operator[](const key_type& k) {
  707.                 const size_type n = m_hash(k);
  708.                 size_type index = n % m_size;
  709.                 size_type count = 0;
  710.                 while (m_node[index].state == Full && count != m_size && k != m_data[index].first) {
  711.                     count++;
  712.                     index = (index + 1) % m_size;
  713.                 }
  714.                 if (m_node[index].state == Full)
  715.                     return m_data[index].second;
  716.                 if (m_node[index].state == Empty)
  717.                 {
  718.                     new(m_data + index) value_type{ k, mapped_type{} };
  719.                     m_node[index].state = Full;
  720.                     return m_data[index].second;
  721.                 }
  722.  
  723.  
  724.             };
  725.  
  726.             mapped_type& operator[](key_type&& k) {
  727.                 size_type n = m_hash(k);
  728.                 n = 0;
  729.                 size_type index = n % m_size;
  730.                 size_type count = 0;
  731.                 while (m_node[index].state == Full && count != m_size && k != m_data[index].first) {
  732.                     count++;
  733.                     index = (index + 1) % m_size;
  734.                 }
  735.                 if (m_node[index].state == Full)
  736.                     return m_data[index].second;
  737.                 if (m_node[index].state == Empty)
  738.                 {
  739.                     //insert(std:move(value_type(std:move(k),0)));
  740.                     new(m_data + index) value_type{ k, mapped_type{} };
  741.                     m_node[index].state = Full;
  742.                     return m_data[index].second;
  743.                 }
  744.             };
  745.             //@}
  746.  
  747.             //@{
  748.             /**
  749.              *  @brief  Access to %hash_map data.
  750.              *  @param  k  The key for which data should be retrieved.
  751.              *  @return  A reference to the data whose key is equal to @a k, if
  752.              *           such a data is present in the %hash_map.
  753.              *  @throw  std::out_of_range  If no such data is present.
  754.              */
  755.             mapped_type& at(const key_type& k);
  756.  
  757.             const mapped_type& at(const key_type& k) const;
  758.             //@}
  759.  
  760.             // bucket interface.
  761.  
  762.             /// Returns the number of buckets of the %hash_map.
  763.             size_type bucket_count() const noexcept;
  764.  
  765.             /*
  766.             * @brief  Returns the bucket index of a given element.
  767.             * @param  _K  A key instance.
  768.             * @return  The key bucket index.
  769.             */
  770.             size_type bucket(const key_type& _K) const;
  771.  
  772.             // hash policy.
  773.  
  774.             /// Returns the average number of elements per bucket.
  775.             float load_factor() const noexcept;
  776.  
  777.             /// Returns a positive number that the %hash_map tries to keep the
  778.             /// load factor less than or equal to.
  779.             float max_load_factor() const noexcept;
  780.  
  781.             /**
  782.              *  @brief  Change the %hash_map maximum load factor.
  783.              *  @param  z The new maximum load factor.
  784.              */
  785.             void max_load_factor(float z);
  786.  
  787.             /**
  788.              *  @brief  May rehash the %hash_map.
  789.              *  @param  n The new number of buckets.
  790.              *
  791.              *  Rehash will occur only if the new number of buckets respect the
  792.              *  %hash_map maximum load factor.
  793.              */
  794.             void rehash(size_type n);
  795.  
  796.             /**
  797.              *  @brief  Prepare the %hash_map for a specified number of
  798.              *          elements.
  799.              *  @param  n Number of elements required.
  800.              *
  801.              *  Same as rehash(ceil(n / max_load_factor())).
  802.              */
  803.             void reserve(size_type n);
  804.  
  805.             bool operator==(const hash_map& other) const;
  806.         private:
  807.             allocator_type m_allocator;
  808.             key_equal m_key_equal;
  809.             hasher m_hash;
  810.             std::vector<Node> m_node;
  811.             value_type* m_data;
  812.             std::vector<char> m_set;
  813.             size_type m_size;
  814.  
  815.     };
  816.  
  817.  
  818. } // namespace fefu
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement