📄 clist_adaptors.hpp
字号:
// Operators
public:
/// Dereference operator
value_type operator *() const
{
MFCSTL_MESSAGE_ASSERT("", NULL != m_list);
return m_value;
}
/// \brief Pre-increment operator
const_iterator& operator ++()
{
if(m_pos == NULL)
{
MFCSTL_MESSAGE_ASSERT("operator ++() called on invalid iterator", NULL != m_list);
m_list = NULL;
}
else
{
m_value = m_list->GetNext(m_pos);
}
return *this;
}
/// \brief Post-increment operator
# ifdef _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR
const_iterator operator ++(int)
# else /* ? _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR */
void operator ++(int)
# endif /* _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR */
{
# ifdef _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR
class_type ret(*this);
# endif /* _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR */
operator ++();
# ifdef _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR
return ret;
# endif /* _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR */
}
/// Evaluates whether \c this is equivalent to \c rhs
///
/// \param rhs The instance from which to copy construct
/// \retval true The two iterators refer to the same position in the same container
/// \retval false The two iterators do not refer to the same position in the same container
ms_bool_t operator ==(const_iterator const& rhs) const
{
// Because the C<Type><Container> containers, e.g. CStringList
// work on the basis of get-and-advance, m_pos alone cannot be
// the sentinel for an ended sequence. Hence, combining the
// implementation of op++ to set m_list to NULL when m_pos is NULL, we
// can test both members, which results in the after-the-fact
// equality evaluating correctly.
MFCSTL_MESSAGE_ASSERT("invalid comparison between iterators from different ranges", NULL == m_list || NULL == rhs.m_list || m_list == rhs.m_list);
return m_pos == rhs.m_pos && m_list == rhs.m_list;
}
/// Evaluates whether \c this is not equivalent to \c rhs
///
/// \param rhs The instance from which to copy construct
/// \retval true The two iterators do not refer to the same position in the same container
/// \retval false The two iterators refer to the same position in the same container
ms_bool_t operator !=(const_iterator const& rhs) const
{
return !operator ==(rhs);
}
// Members
private:
list_type const* m_list;
POSITION m_pos;
value_type m_value;
};
/// @}
/// \name Underlying Container Access
/// @{
public:
/// \brief Returns a mutating (non-const) reference to the underlying list
list_type& get_CList()
{
return static_cast<interface_class_type*>(this)->get_actual_list();
}
/// \brief Returns a non-mutating (const) reference to the underlying list
list_type const& get_CList() const
{
return static_cast<interface_class_type const*>(this)->get_actual_list();
}
/// @}
/// \name Construction
/// @{
protected:
/// \brief Default constructor.
///
/// This is protected, because CList_adaptor_base serves as an abstract base
/// for CList_cadaptor and CList_iadaptor
CList_adaptor_base()
{}
/// \brief Destructor
~CList_adaptor_base() stlsoft_throw_0()
{}
public:
/// Returns a copy of the allocator used by the container
allocator_type get_allocator() const
{
return allocator_type();
}
/// @}
/// \name Size and Capacity
/// @{
public:
/// Returns the number of elements in the sequence
size_type size() const
{
return static_cast<size_type>(get_CList().GetSize());
}
/// \brief The maximum number of items that can be stored in the list
size_type max_size() const
{
return get_allocator().max_size();
}
/// Indicates whether the search sequence is empty
ms_bool_t empty() const
{
return 0 == size();
}
/// @}
/// \name Element access
/// @{
public:
/// @}
/// \name Modifiers
/// @{
public:
void push_back(value_type const& val)
{
get_CList().AddTail(val);
}
/// @}
/// \name Iteration
/// @{
public:
/// Begins the iteration
///
/// \return An iterator representing the start of the sequence
const_iterator begin() const
{
return const_iterator(&get_CList(), get_CList().GetHeadPosition());
}
/// Ends the iteration
///
/// \return An iterator representing the end of the sequence
const_iterator end() const
{
return const_iterator();
}
/// @}
};
template< ss_typename_param_k A
, ss_typename_param_k T = CList_traits<A>
>
class CList_iadaptor
: public CList_adaptor_base<A, CList_iadaptor<A, T>, T>
{
/// \name Member Types
/// @{
private:
typedef CList_adaptor_base<A, CList_iadaptor<A, T>, T> parent_class_type;
public:
/// The type of the underlying MFC list
typedef ss_typename_type_k parent_class_type::list_type list_type;
/// The value type
typedef ss_typename_type_k parent_class_type::value_type value_type;
/// The allocator type
typedef ss_typename_type_k parent_class_type::allocator_type allocator_type;
/// The mutating (non-const) reference type
typedef ss_typename_type_k parent_class_type::reference reference;
/// The non-mutating (const) reference type
typedef ss_typename_type_k parent_class_type::const_reference const_reference;
/// The mutating (non-const) pointer type
typedef ss_typename_type_k parent_class_type::pointer pointer;
/// The non-mutating (const) pointer type
typedef ss_typename_type_k parent_class_type::const_pointer const_pointer;
#if 0
/// The non-mutating (const) iterator type
typedef ss_typename_type_k parent_class_type::const_iterator const_iterator;
#endif /* 0 */
/// The size type
typedef ss_typename_type_k parent_class_type::size_type size_type;
/// The difference type
typedef ss_typename_type_k parent_class_type::difference_type difference_type;
/// The instantiation of the current type
typedef CList_iadaptor<A, T> class_type;
/// @}
/// \name Identity
/// @{
private:
friend class CList_adaptor_base<A, CList_iadaptor<A, T>, T>;
list_type &get_actual_list()
{
MFCSTL_ASSERT(NULL != m_pList);
return *m_pList;
}
list_type const &get_actual_list() const
{
MFCSTL_ASSERT(NULL != m_pList);
return *m_pList;
}
/// @}
/// \name Construction
/// @{
public:
template <ss_typename_param_k A2>
CList_iadaptor(A2 &list)
: m_pList(&list)
{
STLSOFT_STATIC_ASSERT(sizeof(list_type) == sizeof(A2));
#ifdef STLSOFT_META_HAS_IS_SAME_TYPE
STLSOFT_STATIC_ASSERT((stlsoft::is_same_type<list_type, A2>::value));
#else /* ? STLSOFT_META_HAS_IS_SAME_TYPE */
ASSERT(0 == ::strcmp(list.GetRuntimeClass()->m_lpszClassName, list_type().GetRuntimeClass()->m_lpszClassName));
# ifdef _CPPRTTI
ASSERT(0 == ::strcmp(typeid(A2).name(), typeid(list_type).name()));
# endif /* _CPPRTTI */
#endif /* STLSOFT_META_HAS_IS_SAME_TYPE */
}
template <ss_typename_param_k A2>
CList_iadaptor(A2 *pList)
: m_pList(pList)
{
MFCSTL_MESSAGE_ASSERT("Cannot initialise a CList_iadaptor with a NULL pointer", NULL != pList);
STLSOFT_STATIC_ASSERT(sizeof(list_type) == sizeof(A2));
#ifdef STLSOFT_META_HAS_IS_SAME_TYPE
STLSOFT_STATIC_ASSERT((stlsoft::is_same_type<list_type, A2>::value));
#else /* ? STLSOFT_META_HAS_IS_SAME_TYPE */
ASSERT(0 == ::strcmp(pList->GetRuntimeClass()->m_lpszClassName, list_type().GetRuntimeClass()->m_lpszClassName));
# ifdef _CPPRTTI
ASSERT(0 == ::strcmp(typeid(A2).name(), typeid(list_type).name()));
# endif /* _CPPRTTI */
#endif /* STLSOFT_META_HAS_IS_SAME_TYPE */
}
/// @}
/// \name Members
/// @{
private:
list_type *m_pList;
/// @}
/// \name Not to be implemented
/// @{
private:
CList_iadaptor(class_type const& rhs); // Only possible semantics for copy-ctor are share underlying list
class_type& operator =(class_type const& rhs); // Could either repoint, or could do deep copy.
/// @}
};
////////////////////////////////////////////////////////////////////////////
// Unit-testing
#ifdef STLSOFT_UNITTEST
# include "./unittest/clist_adaptors_unittest_.h"
#endif /* STLSOFT_UNITTEST */
/* ////////////////////////////////////////////////////////////////////// */
#ifndef _MFCSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} /* namespace mfcstl */
# else
} /* namespace mfcstl_project */
} /* namespace stlsoft */
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_MFCSTL_NO_NAMESPACE */
/* ////////////////////////////////////////////////////////////////////// */
#endif /* !MFCSTL_INCL_MFCSTL_COLLECTIONS_HPP_CLIST_ADAPTORS */
/* ////////////////////////////////////////////////////////////////////// */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -