Advertisement
Guest User

Untitled

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