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

📄 enumerator_sequence.hpp

📁 用STL的方式封装了WindowsAPI、COM调用、ACE、ATL、MFC、WTL等多种组件
💻 HPP
📖 第 1 页 / 共 3 页
字号:
/* /////////////////////////////////////////////////////////////////////////
 * File:        comstl/enumerator_sequence.hpp (formerly comstl/enum_sequence.hpp; comstl_enum_sequence.h; originally MOEnSeq.h, ::SynesisCom)
 *
 * Purpose:     STL sequence for IEnumXXXX enumerator interfaces.
 *
 * Created:     17th September 1998
 * Updated:     14th June 2006
 *
 * Home:        http://stlsoft.org/
 *
 * Copyright (c) 1998-2006, 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 comstl/enumerator_sequence.hpp
///
/// STL sequence for IEnumXXXX enumerator interfaces.

#ifndef COMSTL_INCL_COMSTL_HPP_ENUMERATOR_SEQUENCE
#define COMSTL_INCL_COMSTL_HPP_ENUMERATOR_SEQUENCE

#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define COMSTL_VER_COMSTL_HPP_ENUMERATOR_SEQUENCE_MAJOR    5
# define COMSTL_VER_COMSTL_HPP_ENUMERATOR_SEQUENCE_MINOR    6
# define COMSTL_VER_COMSTL_HPP_ENUMERATOR_SEQUENCE_REVISION 6
# define COMSTL_VER_COMSTL_HPP_ENUMERATOR_SEQUENCE_EDIT     215
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

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

/*
[Incompatibilies-start]
STLSOFT_COMPILER_IS_WATCOM:
[Incompatibilies-end]
 */

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

#ifndef COMSTL_INCL_COMSTL_H_COMSTL
# include <comstl/comstl.h>
#endif /* !COMSTL_INCL_COMSTL_H_COMSTL */
#ifndef COMSTL_INCL_COMSTL_HPP_ENUMERATION_POLICIES
# include <comstl/enumeration_policies.hpp> // for cloneable_cloning_policy
#endif /* !COMSTL_INCL_COMSTL_HPP_ENUMERATION_POLICIES */
#ifndef STLSOFT_INCL_STLSOFT_HPP_ITERATOR
# include <stlsoft/iterator.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_HPP_ITERATOR */
#ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_HPP_COLLECTIONS
# include <stlsoft/collections/collections.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_COLLECTIONS_HPP_COLLECTIONS */
#ifndef STLSOFT_INCL_STLSOFT_META_HPP_CAPABILITIES
# include <stlsoft/meta/capabilities.hpp>
#endif /* STLSOFT_INCL_STLSOFT_META_HPP_CAPABILITIES */
#ifdef STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
# ifndef STLSOFT_INCL_STLSOFT_META_HPP_BASE_TYPE_TRAITS
#  include <stlsoft/meta/base_type_traits.hpp>
# endif /* !STLSOFT_INCL_STLSOFT_META_HPP_BASE_TYPE_TRAITS */
# ifndef STLSOFT_INCL_STLSOFT_HPP_META
#  include <stlsoft/meta.hpp>
# endif /* !STLSOFT_INCL_STLSOFT_HPP_META */
#endif /* !STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */
#include <algorithm>

#ifdef STLSOFT_UNITTEST
# include <comstl/value_policies.hpp>
# if !defined(STLSOFT_COMPILER_IS_DMC)
#  include "./unittest/_recls_COM_decl_.h"
# endif /* compiler */
# include <winstl/dl/dl_call.hpp>
#endif /* STLSOFT_UNITTEST */

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

#ifndef _COMSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
     defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
/* There is no stlsoft namespace, so must define ::comstl */
namespace comstl
{
# else
/* Define stlsoft::comstl_project */

namespace stlsoft
{

namespace comstl_project
{

# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_COMSTL_NO_NAMESPACE */

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

/// A template for adapting COM enumeration to STL-compatible sequence iteration
///
/// \param I Interface
/// \param V Value type
/// \param VP Value policy type
/// \param R Reference type. The type returned by the iterator's dereference operator. Defaults to V const&. To make it mutable, set to V&
/// \param CP Cloning policy type. Defaults to cloneable_cloning_policy<I>
/// \param Q Quanta. The number of elements retrieved from the enumerator with each invocation of Next(). Defaults to 10
///
/// The various parameterising types are used to stipulate the interface and the
/// value type, and how they are to be handled.
///
/// For example, the following parameterisation defines a sequence operating
/// over an <b>IEnumGUID</b> enumerator instance.
///
/// \htmlonly
/// <table border = 0 cellspacing = 0 cellpadding = 0 >
///  <tr><td>&nbsp;&nbsp;</td><td><code>typedef enumerator_sequence</code></td><td><code>&lt;&nbsp;IEnumGUID</code></td></tr>
///  <tr><td>&nbsp;&nbsp;</td><td><code>&nbsp;</code></td><td><code>,&nbsp;GUID</code></td></tr>
///  <tr><td>&nbsp;&nbsp;</td><td><code>&nbsp;</code></td><td><code>,&nbsp;GUID_policy</code></td></tr>
///  <tr><td>&nbsp;&nbsp;</td><td><code>&nbsp;</code></td><td><code>,&nbsp;GUID const &</code></td></tr>
///  <tr><td>&nbsp;&nbsp;</td><td><code>&nbsp;</code></td><td><code>,&nbsp;forward_cloning_policy&lt;IEnumGUID&gt;</code></td></tr>
///  <tr><td>&nbsp;&nbsp;</td><td><code>&nbsp;</code></td><td><code>,&nbsp;5</code></td></tr>
///  <tr><td>&nbsp;&nbsp;</td><td><code>&nbsp;</code></td><td><code>&gt;&nbsp;&nbsp;&nbsp;enum_sequence_t;</code></td></tr>
/// </table>
/// \endhtmlonly
///
/// The value type is <b>GUID</b> and it is returned as a reference, as
/// the <b>GUID const &</b> in fact.
///
/// The \ref COMSTL type <b>GUID_policy</b> controls how the <b>GUID</b>
/// instances are initialised, copied and destroyed.
///
/// The \ref COMSTL type forward_cloning_policy allows the sequence to provide
/// <a href = "http://sgi.com/tech/stl/ForwardIterator.html">Forward Iterator</a>
/// semantics.
///
/// And the <b>5</b> indicates that the sequence should grab 5 values at a time,
/// to save round trips to the enumerator.
///
/// So this would be used like the following:
///
/// \htmlonly
/// <code>
/// &nbsp;&nbsp;void dump_GUID(GUID const &);
/// <br>
///
/// <br>
/// &nbsp;&nbsp;LPENUMGUID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*penGUIDs = . . .;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Create an instance from wherever
/// <br>
/// &nbsp;&nbsp;enum_sequence_t&nbsp;&nbsp;&nbsp;guids(penGUIDs, false); // Eat the reference
/// <br>
///
/// <br>
/// &nbsp;&nbsp;std::for_each(guids.begin(), guids.end(), dump_GUID);
/// <br>
/// </code>
/// \endhtmlonly
///
/// \note The iterator instances returned by begin() and end() are valid outside
/// the lifetime of the collection instance from which they are obtained
template<   ss_typename_param_k I                                   /* Interface */
        ,   ss_typename_param_k V                                   /* Value type */
        ,   ss_typename_param_k VP                                  /* Value policy type */
        ,   ss_typename_param_k R   =   V const &                   /* Reference type */
        ,   ss_typename_param_k CP  =   cloneable_cloning_policy<I> /* Cloning policy type */
        ,   cs_size_t           Q   =   10                          /* Quanta */
        >
class enumerator_sequence
    : public stlsoft_ns_qual(stl_collection_tag)
{
public:
    /// Interface type
    typedef I                                                                   interface_type;
    /// Value type
    typedef V                                                                   value_type;
    /// Value policy type
    typedef value_policy_adaptor<VP>                                            value_policy_type;
    /// Reference type
    typedef R                                                                   reference;
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
    typedef R                                                                   reference_type; // For backwards compatiblity
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
    /// The pointer type
#if defined(STLSOFT_META_HAS_SELECT_FIRST_TYPE_IF) && \
       !defined(STLSOFT_COMPILER_IS_BORLAND)
    typedef ss_typename_type_k stlsoft_ns_qual(select_first_type_if)<   value_type const*
                                                                    ,   value_type*
                                                                    ,   stlsoft_ns_qual(base_type_traits)<R>::is_const
                                                                    >::type     pointer;
#else /* ? STLSOFT_META_HAS_SELECT_FIRST_TYPE_IF */
    typedef value_type                                                          *pointer;
#endif /* !STLSOFT_META_HAS_SELECT_FIRST_TYPE_IF */
    /// Cloning policy type
    typedef CP                                                                  cloning_policy_type;
    /// Iterator tag type
    typedef ss_typename_type_k cloning_policy_type::iterator_tag_type           iterator_tag_type;
    /// Retrieval quanta
    enum                                                                      { retrievalQuanta = Q };
    /// Type of the current parameterisation
    typedef enumerator_sequence<I, V, VP, R, CP, Q>                             class_type;
    /// Type of the current parameterisation
    typedef class_type                                                          sequence_type;
    /// The size type
    typedef cs_size_t                                                           size_type;
    /// The difference type
    typedef cs_ptrdiff_t                                                        difference_type;
    /// The Boolean type
    typedef cs_bool_t                                                           bool_type;

public:
    /// 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. Defaults to 0, which causes it to be Q
    /// \param bReset Determines whether the Reset() method is invoked on the enumerator instance upon construction. Defaults to true
    ///
    /// \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() or COMSTL_MESSAGE_ASSERT(), which are
    /// 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.
    enumerator_sequence(interface_type *i, bool_type bAddRef, size_type quanta = 0, bool_type bReset = true)
        : m_root(i)
        , m_enumerator(NULL)
        , m_quanta(validate_quanta_(quanta))
        , m_bFirst(true)
    {
        COMSTL_MESSAGE_ASSERT("Precondition violation: interface cannot be NULL!", NULL != i);

        if(bAddRef)
        {
            m_root->AddRef();
        }
        if(bReset)
        {
            m_root->Reset();
        }

        // Here we instantiate m_enumerator
        //
        // If noncloneable, then just AddRef()
        // Otherwise Clone() and fail
        //
        // At this point, m_enumerator will be non-NULL, and
        // can be used in all invocations of begin(), or it
        // will be NULL, in which case the 2nd or subsequent
        // invocations of begin() must be directed to throw.
        m_enumerator = cloning_policy_type::get_working_instance(m_root);

        if(NULL != m_enumerator)
        {
            m_bFirst = false;
        }

        COMSTL_ASSERT(is_valid());
    }
    /// Releases the adapted interface pointer
    ~enumerator_sequence() stlsoft_throw_0()
    {
        COMSTL_ASSERT(is_valid());

        m_root->Release();
        if(NULL != m_enumerator)
        {
            m_enumerator->Release();
        }
    }

public:
    /// Iterator for the enumerator_sequence class
    class iterator
        : public stlsoft_ns_qual(iterator_base)<iterator_tag_type
                                            ,   value_type
                                            ,   difference_type
                                            ,   pointer
                                            ,   reference
                                            >
    {
    public:
        typedef iterator                                                    class_type;
#if defined(STLSOFT_COMPILER_IS_GCC)
        typedef ss_typename_type_k sequence_type::cloning_policy_type       cloning_policy_type;
        typedef ss_typename_type_k sequence_type::value_type                value_type;
#endif /* compiler */

    private:
        struct enumeration_context
        {
        /// \name Member Types
        /// @{
        public:
            typedef enumeration_context     class_type;
            typedef V                       value_type;
            typedef CP                      cloning_policy_type;
        /// @}

        /// \name Construction
        /// @{

⌨️ 快捷键说明

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