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

📄 member_selector_iterator.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 2 页
字号:
    /// \param index The required offset from the iterator's position
    value_type const& operator [](difference_type index) const
    {
        return m_it[index];
    }

    /// \brief Calculate the distance between \c this and \c rhs
    difference_type distance(class_type const& rhs) const
    {
        return m_it - rhs.m_it;
    }
/// @}

/// \name Members
/// @{
private:
    base_iterator_type  m_it;
    M               C:: *m_member;
/// @}
};

#if defined(STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT) && \
    !defined(STLSOFT_COMPILER_IS_DMC)

# if defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) && \
     STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION < STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1

template <ss_typename_param_k I>
struct msi_iterator_traits
{
public:
    enum
    {
//      is_const    =   base_type_traits<typename I::pointer>::is_const
        // This doesn't work, because some libs (Dinkumware) don't have member 'pointer'

//      is_const    =   base_type_traits<typename I::reference>::is_const
        // This doesn't work because the nested class list::iterator does not have a 'reference'
        // type, even though op *() is declared as 'reference operator*() const'. The 'reference'
        // here is of the outer class. This is a good example of why you should:

        // NOTE: == BEST PRACTICE: Always define the types you're using as member types of the type where
        // they're being used! ==

//      is_const    =   base_type_traits<(I::operator*())>::is_const

//      is_const    =   base_type_traits<typename I::pointer_type>::is_const
        // This doesn't work because std::list<>::iterator derives from std::list<>::const_iterator derives
        // from std::_Bidit<> derives from std::iterator<>
        //
        // Neither std::list<>::const_iterator nor std::_Bitit<> define any members of their own, so we're
        // left only with std::iterator<>, which contains only iterator_category, value_type, and
        // distance_type.

        is_const    =   Dinkumware_iterator_traits<I>::is_const
    };
};

template<ss_typename_param_k T>
struct msi_iterator_traits<T*>
{
    enum { is_const = 0 };
};
template<ss_typename_param_k T>
struct msi_iterator_traits<T const*>
{
    enum { is_const = 1 };
};
template<ss_typename_param_k T>
struct msi_iterator_traits<T volatile*>
{
    enum { is_const = 0 };
};
template<ss_typename_param_k T>
struct msi_iterator_traits<T const volatile*>
{
    enum { is_const = 1 };
};
#endif /* dinkumware */


/** \brief Traits class used for specifying sub-types for the member_selector()
 * creator function(s)
 *
 * \ingroup group__library__iterators
 */
template<   ss_typename_param_k I
        ,   class               C
        ,   ss_typename_param_k M
        >
struct msi_traits
{
private:
    typedef member_selector_iterator<I, C, const M>             const_msi_type;
    typedef member_selector_iterator<I, C, M>                   non_const_msi_type;
#if !defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) || \
    STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION >= STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1
    typedef ss_typename_type_k std::iterator_traits<I>::pointer tested_member_type;

    enum
    {
        is_const    =   base_type_traits<tested_member_type>::is_const
    };
#endif /* dinkumware */
public:

#if 1

#endif /* 1 */

#if defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) && \
    STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION < STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1
    typedef ss_typename_type_k select_first_type_if<    const_msi_type
                                                    ,   non_const_msi_type
                                                    ,   msi_iterator_traits<I>::is_const
                                                    >::type             type;
#else /* ? dinkumware */
    typedef ss_typename_type_k select_first_type_if<    const_msi_type
                                                    ,   non_const_msi_type
#if 0
                                                    ,   /* base_type_traits<ss_typename_type_k std::iterator_traits<I>::value_type>::is_const ||
                                                         */base_type_traits<tested_member_type>::is_const/*  ||
                                                        base_type_traits<M>::is_const */
#else /* ? 0 */
                                                    ,   is_const
#endif /* 0 */

                                                    >::type             type;
#endif /* dinkumware */
};


// Need to identify the conditions under which the iterator needs to define the
// value type to be const:
//
// - M is const
// - I's value_type is const
//     - alas

// Solution 1:
//
//  + is_const_type<iterator_traits<I>::value_type>
//
//  - some libraries do not make define, for iterator_traits<T const*>, value_type as const T, but just T
//  - doesn't cater for case where the member M is constant, even if iterator is mutable (e.g. C* not C const*)
//
// Solution 2:
//
//  + is_const_type<iterator_traits<I>::value_type> ||
//    base_type_traits<typename std::iterator_traits<I>::pointer>::is_const ||
//    is_const_type<M>
//
//  - at this point we move into msi_traits
//
//  - doesn't work with good compilers with crufty libraries (e.g. Intel 8 with VC++ Dinkumware libs)
//
// Solution 3:
//
//   use msi_iterator_traits
//
//
// Solution final:
//
//  + use member types within msi_traits to simplify for readers
//  + use msi_iterator_traits for member-detecting compilers with Dinkumware (pre 7.1)
//  + select the general version for DMC++
//  + proscribe particular functionality for Borland and Visual C++ (pre 7.1)

/** \brief Creator function for member_selector_iterator
 *
 * \ingroup group__library__iterators
 *
 * \param it The iterator whose values will be subject to member selection
 * \param member The member pointer which will be used in the selection
 *
 * \return An instance of a suitable specialisation of member_selector_iterator
 */
template<   ss_typename_param_k I
        ,   class               C
        ,   ss_typename_param_k M
        >
inline ss_typename_type_k msi_traits<I, C, M>::type member_selector(I it, M C::*member)
{
    typedef ss_typename_type_k msi_traits<I, C, M>::type    iterator_t;

#if !defined(STLSOFT_COMPILER_IS_DMC) && \
    (   !defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) || \
        STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION >= STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1)
    STLSOFT_STATIC_ASSERT((int)is_const_type<ss_typename_type_k std::iterator_traits<I>::value_type>::value == (int)base_type_traits<ss_typename_type_k std::iterator_traits<I>::value_type>::is_const);
#endif /* !compiler */

//    STLSOFT_STATIC_ASSERT(is_const_type<iterator_t::value_type>::value == 1);

    return iterator_t(it, member);
}

# else /* ? STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */

# if 0 || defined(STLSOFT_COMPILER_IS_DMC)
template<   ss_typename_param_k I
        ,   class               C
        ,   ss_typename_param_k M
        >
inline member_selector_iterator<I, C, M> member_selector(I it, M C::*member)
{
    return member_selector_iterator<I, C, M>(it, member);
}
# endif /* 0 */

#if 0
/** \brief This one needed by const Struct1 (cw8)
 *
 * \ingroup group__library__iterators
 */
template<   ss_typename_param_k I
        ,   class               C
        ,   ss_typename_param_k M
        >
inline member_selector_iterator<I, C, const M> member_selector(I it, const M C::*member)
{
    return member_selector_iterator<I, C, const M>(it, member);
}
#endif /* 0 */

#if 0 || (defined(STLSOFT_COMPILER_IS_MSVC) && _MSC_VER < 1310)
template<   class               C
        ,   ss_typename_param_k M
        >
inline member_selector_iterator<C*, C, M> member_selector(C *it, M C::*member)
{
    return member_selector_iterator<C*, C, M>(it, member);
}
#endif /* 0 */

#if 0 /* || (defined(STLSOFT_COMPILER_IS_MSVC) && _MSC_VER < 1310) */
template<   class               C
        ,   ss_typename_param_k M
        >
inline member_selector_iterator<C const*, C, const M> member_selector(C const* it, M C::*member)
{
    return member_selector_iterator<C const*, C, const M>(it, member);
}
#endif /* 0 */

#if 0
//template<   class               C
//        ,   ss_typename_param_k M
//        >
//inline member_selector_const_iterator<C const*, C, const M> member_selector(C const* it, M C::*member)
//{
//    return member_selector_const_iterator<C const*, C, const M>(it, member);
//}
#endif /* 0 */

#if 0
template<   class               C
        ,   ss_typename_param_k M
        >
inline member_selector_const_iterator<C const*, C, const M> member_selector(C const* it, const M C::*member)
{
    return member_selector_const_iterator<C const*, C, const M>(it, member);
}
#endif /* 0 */

# endif /* STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */

/* /////////////////////////////////////////////////////////////////////////
 * Operators
 */

template<   ss_typename_param_k I
        ,   class               C
        ,   ss_typename_param_k M
        >
inline bool operator ==(member_selector_iterator<I, C, M> const& lhs, member_selector_iterator<I, C, M> const& rhs)
{
    return lhs.equal(rhs);
}

template<   ss_typename_param_k I
        ,   class               C
        ,   ss_typename_param_k M
        >
inline bool operator !=(member_selector_iterator<I, C, M> const& lhs, member_selector_iterator<I, C, M> const& rhs)
{
    return !lhs.equal(rhs);
}


template<   ss_typename_param_k I
        ,   class               C
        ,   ss_typename_param_k M
        >
inline member_selector_iterator<I, C, M> operator +(member_selector_iterator<I, C, M> const& lhs, ss_ptrdiff_t delta)
{
    return member_selector_iterator<I, C, M>(lhs.current() + delta, lhs.member());
}

template<   ss_typename_param_k I
        ,   class               C
        ,   ss_typename_param_k M
        >
inline member_selector_iterator<I, C, M> operator -(member_selector_iterator<I, C, M> const& lhs, ss_ptrdiff_t delta)
{
    return member_selector_iterator<I, C, M>(lhs.current() - delta, lhs.member());
}

template<   ss_typename_param_k I
        ,   class               C
        ,   ss_typename_param_k M
        >
inline ss_ptrdiff_t operator -(member_selector_iterator<I, C, M> const& lhs, member_selector_iterator<I, C, M> const& rhs)
{
    return lhs.distance(rhs);
}


template<   ss_typename_param_k I
        ,   class               C
        ,   ss_typename_param_k M
        >
inline bool operator <(member_selector_iterator<I, C, M> const& lhs, member_selector_iterator<I, C, M> const& rhs)
{
    return lhs.distance(rhs) < 0;
}

template<   ss_typename_param_k I
        ,   class               C
        ,   ss_typename_param_k M
        >
inline bool operator <=(member_selector_iterator<I, C, M> const& lhs, member_selector_iterator<I, C, M> const& rhs)
{
    return lhs.distance(rhs) <= 0;
}

template<   ss_typename_param_k I
        ,   class               C
        ,   ss_typename_param_k M
        >
inline bool operator >(member_selector_iterator<I, C, M> const& lhs, member_selector_iterator<I, C, M> const& rhs)
{
    return lhs.distance(rhs) > 0;
}

template<   ss_typename_param_k I
        ,   class               C
        ,   ss_typename_param_k M
        >
inline bool operator >=(member_selector_iterator<I, C, M> const& lhs, member_selector_iterator<I, C, M> const& rhs)
{
    return lhs.distance(rhs) >= 0;
}

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

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

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

#ifndef _STLSOFT_NO_NAMESPACE
} // namespace stlsoft
#endif /* _STLSOFT_NO_NAMESPACE */

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

#endif /* !STLSOFT_INCL_STLSOFT_ITERATORS_HPP_MEMBER_SELECTOR_ITERATOR */

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

⌨️ 快捷键说明

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