018: assign()

assign() を定義します。

assign() はサイズ指定型、イテレータ型、initializer_list型の3種類あります。いずれも、前回定義した代入演算子と似た造りになります。

template <typename T>
class myvector
{
...

    /**
     * @brief      Replaces the contents with count copies of value.
     * @param[in]  count: The new size of the container.
     * @param[in]  value: The value to initialize elements of the container with.
     * @throw      std::length_error: If count is greater than max_size().
     * @throw      std::bad_alloc: If malloc() (or realloc()) fails to allocate storage.
     */
    void assign(size_type count, const value_type& value)
    {
        size_type new_size = length_check(count);

        // clear
        for (size_type i = 0; i < size_; i++) {
            heap_[i].~value_type();
        }
        size_ = 0;

        // re-allocate if needed
        if (new_size > capacity_) {
            reallocation(new_size, realloc_switcher());
        }

        // assign
        pointer p = heap_;
        for (size_type i = 0; i < new_size; i++) {
            new(p++) value_type(value);
        }
        size_ = new_size;
    }

    /**
     * @brief      Replaces the contents with copies of those in the range [first, last).
     * @param[in]  first: The first of the range to copy the elements from.
     * @param[in]  last: The last of the range to copy the elements from.
     * @throw      std::length_error: If distance between first and last is greater than max_size().
     * @throw      std::bad_alloc: If malloc() (or realloc()) fails to allocate storage.
     * @tparam     InputIt: Iterator to the elements.
     */
    template <class InputIt>
    void assign(InputIt first,
                typename std::enable_if<not std::is_integral<InputIt>::value, InputIt>::type last)
    {
        // Switcher for mydistance(). Whether InputIt is random access iterator or input iterator.
        using iterator_type = typename std::iterator_traits<InputIt>::iterator_category;

        size_type new_size = length_check(mydistance(first, last, iterator_type()));

        // clear
        for (size_type i = 0; i < size_; i++) {
            heap_[i].~value_type();
        }
        size_ = 0;

        // re-allocate if needed
        if (new_size > capacity_) {
            reallocation(new_size, realloc_switcher());
        }

        // assign
        pointer p = heap_;
        for (InputIt i = first; i != last; ++i) {
            new(p++) value_type(*i);
        }
        size_ = new_size;
    }

    /**
     * @brief      Replaces the contents with the elements from the initializer list ilist.
     * @param[in]  ilist: Initializer list to copy the values from.
     * @throw      std::length_error: If ilist size is greater than max_size().
     * @throw      std::bad_alloc: If malloc() (or realloc()) fails to allocate storage.
     */
    void assign(std::initializer_list<value_type> ilist)
    {
        size_type new_size = length_check(ilist.size());

        // clear
        for (size_type i = 0; i < size_; i++) {
            heap_[i].~value_type();
        }
        size_ = 0;

        // re-allocate if needed
        if (new_size > capacity_) {
            reallocation(new_size, realloc_switcher());
        }

        // assign
        pointer p = heap_;
        for (const auto& i: ilist) {
            new(p++) value_type(i);
        }
        size_ = new_size;
    }

    ...

};
どの assign() も、①clear()相当の処理、②必要なら領域拡張、③コピーコンストラクタでコピー、という処理を行います。


全ソースコード: https://github.com/suomesta/myvector/tree/master/018

0 件のコメント:

コメントを投稿