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

📄 pod_vector.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 4 页
字号:
/* /////////////////////////////////////////////////////////////////////////
 * File:        stlsoft/containers/pod_vector.hpp
 *
 * Purpose:     Contains the pod_vector class.
 *
 * Created:     23rd December 2003
 * Updated:     22nd March 2007
 *
 * Thanks to:   Chris Newcombe for requesting sufficient enhancements to
 *              auto_buffer such that pod_vector was born.
 *
 * Home:        http://stlsoft.org/
 *
 * Copyright (c) 2003-2007, Matthew Wilson and Synesis Software
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
 *   any contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * ////////////////////////////////////////////////////////////////////// */


/** \file stlsoft/containers/pod_vector.hpp
 *
 * \brief [C++ only] Definition of the stlsoft::pod_vector container class
 *   template
 *   (\ref group__library__containers "Containers" Library).
 */

#ifndef STLSOFT_INCL_STLSOFT_CONTAINERS_HPP_POD_VECTOR
#define STLSOFT_INCL_STLSOFT_CONTAINERS_HPP_POD_VECTOR

#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_POD_VECTOR_MAJOR       4
# define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_POD_VECTOR_MINOR       1
# define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_POD_VECTOR_REVISION    7
# define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_POD_VECTOR_EDIT        69
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

/* /////////////////////////////////////////////////////////////////////////
 * Compatibility
 */

/*
[Incompatibilies-start]
STLSOFT_COMPILER_IS_MSVC: _MSC_VER<1200
STLSOFT_COMPILER_IS_WATCOM:
[Incompatibilies-end]
 */

/* /////////////////////////////////////////////////////////////////////////
 * Includes
 */

#ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
# include <stlsoft/stlsoft.h>
#endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */

#if defined(STLSOFT_COMPILER_IS_MSVC) && \
    _MSC_VER < 1200
# error stlsoft/containers/pod_vector.hpp is not compatible with Visual C++ 5.0 or earlier
#endif /* compiler */

#ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
# include <stlsoft/memory/auto_buffer.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER */
#ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR
# include <stlsoft/memory/allocator_selector.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR */
#ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP
# include <stlsoft/util/std_swap.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP */
#ifndef STLSOFT_INCL_STLSOFT_ALGORITHMS_HPP_POD
# include <stlsoft/algorithms/pod.hpp>          // for pod_copy_n(), etc.
#endif /* !STLSOFT_INCL_STLSOFT_ALGORITHMS_HPP_POD */
#ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
# include <stlsoft/collections/util/collections.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS */
#include <stdexcept>                            // for std::out_of_range

/* /////////////////////////////////////////////////////////////////////////
 * Namespace
 */

#ifndef _STLSOFT_NO_NAMESPACE
namespace stlsoft
{
#endif /* _STLSOFT_NO_NAMESPACE */

/* /////////////////////////////////////////////////////////////////////////
 * Classes
 */

/** \brief Efficient vector class for use with POD types only
 *
 * \ingroup group__library__containers
 */
template<   ss_typename_param_k T
#if defined(STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT) && \
    defined(STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT)
        ,   ss_typename_param_k A       =   ss_typename_type_def_k allocator_selector<T>::allocator_type
        ,   ss_size_t           SPACE   =   64
#else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT && STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT */
        ,   ss_typename_param_k A       /* =    ss_typename_type_def_k stlsoft_ns_qual(allocator_selector)<T>::allocator_type */
        ,   ss_size_t           SPACE   /* =    64 */
#endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT && STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT */
        >
class pod_vector
    : public stl_collection_tag
{
/// \name Typedefs
/// @{
private:
    typedef auto_buffer_old<T, A, SPACE>                            buffer_type;
public:
    /// The value type
    typedef ss_typename_type_k buffer_type::value_type              value_type;
    /// The allocator type
    typedef ss_typename_type_k buffer_type::allocator_type          allocator_type;
    /// The type of the current parameterisation
    typedef pod_vector<T, A, SPACE>                                 class_type;
    /// The reference type
    typedef ss_typename_type_k buffer_type::reference               reference;
    /// The non-mutable (const) reference type
    typedef ss_typename_type_k buffer_type::const_reference         const_reference;
    /// The pointer type
    typedef ss_typename_type_k buffer_type::pointer                 pointer;
    /// The non-mutable (const) pointer type
    typedef ss_typename_type_k buffer_type::const_pointer           const_pointer;
    /// The iterator type
    typedef ss_typename_type_k buffer_type::iterator                iterator;
    /// The non-mutable (const) iterator type
    typedef ss_typename_type_k buffer_type::const_iterator          const_iterator;
#if defined(STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
    /// The type of the non-const (mutating) reverse iterator
    typedef ss_typename_type_k buffer_type::reverse_iterator        reverse_iterator;
    /// The type of the const (non-mutating) reverse iterator
    typedef ss_typename_type_k buffer_type::const_reverse_iterator  const_reverse_iterator;
#endif /* STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT */
    /// The size type
    typedef ss_typename_type_k buffer_type::size_type               size_type;
    /// The difference type
    typedef ss_typename_type_k buffer_type::difference_type         difference_type;

/// @}

/// \name Construction
/// @{
public:
    ss_explicit_k pod_vector(size_type cItems = 0);
    pod_vector(size_type cItems, value_type const& value);
    pod_vector(class_type const& rhs);
    pod_vector(const_iterator first, const_iterator last);

    pod_vector& operator =(class_type const& rhs);
/// @}

/// \name Iteration
/// @{
public:
    iterator                begin();
    const_iterator          begin() const;
    iterator                end();
    const_iterator          end() const;
#if defined(STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
    reverse_iterator        rbegin();
    const_reverse_iterator  rbegin() const;
    reverse_iterator        rend();
    const_reverse_iterator  rend() const;
#endif /* STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT */
/// @}

/// \name Attributes
/// @{
public:
    size_type       size() const;
    size_type       capacity() const;
    size_type       max_size() const;
    ss_bool_t       empty() const;
    allocator_type  get_allocator() const;
/// @}

/// \name Accessors
/// @{
public:
    reference       at(size_type index);
    const_reference at(size_type index) const;
    reference       operator[](size_type index);
    const_reference operator[](size_type index) const;
    reference       front();
    const_reference front() const;
    reference       back();
    const_reference back() const;
/// @}

/// \name Operations
/// @{
public:
    void        clear();
    void        swap(class_type& rhs);
    void        reserve(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */;
// Note: resize() is split into two, so the one-param version can be very quick
    void        resize(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */;
    void        resize(size_type cItems, value_type const& value) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */;
    void        push_back(value_type const& value);
    void        pop_back();

    void        assign(const_iterator first, const_iterator last);
    void        assign(size_type cItems, value_type const& value = value_type());
    iterator    insert(iterator it, value_type const& value = value_type());
    void        insert(iterator it, size_type cItems, value_type const& value);
    void        insert(iterator it, const_iterator first, const_iterator last);
    iterator    erase(iterator it);
    iterator    erase(iterator first, iterator last);
/// @}

/// \name Implementation
/// @{
private:
    pointer         begin_();
    const_pointer   begin_() const;

    void        range_check_(size_type index) const /* stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) ) */;

    ss_bool_t   resize_(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */;

    ss_bool_t   is_valid_() const;
/// @}

/// \name Members
/// @{
private:
    size_type   m_cItems;   // A size member is used, rather than m_end (iterator), because some of the state
                            // is maintained in the parent class. Doing it this way makes swap() and other methods
                            // very simple.
    buffer_type m_buffer;   // The auto_buffer
/// @}
};

/* /////////////////////////////////////////////////////////////////////////
 * Operators
 */

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
inline ss_bool_t operator ==(pod_vector<T, A, SPACE> const& lhs, pod_vector<T, A, SPACE> const& rhs)
{
    if(lhs.size() != rhs.size())
    {
        return false;
    }
    else
    {
#if 0
        for(ss_typename_type_k pod_vector<T, A, SPACE>::size_type i = 0, size = lhs.size(); i < size; ++i)
        {
            if(lhs[i] != rhs[i])
            {
                return false;
            }
        }

        return true;
#else /* ? 0 */
        return 0 == memcmp(&lhs[0], &rhs[0], sizeof(ss_typename_type_k pod_vector<T, A, SPACE>::size_type) * lhs.size());
#endif /* 0 */
    }
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
inline ss_bool_t operator !=(pod_vector<T, A, SPACE> const& lhs, pod_vector<T, A, SPACE> const& rhs)
{
    return !operator ==(lhs, rhs);
}

/* /////////////////////////////////////////////////////////////////////////
 * swapping
 */

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
inline void swap(pod_vector<T, A, SPACE>& lhs, pod_vector<T, A, SPACE>& rhs)
{
    lhs.swap(rhs);
}

/* /////////////////////////////////////////////////////////////////////////
 * Unit-testing
 */

⌨️ 快捷键说明

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