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

📄 enumerator_sequence.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 3 页
字号:
/* /////////////////////////////////////////////////////////////////////////
 * File:        comstl/collections/enumerator_sequence.hpp (originally MOEnSeq.h, ::SynesisCom)
 *
 * Purpose:     STL sequence for IEnumXXXX enumerator interfaces.
 *
 * Created:     17th September 1998
 * Updated:     5th August 2007
 *
 * Home:        http://stlsoft.org/
 *
 * Copyright (c) 1998-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 comstl/collections/enumerator_sequence.hpp
 *
 * \brief [C++ only] Definition of the comstl::enumerator_sequence
 *   collection class template
 *   (\ref group__library__collections "Collections" Library).
 */

#ifndef COMSTL_INCL_COMSTL_COLLECTIONS_HPP_ENUMERATOR_SEQUENCE
#define COMSTL_INCL_COMSTL_COLLECTIONS_HPP_ENUMERATOR_SEQUENCE

#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define COMSTL_VER_COMSTL_COLLECTIONS_HPP_ENUMERATOR_SEQUENCE_MAJOR    6
# define COMSTL_VER_COMSTL_COLLECTIONS_HPP_ENUMERATOR_SEQUENCE_MINOR    0
# define COMSTL_VER_COMSTL_COLLECTIONS_HPP_ENUMERATOR_SEQUENCE_REVISION 12
# define COMSTL_VER_COMSTL_COLLECTIONS_HPP_ENUMERATOR_SEQUENCE_EDIT     237
#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_COLLECTIONS_HPP_ENUMERATION_POLICIES
# include <comstl/collections/enumeration_policies.hpp>
#endif /* !COMSTL_INCL_COMSTL_COLLECTIONS_HPP_ENUMERATION_POLICIES */
#ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
# include <stlsoft/util/std/iterator_helper.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER */
#ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
# include <stlsoft/collections/util/collections.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_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_META_HPP_SELECT_FIRST_TYPE_IF
#  include <stlsoft/meta/select_first_type_if.hpp>
# endif /* !STLSOFT_INCL_STLSOFT_META_HPP_SELECT_FIRST_TYPE_IF */
#endif /* !STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */
#include <algorithm>

#ifdef STLSOFT_UNITTEST
# include <comstl/util/value_policies.hpp>
# if !defined(STLSOFT_COMPILER_IS_DMC)
#  include "./unittest/_recls_COM_decl_.h"
# endif /* compiler */
# if !defined(STLSOFT_COMPILER_IS_COMO)
#  include <winstl/dl/dl_call.hpp>
# endif /* compiler */
#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
 */

/** \brief A template for adapting COM enumerators to STL-compatible
 *    sequence iteration.
 *
 * \ingroup group__library__collections
 *
 * \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 <code>V const&</code>. To make it mutable, set to
 *   <code>V&</code>
 * \param CP Cloning policy type. Defaults to cloneable_cloning_policy&lt;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 <code>IEnumGUID</code> enumerator instance.
 *
\code
typedef enumerator_sequence<IEnumGUID
                          , GUID
                          , GUID_policy
                          , GUID const&
                          , forward_cloning_policy<IEnumGUID>
                          , 5
                          >    enum_sequence_t;
\endcode
 *
 * The value type is <code>GUID</code> and it is returned as a reference, as
 * the <code>GUID const&</code> in fact.
 *
 * The \link group__project__comstl\endlink type 
 * <GUID const&>GUID_policy</GUID const&> controls how the 
 * <GUID const&>GUID</GUID const&> instances are initialised, copied and
 * destroyed.
 *
 * The \link group__project__comstl\endlink type forward_cloning_policy allows the sequence to provide
 * <a href = "http://sgi.com/tech/stl/ForwardIterator.html">Forward Iterator</a>
 * semantics.
 *
 * And the <GUID const&>5</GUID const&> indicates that the sequence should
 * grab 5 values at a time, to save round trips to the enumerator.
 *
 * This would be used as follows:
 *
\code
void dump_GUID(GUID const&);

LPENUMGUID        *penGUIDs = . . .;      // Create an instance from wherever
enum_sequence_t   guids(penGUIDs, false); // Eat the reference

std::for_each(guids.begin(), guids.end(), dump_GUID);
\endcode
 *
 * \note The iterator instances returned by begin() and end() are valid outside
 * the lifetime of the collection instance from which they are obtained
 *
 * \sa comstl::collection_sequence
 */
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)
{
/// \name Member Types
/// @{
public:
    /// \brief Interface type
    typedef I                                                                   interface_type;
    /// \brief Value type
    typedef V                                                                   value_type;
    /// \brief Value policy type
    typedef value_policy_adaptor<VP>                                            value_policy_type;
    /// \brief Reference type
    typedef R                                                                   reference;
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
    typedef R                                                                   reference_type; // For backwards compatiblity
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
    /// \brief The mutating (non-const) 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 */
    /// \brief The non-mutating (const) pointer type
    typedef value_type const*                                                   const_pointer;
    /// \brief Cloning policy type
    typedef CP                                                                  cloning_policy_type;
    /// \brief Iterator tag type
    typedef ss_typename_type_k cloning_policy_type::iterator_tag_type           iterator_tag_type;
    /// \brief Retrieval quanta
    enum                                                                      { retrievalQuanta = Q };
    /// \brief Type of the current parameterisation
    typedef enumerator_sequence<I, V, VP, R, CP, Q>                             class_type;
    /// \brief Type of the current parameterisation
    typedef class_type                                                          sequence_type;
    /// \brief The size type
    typedef cs_size_t                                                           size_type;
    /// \brief The difference type
    typedef cs_ptrdiff_t                                                        difference_type;
    /// \brief The Boolean type
    typedef cs_bool_t                                                           bool_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. 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());
    }
    /// \brief Releases the adapted interface pointer
    ~enumerator_sequence() stlsoft_throw_0()
    {
        COMSTL_ASSERT(is_valid());

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

/// \name Iteration
/// @{
public:
    /// \brief 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
        /// @{

⌨️ 快捷键说明

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