⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 auto_buffer.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 4 页
字号:
            // Expansion; cases 1, 3 & 5

            if(is_in_external_array_())
            {
                // Current buffer is allocated: case 5
                pointer new_buffer  =   reallocate_(m_buffer, m_cItems, cItems);

                // Still test for NULL here, since some allocators will
                // not throw bad_alloc.
                if(NULL == new_buffer)
                {
                    return false;
                }

                // Now repoint to the new buffer
                m_buffer = new_buffer;
            }
            else
            {
                // Expanding from internal buffer; cases 1 & 3

                if(space < cItems)
                {
                    // Expanding to allocated buffer; case 3

                    pointer new_buffer = allocate_(cItems);

                    // Still test for NULL here, since some allocators will
                    // not throw bad_alloc.
                    if(NULL == new_buffer)
                    {
                        return false;
                    }

                    block_copy(new_buffer, m_buffer, m_cItems);

                    m_buffer = new_buffer;

                    m_bExternal = true;
                }
                else
                {
                    // Expanding to internal buffer; case 1

                    // Nothing to do
                    STLSOFT_ASSERT(!(space < cItems));
                }
            }
        }
        else
        {
            // Contraction; cases 2, 4 & 6

            if(is_in_external_array_())
            {
                // Current buffer is allocated: cases 4 & 6

                if(space < cItems)
                {
                    // Contracting within allocated buffer; case 6

                    // Nothing to do
                    STLSOFT_ASSERT(space < cItems);
                }
#if defined(STLSOFT_AUTO_BUFFER_AGGRESSIVE_SHRINK)
                else
#else /* ? STLSOFT_AUTO_BUFFER_AGGRESSIVE_SHRINK */
                else if(0 == cItems)
#endif /* STLSOFT_AUTO_BUFFER_AGGRESSIVE_SHRINK */
                {
                    // Contracting back to internal; case 4

                    block_copy(const_cast<pointer>(&m_internal[0]), m_buffer, cItems);

                    deallocate_(m_buffer, m_cItems);

                    m_buffer = const_cast<pointer>(&m_internal[0]);

                    m_bExternal = false;
                }
            }
            else
            {
                // Current buffer is internal; case 2

                // Nothing to do
                STLSOFT_ASSERT(!(space < cItems));
            }
        }

        m_cItems = cItems;

        STLSOFT_ASSERT(is_valid());

        return true;
    }

    /// \brief Swaps contents with the given buffer
    ///
    /// \note This method is only constant time when the memory for two buffers
    /// has been acquired via the allocator. Otherwise, it will depend on the
    /// costs of exchanging the memory
    ///
    /// \note Exception-safety: Provides the no-throw guarantee
    void swap(class_type& rhs) stlsoft_throw_0()
    {
        STLSOFT_ASSERT(is_valid());

        if( is_in_external_array_() &&
            rhs.is_in_external_array_())
        {
            // Both are allocated, so just swap them
            std_swap(m_buffer, rhs.m_buffer);
        }
        else if(is_in_external_array_())
        {
            // *this is allocated on the heap, rhs is using m_internal

            // 1. Copy the contents of rhs.m_internal to this->m_internal
            block_copy(&m_internal[0], &rhs.m_internal[0], rhs.m_cItems);

            // 2. Move m_buffer from *this to rhs
            rhs.m_buffer = m_buffer;

            // 3. Tell *this to use its internal buffer
            m_buffer = &m_internal[0];
        }
        else if(rhs.is_in_external_array_())
        {
            // This is a lazy cheat, but eminently effective.
            rhs.swap(*this);

            return;
        }
        else
        {
            // Both are using internal buffers, so we exchange the contents
            value_type  t[space];

            block_copy(&t[0],               &rhs.m_internal[0], rhs.m_cItems);
            block_copy(&rhs.m_internal[0],  &m_internal[0],     m_cItems);
            block_copy(&m_internal[0],      &t[0],              rhs.m_cItems);
        }

        std_swap(m_cItems,      rhs.m_cItems);
        std_swap(m_bExternal,   rhs.m_bExternal);

        STLSOFT_ASSERT(is_valid());
    }
/// @}

/// \name Operators
/// @{
public:
    // Note: The following two const and non-const implicit conversion
    // operators are correctly implemented. However, GCC will pedantically
    // give a verbose warning describing its having selected one over the
    // other, and this is, in current versions of the compiler, not
    // suppressable. The warnings must, alas, simply be ignored.

#ifdef _STLSOFT_AUTO_BUFFER_ALLOW_NON_CONST_CONVERSION_OPERATOR
    /// \brief An implicit conversion to a pointer to the start of the element array
    ///
    /// \deprecate This is deprecated
    operator pointer ()
    {
        STLSOFT_ASSERT(is_valid());

        return m_buffer;
    }
#else /* ? _STLSOFT_AUTO_BUFFER_ALLOW_NON_CONST_CONVERSION_OPERATOR */
    /// \brief Subscript operator
    reference operator [](size_type index)
    {
        STLSOFT_MESSAGE_ASSERT("Index is out of bounds", index <= m_cItems);

        STLSOFT_ASSERT(is_valid());

        return m_buffer[index];
    }

    /// \brief Subscript operator
    const_reference operator [](size_type index) const
    {
        STLSOFT_MESSAGE_ASSERT("Index is out of bounds", index <= m_cItems);

        STLSOFT_ASSERT(is_valid());

        return m_buffer[index];
    }
#endif /* _STLSOFT_AUTO_BUFFER_ALLOW_NON_CONST_CONVERSION_OPERATOR */

#ifdef _STLSOFT_AUTO_BUFFER_ALLOW_CONST_CONVERSION_OPERATOR
    /// \brief An implicit conversion to a pointer-to-const to the start of the element array
    operator const_pointer () const
    {
        STLSOFT_ASSERT(is_valid());

        return m_buffer;
    }
#endif /* _STLSOFT_AUTO_BUFFER_ALLOW_CONST_CONVERSION_OPERATOR */
/// @}

/// \name Accessors
/// @{
public:
    /// \brief Returns a pointer to the element array
    pointer data()
    {
        STLSOFT_ASSERT(is_valid());

        return m_buffer;
    }
    /// \brief Returns a pointer-to-const to the element array
    const_pointer data() const
    {
        STLSOFT_ASSERT(is_valid());

        return m_buffer;
    }

    /// \brief Returns a reference to the last element in the buffer
    ///
    /// \pre The buffer instance must not be empty
    reference front()
    {
        STLSOFT_ASSERT(is_valid());

        STLSOFT_MESSAGE_ASSERT("Cannot call front() on an empty buffer!", !empty());

        return m_buffer[0];
    }
    /// \brief Returns a reference to the last element in the buffer
    ///
    /// \pre The buffer instance must not be empty
    reference back()
    {
        STLSOFT_ASSERT(is_valid());

        STLSOFT_MESSAGE_ASSERT("Cannot call back() on an empty buffer!", !empty());

        return m_buffer[size() - 1];
    }
    /// \brief Returns a non-mutating (const) reference to the last element
    ///   in the buffer
    ///
    /// \pre The buffer instance must not be empty
    const_reference front() const
    {
        STLSOFT_ASSERT(is_valid());

        STLSOFT_MESSAGE_ASSERT("Cannot call front() on an empty buffer!", !empty());

        return m_buffer[0];
    }
    /// \brief Returns a non-mutating (const) reference to the last element
    ///   in the buffer
    ///
    /// \pre The buffer instance must not be empty
    const_reference back() const
    {
        STLSOFT_ASSERT(is_valid());

        STLSOFT_MESSAGE_ASSERT("Cannot call back() on an empty buffer!", !empty());

        return m_buffer[size() - 1];
    }
/// @}

/// \name Iteration
/// @{
public:
    /// \brief Returns a non-mutating iterator representing the start of the sequence
    const_iterator begin() const
    {
        STLSOFT_ASSERT(is_valid());

        return m_buffer;
    }
    /// \brief Returns a non-mutating iterator representing the end of the sequence
    ///
    /// \note In the case where memory allocation has failed in the context
    /// where exceptions are not thrown for allocation failure, this method will
    /// return the same value as begin(). Hence, operations on the <i>empty</i>
    /// auto_buffer<> instance will be safe if made in respect of the range
    /// defined by [begin(), end()).
    const_iterator end() const
    {
        STLSOFT_ASSERT(is_valid());

        return m_buffer + m_cItems;
    }

    /// \brief Returns a mutable iterator representing the start of the sequence
    iterator begin()
    {
        STLSOFT_ASSERT(is_valid());

        return m_buffer;
    }
    /// \brief Returns a mutable iterator representing the end of the sequence
    ///
    /// \note In the case where memory allocation has failed in the context
    /// where exceptions are not thrown for allocation failure, this method will
    /// return the same value as begin(). Hence, operations on the <i>empty</i>
    /// auto_buffer<> instance will be safe if made in respect of the range
    /// defined by [begin(), end()).
    iterator end()
    {
        STLSOFT_ASSERT(is_valid());

        return m_buffer + m_cItems;
    }

#if defined(STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
    /// Begins the reverse iteration
    ///
    /// \return An iterator representing the start of the reverse sequence
    const_reverse_iterator rbegin() const
    {
        STLSOFT_ASSERT(is_valid());

        return const_reverse_iterator(end());
    }
    /// Ends the reverse iteration
    ///
    /// \return An iterator representing the end of the reverse sequence
    const_reverse_iterator rend() const
    {
        STLSOFT_ASSERT(is_valid());

        return const_reverse_iterator(begin());
    }
    /// Begins the reverse iteration
    ///
    /// \return An iterator representing the start of the reverse sequence
    reverse_iterator  rbegin()
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -