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

📄 carray_adaptors.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 4 页
字号:
                        ,   array_traits_type
                        >               arp(ar);
            arp.assign(first, last);

            CArray_swap(this->get_CArray(), ar);
        }
#else /* ? MFCSTL_CARRAY_SWAP_MEMBERS_SUPPORT */
        clear_and_assign_(first, last);
#endif /* MFCSTL_CARRAY_SWAP_MEMBERS_SUPPORT */
    }
/// @}

/// \name Size and Capacity
/// @{
public:
    /// \brief The number of items in the array
    size_type size() const
    {
        return static_cast<size_type>(get_CArray().GetSize());
    }
    /// \brief The maximum number of items that can be stored in the array
    size_type max_size() const
    {
        return get_allocator().max_size();
    }
    /// \brief Indicates whether the array is empty
    ms_bool_t empty() const
    {
        return 0 == size();
    }
    /// \brief Adjusts the number of elements in the array
    ///
    /// \param n The number of elements that the array will contain after resizing
    ///
    /// \note Exception-safety is <b>strong</b> if the default constructor of the value type
    /// cannot throw exceptions, otherwise it is weak
    void resize(size_type n)
    {
        try
        {
            get_CArray().SetSize(n, calc_increment_(n));
        }
        catch(CMemoryException *px)
        {
            exception_translation_policy_type::handle(px);
        }
        catch(mfcstl_ns_qual_std(bad_alloc) &x)
        {
            exception_translation_policy_type::handle(x);
        }

        // Postcondition
        MFCSTL_ASSERT(size() == n);
    }
    /// \brief Adjusts the number of elements in the array
    ///
    /// \param n The number of elements that the array will contain after resizing
    /// \param value The value of any additional elements created during resizing
    ///
    /// \note Due to the limitations of the underlying CArray-family containers, the
    ///   additional elements are default constructed and then subjected to
    ///   copy-assignment.
    ///
    /// \note Exception-safety is <b>weak</b>, but the size is maintained in the case
    /// where an exception is thrown by the copy assignment of any new elements.
    void resize(size_type n, value_type value)
    {
        const size_type oldSize = size();
        resize(n);
        if(oldSize < n)
        {
            try
            {
                mfcstl_ns_qual_std(fill_n)(begin() + oldSize, n - oldSize, value);
            }
            catch(...)
            {
                resize(oldSize);
                throw;
            }
        }
    }
/// @}

/// \name Element access
/// @{
public:
    /// \brief Returns a mutable (non-const) reference to the element at the given index
    ///
    /// \param n The requested index. Must be less than size()
    ///
    /// \note The implementation will assert in debug mode if the index is out of range
    reference operator [](size_type n)
    {
        MFCSTL_MESSAGE_ASSERT("index out of bounds", n < size());

        return get_CArray()[n];
    }
    /// \brief Returns a non-mutable (const) reference to the element at the given index
    ///
    /// \param n The requested index. Must be less than size()
    ///
    /// \note The implementation will assert in debug mode if the index is out of range
    const_reference operator [](size_type n) const
    {
        MFCSTL_MESSAGE_ASSERT("index out of bounds", n < size());

        return get_CArray()[n];
    }
    /// \brief Returns a mutable (non-const) reference to the element at the given index
    ///
    /// \param n The requested index. If the index is not less than size() an
    /// instance of std::out_of_range will be thrown
    reference at(size_type n)
    {
        if(n >= size())
        {
            STLSOFT_THROW_X(mfcstl_ns_qual_std(out_of_range)("Invalid index specified"));
        }

        return (*this)[n];
    }
    /// \brief Returns a non-mutable (const) reference to the element at the given index
    ///
    /// \param n The requested index. If the index is not less than size() an
    /// instance of std::out_of_range will be thrown
    const_reference at(size_type n) const
    {
        if(n >= size())
        {
            STLSOFT_THROW_X(mfcstl_ns_qual_std(out_of_range)("Invalid index specified"));
        }
        return (*this)[n];
    }
    /// \brief Returns a mutable (non-const) reference to the first element in the array
    reference front()
    {
        MFCSTL_MESSAGE_ASSERT("front() called on an empty instance", !empty());

        return (*this)[0];
    }
    /// \brief Returns a mutable (non-const) reference to the last element in the array
    reference back()
    {
        MFCSTL_MESSAGE_ASSERT("back() called on an empty instance", !empty());

        return (*this)[size() - 1];
    }
    /// \brief Returns a non-mutable (const) reference to the first element in the array
    const_reference front() const
    {
        MFCSTL_MESSAGE_ASSERT("front() called on an empty instance", !empty());

        return (*this)[0];
    }
    /// \brief Returns a non-mutable (const) reference to the last element in the array
    const_reference back() const
    {
        MFCSTL_MESSAGE_ASSERT("back() called on an empty instance", !empty());

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

/// \name Iteration
/// @{
public:
    /// \brief Returns a mutable (non-const) iterator representing the start of the array
    iterator begin()
    {
        return get_CArray().GetData();
    }
    /// \brief Returns a mutable (non-const) iterator representing the end of the array
    iterator end()
    {
        return begin() + size();
    }
    /// \brief Returns a non-mutable (const) iterator representing the start of the array
    const_iterator begin() const
    {
        // This is needed because CXxxxArray::GetData() const returns, e.g., const CObject** instead of CObject* const*
        value_type const    *p1 =   get_CArray().GetData();
        value_type *const   p2  =   const_cast<value_type *const>(p1);

        return p2;
    }
    /// \brief Returns a non-mutable (const) iterator representing the end of the array
    const_iterator end() const
    {
        return begin() + size();
    }
#ifdef STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT
    /// \brief Returns a mutable (non-const) reverse iterator representing the start of the array
    reverse_iterator rbegin()
    {
        return reverse_iterator(end());
    }
    /// \brief Returns a mutable (non-const) reverse iterator representing the end of the array
    reverse_iterator rend()
    {
        return reverse_iterator(begin());
    }
    /// \brief Returns a non-mutable (const) reverse iterator representing the start of the array
    const_reverse_iterator rbegin() const
    {
        return const_reverse_iterator(end());
    }
    /// \brief Returns a non-mutable (const) reverse iterator representing the end of the array
    const_reverse_iterator rend() const
    {
        return const_reverse_iterator(begin());
    }
#endif /* STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT */
/// @}

/// \name Comparison
/// @{
public:
    template<   ss_typename_param_k A2
            ,   ss_typename_param_k I2
            ,   ss_typename_param_k T2
            >
    ms_bool_t equal(CArray_adaptor_base<A2, I2, T2> const& rhs) const
    {
        typedef CArray_adaptor_base<A2, I2, T2>         rhs_t;
        typedef ss_typename_type_k rhs_t::value_type    rhs_value_t;

        STLSOFT_STATIC_ASSERT(sizeof(value_type) == sizeof(ss_typename_type_k rhs_t::value_type));

#ifdef STLSOFT_META_HAS_IS_SAME_TYPE
        STLSOFT_STATIC_ASSERT((stlsoft::is_same_type<value_type, rhs_value_t>::value));
#endif /* STLSOFT_META_HAS_IS_SAME_TYPE */

        return size() == rhs.size() && stlsoft_ns_qual_std(equal)(begin(), end(), rhs.begin());
    }

    ms_bool_t equal(array_type const& rhs) const
    {
        array_type const    &lhs    =   this->get_CArray();

        return lhs.GetSize() == rhs.GetSize() && stlsoft_ns_qual_std(equal)(begin(), end(), rhs.GetData());
    }

    template<   ss_typename_param_k A2
            ,   ss_typename_param_k I2
            ,   ss_typename_param_k T2
            >
    ms_bool_t less_than(CArray_adaptor_base<A2, I2, T2> const& rhs) const
    {
        typedef CArray_adaptor_base<A2, I2, T2>         rhs_t;
        typedef ss_typename_type_k rhs_t::value_type    rhs_value_t;

        STLSOFT_STATIC_ASSERT(sizeof(value_type) == sizeof(ss_typename_type_k rhs_t::value_type));

#ifdef STLSOFT_META_HAS_IS_SAME_TYPE
        STLSOFT_STATIC_ASSERT((stlsoft::is_same_type<value_type, rhs_value_t>::value));
#endif /* STLSOFT_META_HAS_IS_SAME_TYPE */

        return stlsoft_ns_qual_std(lexicographical_compare)(begin(), end(), rhs.begin(), rhs.end());
    }

    ms_bool_t less_than(array_type const& rhs) const
    {
        return stlsoft_ns_qual_std(lexicographical_compare)(begin(), end(), rhs.GetData(), rhs.GetData() + rhs.GetSize());
    }

    template<   ss_typename_param_k A2
            ,   ss_typename_param_k I2
            ,   ss_typename_param_k T2
            >
    ms_bool_t greater_than(CArray_adaptor_base<A2, I2, T2> const& rhs) const
    {
        typedef CArray_adaptor_base<A2, I2, T2>         rhs_t;
        typedef ss_typename_type_k rhs_t::value_type    rhs_value_t;

        STLSOFT_STATIC_ASSERT(sizeof(value_type) == sizeof(ss_typename_type_k rhs_t::value_type));

#ifdef STLSOFT_META_HAS_IS_SAME_TYPE
        STLSOFT_STATIC_ASSERT((stlsoft::is_same_type<value_type, rhs_value_t>::value));
#endif /* STLSOFT_META_HAS_IS_SAME_TYPE */

        return stlsoft_ns_qual_std(lexicographical_compare)(rhs.begin(), rhs.end(), begin(), end());
    }

    ms_bool_t greater_than(array_type const& rhs) const
    {
        return stlsoft_ns_qual_std(lexicographical_compare)(rhs.GetData(), rhs.GetData() + rhs.GetSize(), begin(), end());
    }
/// @}

/// \name Modifiers
/// @{
public:
    /// \brief Adds the given element to the end of the array
    ///
    /// \param value The value to add to the end of the array
    ///
    /// \note All iterators, pointers and references are invalidated
    void push_back(value_type const& value)
    {
        const size_type oldSize =   size();

        resize(size());

        try
        {
            try
            {
                get_CArray().Add(value);
            }
            catch(CMemoryException *px)
            {
                exception_translation_policy_type::handle(px);
            }
            catch(mfcstl_ns_qual_std(bad_alloc) &x)
            {
                exception_translation_policy_type::handle(x);
            }
        }
        catch(...)
        {
            if(size() != oldSize)
            {
                MFCSTL_ASSERT(size() == oldSize + 1);

                resize(oldSize);
            }

            throw;
        }
    }
    /// \brief Removes the last element from the non-empty array
    ///
    /// \note The behaviour is undefined if the array is empty
    void pop_back() stlsoft_throw_0()
    {
        // Precondition checks
        MFCSTL_MESSAGE_ASSERT("pop_back() called on empty container", !empty());

        get_CArray().RemoveAt(get_CArray().GetUpperBound());
    }
    /// \brief Inserts the given value at the given position
    ///
    /// \param pos The position at which to insert. The value will be inserted
    ///   before the element referred to by pos, or at the end if pos == end()
    /// \param value The value to be inserted
    ///
    /// \retval The position of the inserted value
    ///
    /// \note All iterators, pointers and references are invalidated
    ///
    /// \note Any elements after the insertion position are moved using memmove,
    ///   rather than by copy construction. If the element type maintains
    ///   pointers to its internal members, or to its peer elements, then these
    ///   relationships will be broken, and the subsequent behaviour of the
    ///   program will be undefined
    iterator insert(iterator pos, value_type const& value)
    {
        // Precondition checks
        MFCSTL_ASSERT(pos == end() || (pos >= begin() && pos < end()));

        difference_type index   =   pos - begin();
        const size_type oldSize =   size();

        resize(size());

        try
        {
            try
            {
                get_CArray().InsertAt(static_cast<int>(index), value, 1);
            }
            catch(CMemoryException *px)
            {
                exception_translation_policy_type::handle(px);
            }
            catch(mfcstl_ns_qual_std(bad_alloc) &x)
            {
                exception_translation_policy_type::handle(x);
            }
        }
        catch(...)
        {
            if(size() != oldSize)
            {
                MFCSTL_ASSERT(size() == oldSize + 1);

                get_CArray().RemoveAt(static_cast<int>(index), 1);
            }

            throw;
        }

        return begin() + index;
    }
    /// \brief Inserts a number of copies of the given value at the given position
    ///
    /// \param pos The position at which to insert. The value(s) will be inserted
    ///   before the element referred to by pos, or at the end if pos == end()
    /// \param n The number of values to insert
    /// \param value The value to be inserted
    ///
    /// \note All iterators, pointers and references are invalidated
    ///
    /// \note Any elements after the insertion position are moved using memmove,
    ///   rather than by copy construction. If the element type maintains
    ///   pointers to its internal members, or to its peer elements, then these
    ///   relationships will be broked, and the subsequent behaviour of the
    ///   program will be undefined
    void insert(iterator pos, size_type n, value_type const& value)
    {
        // Precondition checks
        MFCSTL_ASSERT(pos == end() || (pos >= begin() && pos < end()));

        difference_type index = pos - begin();

        if(empty())
        {
            MFCSTL_ASSERT(0 == index);

⌨️ 快捷键说明

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