📄 member_selector_iterator.hpp
字号:
/// \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 + -