forked from enlightenment/efl
218 lines
6.1 KiB
C++
218 lines
6.1 KiB
C++
#ifndef EINA_ITERATOR_HH_
|
|
#define EINA_ITERATOR_HH_
|
|
|
|
#include <Eina.h>
|
|
|
|
#include <cstdlib>
|
|
#include <iterator>
|
|
|
|
/**
|
|
* @addtogroup Eina_Cxx_Content_Access_Group
|
|
*
|
|
* @{
|
|
*/
|
|
|
|
namespace efl { namespace eina {
|
|
|
|
/**
|
|
* @defgroup Eina_Cxx_Iterator_Group Iterator
|
|
* @ingroup Eina_Cxx_Content_Access_Group
|
|
*
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* Common implementations for iterators.
|
|
*/
|
|
template <typename T>
|
|
struct _common_iterator_base
|
|
{
|
|
private:
|
|
typedef _common_iterator_base<T> self_type; /**< Type for the iterator instantiation itself. */
|
|
public:
|
|
typedef T const value_type; /**< Type for elements returned by the iterator. */
|
|
typedef value_type* pointer; /**< Type for a pointer to an element. */
|
|
typedef value_type& reference; /**< Type for a reference to an element. */
|
|
typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two iterators. */
|
|
typedef std::input_iterator_tag iterator_category; /**< Defines the iterator as being an input iterator. */
|
|
|
|
/**
|
|
* @brief Default constructor. Creates an iterator that points to nothing.
|
|
*/
|
|
_common_iterator_base() {}
|
|
|
|
/**
|
|
* @brief Creates a iterator wrapping the given native @c Eina_Iterator handle.
|
|
* @param iterator Handle to a native @c Eina_Iterator.
|
|
*
|
|
* This constructor creates an iterator that wraps the given native
|
|
* @c Eina_Iterator handle, providing an OOP interface to it.
|
|
*
|
|
* @warning The created iterator object gains ownership of the handle
|
|
* and will deallocate it at destruction time.
|
|
*/
|
|
explicit _common_iterator_base(Eina_Iterator* iterator)
|
|
: _iterator(iterator) {}
|
|
|
|
/**
|
|
* @brief Release the internal native Eina iterator handle.
|
|
*/
|
|
~_common_iterator_base()
|
|
{
|
|
if(_iterator)
|
|
eina_iterator_free(_iterator);
|
|
}
|
|
|
|
/**
|
|
* @brief Creates an iterator from another iterator of the same type.
|
|
* @param other Another iterator of the same type.
|
|
*
|
|
* @warning The supplied iterator transfer its internal handle to the
|
|
* new iterator, thus @p other will point to nothing after the call
|
|
* of this constructor.
|
|
*/
|
|
_common_iterator_base(self_type const& other)
|
|
: _iterator(other._iterator)
|
|
{
|
|
other._iterator = 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Acquire the internal handle of the given iterator.
|
|
* @param other Another iterator of the same type.
|
|
* @return Reference for itself.
|
|
*
|
|
* @warning The supplied iterator transfer its internal handle to the
|
|
* new iterator, thus @p other will point to nothing after the call
|
|
* of this constructor.
|
|
*/
|
|
_common_iterator_base& operator=(self_type const& other)
|
|
{
|
|
_iterator = other._iterator;
|
|
other._iterator = 0;
|
|
return *this;
|
|
}
|
|
|
|
protected:
|
|
/**
|
|
* @internal
|
|
*/
|
|
mutable Eina_Iterator* _iterator;
|
|
|
|
/**
|
|
* @brief Check if the iterators wrap the same handle.
|
|
* @param lhs Iterator at the left side of the expression.
|
|
* @param lhs Iterator at the right side of the expression.
|
|
* @return @c true if both iterators wrap the same handle, @c false otherwise.
|
|
*/
|
|
friend inline bool operator==(_common_iterator_base<T> const& lhs, _common_iterator_base<T> const& rhs)
|
|
{
|
|
return lhs._iterator == rhs._iterator;
|
|
}
|
|
|
|
/**
|
|
* @brief Check if the iterators wrap the different handles.
|
|
* @param lhs Iterator at the left side of the expression.
|
|
* @param lhs Iterator at the right side of the expression.
|
|
* @return @c true if the iterators wrap different handles, @c false otherwise.
|
|
*/
|
|
friend inline bool operator!=(_common_iterator_base<T> const& lhs, _common_iterator_base<T> const& rhs)
|
|
{
|
|
return !(lhs == rhs);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* C++ wrappers to the native @c Eina_Iterator.
|
|
* It provides an OOP interface to the @c Eina_Iterator functions, and
|
|
* automatically take care of allocating a deallocating resources using
|
|
* the RAII programming idiom.
|
|
*/
|
|
template <typename T>
|
|
struct iterator : _common_iterator_base<T const>
|
|
{
|
|
private:
|
|
typedef _common_iterator_base<T const> base_type; /**< Type for the base class. */
|
|
typename base_type::pointer _value; /**< @internal */
|
|
typedef iterator<T> self_type; /**< Type for the specialized iterator itself. */
|
|
public:
|
|
typedef typename base_type::value_type value_type; /**< Type for elements returned by the iterator. */
|
|
typedef typename base_type::pointer pointer; /**< Type for a pointer to an element. */
|
|
typedef typename base_type::reference reference; /**< Type for a reference to an element. */
|
|
typedef typename base_type::difference_type difference_type; /**< Type to represent the distance between two iterators. */
|
|
typedef typename base_type::iterator_category iterator_category; /**< Defines the iterator category as the same of the base class. */
|
|
|
|
/**
|
|
* @brief Creates a iterator wrapping the given native @c Eina_Iterator handle.
|
|
*
|
|
* This constructor creates an iterator that wraps the given native
|
|
* @c Eina_Iterator handle, providing an OOP interface to it.
|
|
*/
|
|
explicit iterator(Eina_Iterator* iterator_ = 0)
|
|
: base_type(iterator_)
|
|
{
|
|
if(this->_iterator)
|
|
++*this;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Move the iterator to the next position.
|
|
* @return The iterator itself.
|
|
*
|
|
* This operator increments the iterator, making it point to the
|
|
* position right after the current one.
|
|
* At the end, it returns a reference to itself.
|
|
*/
|
|
self_type& operator++()
|
|
{
|
|
void* data;
|
|
Eina_Bool r = ::eina_iterator_next(this->_iterator, &data);
|
|
if(!r)
|
|
this->_iterator = 0;
|
|
_value = static_cast<pointer>(data);
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
* @brief Move the iterator to the next position.
|
|
* @return The iterator itself.
|
|
*
|
|
* Works exactly like @ref operator++().
|
|
*/
|
|
self_type& operator++(int)
|
|
{
|
|
return ++**this;
|
|
}
|
|
|
|
/**
|
|
* @brief Get a reference to the element currently pointed by the iterator.
|
|
* @return Reference to the current element.
|
|
*/
|
|
value_type& operator*() const
|
|
{
|
|
return *_value;
|
|
}
|
|
|
|
/**
|
|
* @brief Return a pointer to the current element, which member will be accessed.
|
|
* @return Pointer to the element currently pointed by the iterator.
|
|
*/
|
|
pointer operator->() const
|
|
{
|
|
return _value;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
} }
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#endif
|