sequence_range.hpp

来自「用STL的方式封装了WindowsAPI、COM调用、ACE、ATL、MFC、W」· HPP 代码 · 共 506 行 · 第 1/2 页

HPP
506
字号
    typedef S const                                                 &sequence_reference_type;
    typedef ss_typename_type_k sequence_type::value_type            value_type;
    typedef ss_typename_type_k sequence_type::const_iterator        iterator;
    typedef ss_typename_type_k sequence_type::const_iterator        const_iterator;
    typedef ss_typename_type_k sequence_type::const_reference       reference;
    typedef ss_typename_type_k sequence_type::const_reference       const_reference;
    typedef ss_typename_type_k sequence_type::difference_type       difference_type;
    typedef ss_typename_type_k sequence_type::size_type             size_type;
};

template<   ss_typename_param_k S
        >
struct non_const_sequence_range_traits
{
public:
    typedef S                                                       sequence_type;
    typedef S const                                                 &sequence_reference_type;
    typedef ss_typename_type_k sequence_type::value_type            value_type;
    typedef ss_typename_type_k sequence_type::iterator              iterator;
    typedef ss_typename_type_k sequence_type::iterator              const_iterator;
    typedef ss_typename_type_k sequence_type::reference             reference;
    typedef ss_typename_type_k sequence_type::reference             const_reference;
    typedef ss_typename_type_k sequence_type::difference_type       difference_type;
    typedef ss_typename_type_k sequence_type::size_type             size_type;
};
#endif /* STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED */

/// \brief This class adapts an STL sequence instance into a Range
///
/// \param S The sequence class
/// \param T The sequence range traits, used to deduce the Range's iterator, const_iterator, reference, const_reference and value_type
///
/// It is categoried as an Iterable Range
///
/// It could be used as follows
/// \htmlonly
/// <code>
/// <pre>
/// void dump_elements(std::vector&lt;int&gt; const &numbers)
/// {
///   for(sequence_range&lt;std::vector&lt;int&gt; &gt; r(numbers); r; ++r)
///   {
///     std::cout &lt;&lt; &r; // Dump the current value to stdout
///   }
/// }
/// </pre>
/// </code>
/// \endhtmlonly
template<   ss_typename_param_k S
#if defined(STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED)
        ,   ss_typename_param_k T = sequence_range_traits<S, is_const<S>::value>    // Determines whether the sequence is const
#else /* ? STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED */
        ,   ss_typename_param_k T = const_sequence_range_traits<S>                  // Defaults to a const sequence
#endif /* STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED */
        >
class sequence_range
    : public mutating_operator_adaptor<sequence_range<S, T>, T> // This provides the operator forms of the methods
    , public iterable_range_tag
{
public:
    /// The sequence type
    typedef S                                                       sequence_type;
    /// The traits type
    typedef T                                                       traits_type;
    /// The range category tag type
    typedef iterable_range_tag                                      range_tag_type;
    /// The current instantiation of the type
    typedef sequence_range<S, T>                                    class_type;
    /// The sequence reference type
    typedef ss_typename_type_k traits_type::sequence_reference_type sequence_reference_type;
    /// The value type
    typedef ss_typename_type_k traits_type::value_type              value_type;
    /// The mutating (non-const) iterator type
    typedef ss_typename_type_k traits_type::iterator                iterator;
    /// The non-mutating (const) iterator type
    typedef ss_typename_type_k traits_type::const_iterator          const_iterator;
    /// The mutating (non-const) reference type
    typedef ss_typename_type_k traits_type::reference               reference;
    /// The non-mutating (const) reference type
    typedef ss_typename_type_k traits_type::const_reference         const_reference;
    /// The difference type
    typedef ss_typename_type_k traits_type::difference_type         difference_type;
    /// The size type
    typedef ss_typename_type_k traits_type::size_type               size_type;

public:

#if !defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) || \
    defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED) || \
    (   defined(STLSOFT_COMPILER_IS_MSVC) && \
        _MSC_VER == 1200)
    /// Constructor
    ///
    /// \param rhs The sequence which will be adapted to a range
    sequence_range(sequence_reference_type rhs) // The constness of this will require some thinking about. Maybe need sequence_range and const_sequence_range??
        : m_position(rhs.begin())
        , m_last(rhs.end())
    {}
#endif /* !STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT || STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED */

#if defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) && \
    (   !defined(STLSOFT_COMPILER_IS_MSVC) || \
        _MSC_VER != 1200)
    /// Constructor
    ///
    /// \param rhs The sequence which will be adapted to a range
    template <ss_typename_param_k S1>
    sequence_range(S1 &rhs)
        : m_position(rhs.begin())
        , m_last(rhs.end())
    {}
#endif /* STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */

#ifdef STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT
    /// Constructs a range over an array
    template <ss_size_t N>
    sequence_range(S (&ar)[N])
        : m_position(&ar[0])
        , m_last(&ar[N])
    {}
#endif /* STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT */

    /// Constructs from an iterator
    ///
    /// \param position The start position of the range
    /// \param last The end position of the range
    sequence_range(iterator position, iterator last)
        : m_position(position)
        , m_last(last)
    {}

    /// Copy constructor
    ///
    /// \note This has to be provided, to avoid precipitating C4217 with Visual C++
    sequence_range(class_type const &rhs)
        : m_position(rhs.m_position)
        , m_last(rhs.m_last)
    {}

    /// Copy assignment operator
    ///
    /// \note This has to be provided, to avoid precipitating C4217 with Visual C++
    class_type &operator =(class_type const &rhs)
    {
        m_position  =   rhs.m_position;
        m_last      =   rhs.m_last;

        return *this;
    }

/// \name Notional Range methods
/// @{
public:
    /// Indicates whether the range is open
    ss_bool_t is_open() const
    {
        return m_position != m_last;
    }
    /// Returns the current value in the range
    reference current()
    {
        STLSOFT_ASSERT(is_open());

        return *m_position;
    }
    /// Returns the current value in the range
    const_reference current() const
    {
        STLSOFT_ASSERT(is_open());

        return *m_position;
    }
    /// Advances the current position in the range
    class_type &advance()
    {
        STLSOFT_MESSAGE_ASSERT("Attempting to increment the range past its end point", is_open());

        ++m_position;

        return *this;
    }
/// @}

/// \name Iterable Range methods
/// @{
public:
    /// Returns an iterator to the current position of the range
    iterator begin()
    {
        return m_position;
    }
    /// Returns an iterator to the end of the range
    iterator end()
    {
        return m_last;
    }

    /// Returns an iterator to the current position of the range
    const_iterator begin() const
    {
        return m_position;
    }
    /// Returns an iterator to the end of the range
    const_iterator end() const
    {
        return m_last;
    }
/// @}

// Members
private:
    iterator    m_position;
    iterator    m_last;
};

////////////////////////////////////////////////////////////////////////////
// Functions

template<ss_typename_param_k S>
#ifdef STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
inline sequence_range<S> make_sequence_range(S &s)
#else /* ? STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */
inline sequence_range<S> make_sequence_range(S const &s)
#endif /* STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */
{
    return sequence_range<S>(s);
}

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

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

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

#ifndef RANGELIB_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
     defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace rangelib
# else
} // namespace rangelib_project
} // namespace stlsoft
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !RANGELIB_NO_NAMESPACE */

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

#endif /* !RANGELIB_INCL_RANGELIB_HPP_SEQUENCE_RANGE */

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

⌨️ 快捷键说明

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