引数が単発の iterator と、範囲の iterator の2種類実装します。
template <typename T> class myvector { ... /** * @brief Erases the specified elements from the container. Removes the * element at pos. * Invalidates iterators and references at or after the point of * the erase, including the end() iterator. The iterator pos must * be valid and dereferenceable. Thus the end() iterator (which is * valid, but is not dereferencable) cannot be used as a value for * pos. * @param[in] pos: Iterator to the element to remove. * @return Iterator following the last removed element. If the iterator pos * refers to the last element, the end() iterator is returned. */ iterator erase(const_iterator pos) { // calculate distance size_type distance = mydistance(static_cast<const_iterator>(&heap_[0]), pos, std::random_access_iterator_tag()); // remove one element heap_[distance].~value_type(); // slide elements after pos decremental_slide(distance, 1, slide_switcher()); size_--; return static_cast<iterator>(&heap_[distance]); } /** * @brief Erases the specified elements from the container. Removes the * elements in the range [first, last). * Invalidates iterators and references at or after the point of * the erase, including the end() iterator. The iterator first * does not need to be dereferenceable if first==last: erasing an * empty range is a no-op. * @param[in] first: The first of range of elements to remove. * @param[in] last: The last of range of elements to remove. */ iterator erase(const_iterator first, const_iterator last) { // calculate distance size_type distance = mydistance(static_cast<const_iterator>(&heap_[0]), first, std::random_access_iterator_tag()); if (first == last) { return mynext(&(heap_[0]), distance, std::random_access_iterator_tag()); } // calculate count size_type count = mydistance(first, last, std::random_access_iterator_tag()); // remove elements for (size_type i = distance; i < (distance + count); i++) { heap_[i].~value_type(); } // slide elements after first decremental_slide(distance, count, slide_switcher()); size_ -= count; return static_cast<iterator>(&heap_[distance]); } ... private: /** * @brief Does slide elements into decremental direction. * value_type shall be TriviallyCopyable. * @param[in] pos: Element index which is start position of moving. * @param[in] count: The size of the elements to be moved. * @param[in] trivially_copyable_tag: Function switcher according to value_type characteristic. */ void decremental_slide(size_type pos, size_type count, trivially_copyable_tag) { for (size_type i = pos; (i + count) < size_; i++) { heap_[i] = heap_[i + count]; } } /** * @brief Does slide elements into decremental direction. * value_type shall be MoveConstructible. * @param[in] pos: Element index which is start position of moving. * @param[in] count: The size of the elements to be moved. * @param[in] move_constructible_tag: Function switcher according to value_type characteristic. */ void decremental_slide(size_type pos, size_type count, move_constructible_tag) { for (size_type i = pos; (i + count) < size_; i++) { new(&heap_[i]) value_type(std::move(heap_[i + count])); } } /** * @brief Does slide elements into decremental direction. * value_type shall be CopyConstructible. * @param[in] pos: Element index which is start position of moving. * @param[in] count: The size of the elements to be moved. * @param[in] copy_constructible_tag: Function switcher according to value_type characteristic. */ void decremental_slide(size_type pos, size_type count, copy_constructible_tag) { for (size_type i = pos; (i + count) < size_; i++) { new(&heap_[i]) value_type(heap_[i + count]); } } };補助関数 decremental_slide() を定義します。これは insert() を実装するときに作成して incremental_slide() と似た関数で、要素を前方へズラします。
eraseの中身は、①要素削除後のサイズの計算、②要素の削除(デストラクタ)、③要素の移動、となります。この処理の流れも、insert() に似たものになります。
全ソースコード:
https://github.com/suomesta/myvector/tree/master/028
0 件のコメント:
コメントを投稿