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

📄 collection_sequence.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 2 页
字号:
    typedef ss_typename_type_k enumerator_sequence_type::reference              reference;
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
    typedef ss_typename_type_k enumerator_sequence_type::reference_type         reference_type; // For backwards compatiblity
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
    /// \brief The mutating (non-const) pointer type
    typedef ss_typename_type_k enumerator_sequence_type::pointer                pointer;
    /// \brief The non-mutating (const) pointer type
    typedef ss_typename_type_k enumerator_sequence_type::const_pointer          const_pointer;
    /// \brief The mutating (non-const) iterator type
    typedef ss_typename_type_k enumerator_sequence_type::iterator               iterator;
    /// \brief The non-mutating (const) iterator type
    typedef ss_typename_type_k enumerator_sequence_type::const_iterator         const_iterator;
    /// \brief Cloning policy type
    typedef ss_typename_type_k enumerator_sequence_type::cloning_policy_type    cloning_policy_type;
    /// \brief Iterator tag type
    typedef ss_typename_type_k enumerator_sequence_type::iterator_tag_type      iterator_tag_type;
    /// \brief Retrieval quanta
    enum                                                                      { retrievalQuanta = enumerator_sequence_type::retrievalQuanta };
    /// \brief The policy for acquiring the enumerator from the collection
    typedef EAP                                                                 enumerator_acquisition_policy_type;
    /// \brief Type of the current parameterisation
    typedef collection_sequence<CI, EI, V, VP, R, CP, Q, EAP>                   class_type;
    /// \brief The size type
    typedef ss_typename_type_k enumerator_sequence_type::size_type              size_type;
    /// \brief The difference type
    typedef ss_typename_type_k enumerator_sequence_type::difference_type        difference_type;
/// @}

public:
    /// \brief Conversion constructor
    ///
    /// \param i The enumeration interface pointer to adapt
    /// \param bAddRef Causes a reference to be added if \c true, otherwise the sequence is deemed to <i>sink</i>, or consume, the interface pointer
    /// \param quanta The actual quanta required for this instance. Must be <= Q
    ///
    /// \note This does not throw an exception, so it is safe to be used to "eat" the
    /// reference. The only possible exception to this is if COMSTL_ASSERT(), which is
    /// used to validate that the given quanta size is within the limit specified in
    /// the specialisation, has been redefined to throw an exception. But since
    /// precondition violations are no more recoverable than any others (see the article
    /// "The Nuclear Reactor and the Deep Space Probe"), this does not represent
    /// a concerning contradiction to the no-throw status of the constructor.
    collection_sequence(collection_interface_type *i, cs_bool_t bAddRef, size_type quanta = 0)
        : m_i(i)
        , m_quanta(validate_quanta_(quanta))
    {
        COMSTL_ASSERT(NULL != i);
        COMSTL_MESSAGE_ASSERT("Cannot set a quantum that exceeds the value specified in the template specialisation", quanta <= retrievalQuanta); // Could have named these things better!

        if(bAddRef)
        {
            m_i->AddRef();
        }

        COMSTL_ASSERT(is_valid());
    }
    /// \brief Releases the adapted interface pointer
    ~collection_sequence() stlsoft_throw_0()
    {
        COMSTL_ASSERT(is_valid());

        m_i->Release();
    }

/// \name Iteration
/// @{
public:
    /// \brief Begins the iteration
    ///
    /// \return An iterator representing the start of the sequence
    iterator begin() const
    {
        COMSTL_ASSERT(is_valid());

        LPUNKNOWN   punkEnum;
        HRESULT     hr  =   enumerator_acquisition_policy_type::acquire(m_i, &punkEnum);

        if(SUCCEEDED(hr))
        {
            enumerator_interface_type   *ei;

            hr = punkEnum->QueryInterface(IID_traits<enumerator_interface_type>::iid(), reinterpret_cast<void**>(&ei));

            punkEnum->Release();

            if(SUCCEEDED(hr))
            {
                COMSTL_ASSERT(is_valid());

                return enumerator_sequence_type(ei, false, m_quanta).begin();
            }
            else
            {
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
                COMSTL_ASSERT(is_valid());

                STLSOFT_THROW_X(com_exception("the enumerator does not provide the requested interface", hr));
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
            }
        }
        else
        {
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
            COMSTL_ASSERT(is_valid());

            STLSOFT_THROW_X(com_exception("enumerator could not be elicited from the collection", hr));
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
        }

        COMSTL_ASSERT(is_valid());

        return iterator();
    }
    /// \brief Ends the iteration
    ///
    /// \return An iterator representing the end of the sequence
    iterator end() const
    {
        COMSTL_ASSERT(is_valid());

        return iterator();
    }
/// @}

/// \name Capacity
/// @{
public:
    /** \brief Returns the number of items in the collection
     *
    \code
    IGUIDCollection       *penGUIDs = . . .;        // Create an instance from wherever
    collection_sequence_t guids(penGUIDs, false);   // Eat the reference
    size_t                numItems = guids.size();  // Evaluate the number of elements in the collection
    \endcode
     *
     *
     * \note This method will not compile for collection interfaces
     * that do not contain the get_Count method
     */
    size_type size() const
    {
        COMSTL_ASSERT(is_valid());

        ULONG   count;
        HRESULT hr  =   m_i->get_Count(&count);

        COMSTL_ASSERT(is_valid());

        return SUCCEEDED(hr) ? count : 0;
    }
/// @}

/// \name Invariant
/// @{
private:
    cs_bool_t is_valid() const
    {
        if(NULL == m_i)
        {
            return false;
        }

        return true;
    }
/// @}

// Implementation
private:
    static size_type validate_quanta_(size_type quanta)
    {
        COMSTL_MESSAGE_ASSERT("Cannot set a quantum that exceeds the value specified in the template specialisation", quanta <= retrievalQuanta); // Could have named these things better!

        if( 0 == quanta ||
            quanta > retrievalQuanta)
        {
            quanta = retrievalQuanta;
        }

        return quanta;
    }

// Members
private:
    collection_interface_type   *m_i;
    size_type const             m_quanta;

// Not to be implemented
private:
    collection_sequence(class_type const&);
    class_type const& operator =(class_type const&);
};

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

#ifdef STLSOFT_UNITTEST
# include "./unittest/collection_sequence_unittest_.h"
#endif /* STLSOFT_UNITTEST */

/* ////////////////////////////////////////////////////////////////////// */

#ifndef _COMSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
     defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace comstl
# else
} // namespace stlsoft::comstl_project
} // namespace stlsoft
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_COMSTL_NO_NAMESPACE */

/* ////////////////////////////////////////////////////////////////////// */

#endif /* !COMSTL_INCL_COMSTL_COLLECTIONS_HPP_COLLECTION_SEQUENCE */

/* ////////////////////////////////////////////////////////////////////// */

⌨️ 快捷键说明

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