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

📄 enumerator_sequence.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 3 页
字号:

        /// \name Members
        /// @{
        private:
            interface_type  *m_enumerator;
            size_type       m_acquired;
            size_type       m_current;
            size_type const m_quanta;
            value_type      m_values[retrievalQuanta];
            long            m_refCount;
            size_type       m_previousBlockTotal;
        /// @}

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


    /// \name Construction
    /// @{
    private:
        friend class enumerator_sequence<I, V, VP, R, CP, Q>;

        /// \brief Constructor
        iterator(interface_type *i, size_type quanta, bool_type &bFirst)
            : m_ctxt(new enumeration_context(i, quanta, bFirst))
        {
            bFirst = false;

            COMSTL_ASSERT(is_valid());
        }
    public:
        /// \brief Default constructor
        iterator()
            : m_ctxt(NULL)
        {
            COMSTL_ASSERT(is_valid());
        }
        /// \brief Copy constructor
        iterator(class_type const& rhs)
            : m_ctxt(enumeration_context::make_clone(rhs.m_ctxt))
        {
            COMSTL_ASSERT(is_valid());
        }

        /// \brief Releases any internal storage
        ~iterator() stlsoft_throw_0()
        {
            COMSTL_ASSERT(is_valid());

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

        class_type& operator =(class_type const& rhs)
        {
            enumeration_context *newCtxt    =   enumeration_context::make_clone(rhs.m_ctxt);

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

            m_ctxt = newCtxt;

            return *this;
        }
    /// @}

    /// \name Forward Iterator Methods
    /// @{
    public:
        /// \brief Pre-increment operator
        class_type& operator ++()
        {
            COMSTL_ASSERT(is_valid());

            m_ctxt->advance();

            COMSTL_ASSERT(is_valid());

            return *this;
        }

        /// \brief Post-increment operator
        class_type operator ++(int)
        {
            COMSTL_ASSERT(is_valid());

            class_type  r(*this);

            operator ++();

            COMSTL_ASSERT(is_valid());

            return r;
        }

        /// \brief Returns the value represented by the current iteration position
        reference operator *()
        {
            COMSTL_ASSERT(is_valid());
            COMSTL_MESSAGE_ASSERT("Attempting to dereference an invalid iterator", NULL != m_ctxt && !m_ctxt->empty());

            return m_ctxt->current();
        }

        /// \brief Returns the value represented by the current iteration position
        pointer operator ->()
        {
            COMSTL_ASSERT(is_valid());
            COMSTL_MESSAGE_ASSERT("Attempting to dereference an invalid iterator", NULL != m_ctxt && !m_ctxt->empty());

            return &m_ctxt->current();
        }

    private:
        static bool_type equal_(class_type const& lhs, class_type const& rhs, stlsoft_ns_qual_std(input_iterator_tag))
        {
            // The only valid comparison is when they both represent the end values.
            return lhs.is_end_point() && rhs.is_end_point();
        }
        static bool_type equal_(class_type const& lhs, class_type const& rhs, stlsoft_ns_qual_std(forward_iterator_tag))
        {
            // The iterators can be equal under two conditions:
            //
            // 1. The end iterator (as in the case for input iterators)
            // 2. Both have a context, and the index of both contexts are the same
            //
            // otherwise:
            //
            // 3. They're not equal

            if(lhs.is_end_point())
            {
                return rhs.is_end_point(); // 1 or 3
            }
            else
            {
                if(rhs.is_end_point())
                {
                    return false; // 3
                }
                else
                {
                    COMSTL_ASSERT(NULL != lhs.m_ctxt);
                    COMSTL_ASSERT(NULL != rhs.m_ctxt);

                    return lhs.m_ctxt->index() == rhs.m_ctxt->index(); // 2 or 3
                }
            }
        }
    public:

        /// \brief Evaluates whether \c this and \c rhs are equivalent
        bool_type equal(class_type const& rhs) const
        {
            COMSTL_ASSERT(is_valid());

            return class_type::equal_(*this, rhs, iterator_tag_type());
        }
        /// \brief Evaluates whether \c this and \c rhs are equivalent
        bool_type operator == (class_type const& rhs) const
        {
            COMSTL_ASSERT(is_valid());

            return this->equal(rhs);
        }
        /// \brief Evaluates whether \c this and \c rhs are not equivalent
        bool_type operator != (class_type const& rhs) const
        {
            COMSTL_ASSERT(is_valid());

            return !this->equal(rhs);
        }
    /// @}

    /// \name Invariant
    /// @{
    private:
        bool_type is_valid() const
        {
            return (NULL == m_ctxt) || m_ctxt->is_valid();
        }
    /// @}

    /// \name Implementation
    /// @{
    private:
        bool_type is_end_point() const
        {
            return NULL == m_ctxt || m_ctxt->empty();
        }
    /// @}

    /// \name Members
    /// @{
    private:
        enumeration_context *m_ctxt;
    /// @}
    };
    /// \brief The non-mutating (const) iterator type
    typedef iterator                                                            const_iterator;

public:
    /// \brief Begins the iteration
    ///
    /// \return An iterator representing the start of the sequence
    ///
    /// \note The first time this is called, the iterated range represented by [begin(), end())
    /// directly uses that of the enumerator interface pointer passed to the constructor. When
    /// specialised with cloneable_cloning_policy and forward_cloning_policy policies, all
    /// subsequent calls to begin() will use a cloned enumerator instance, retrieved via
    /// I::Clone(). If the enumerator instance is not cloneable, then begin() will throw an
    /// instance of clone_failure on all subsequent invocations.
    iterator begin() const
    {
        COMSTL_ASSERT(is_valid());

        interface_type  *en;

        if(NULL != m_enumerator)
        {
            en = m_enumerator;
        }
        else
        {
            if(!m_bFirst)
            {
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
                STLSOFT_THROW_X(clone_failure(E_NOTIMPL));
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
                return end();
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
            }
            else
            {
                en = m_root;
            }
        }

        COMSTL_ASSERT(NULL != en);

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

        return iterator();
    }
/// @}

/// \name Invariant
/// @{
private:
    bool_type is_valid() const
    {
        if(NULL == m_root)
        {
#ifdef STLSOFT_UNITTEST
            fprintf(err, "enumerator_sequence: m_root is NULL\n");

            COMSTL_ASSERT(0);
#endif /* STLSOFT_UNITTEST */

            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:
    interface_type          *m_root;
    interface_type          *m_enumerator;
    size_type const         m_quanta;
    ss_mutable_k bool_type  m_bFirst;

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

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

#ifdef STLSOFT_UNITTEST
# include "./unittest/enumerator_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_ENUMERATOR_SEQUENCE */

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

⌨️ 快捷键说明

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